Skip to content

Commit

Permalink
chore: [capricorn86#1315] Adds support for multiple values to Headers…
Browse files Browse the repository at this point in the history
… and removes logic for splitting cookie string
  • Loading branch information
capricorn86 committed Mar 18, 2024
1 parent caba022 commit 8a4e309
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 127 deletions.
64 changes: 0 additions & 64 deletions packages/happy-dom/src/cookie/urilities/CookieStringUtility.ts
Expand Up @@ -113,68 +113,4 @@ export default class CookieStringUtility {

return cookieString.join('; ');
}

/**
* Returns a list of Cookie String parsed from Cookies String.
*
* Based on:
* https://github.com/nfriedly/set-cookie-parser/blob/master/lib/set-cookie.js (MIT)
*
* @param cookiesString Cookies string.
* @returns Cookies strings.
*/
public static splitCookiesString(cookiesString: string): string[] {
let pos = 0;

const skipWhiteSpace = (): boolean => {
while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) {
pos += 1;
}
return pos < cookiesString.length;
};

const notSpecialChar = (): boolean => {
const ch = cookiesString.charAt(pos);
return ch !== '=' && ch !== ';' && ch !== ',';
};

const cookiesStrings: string[] = [];

while (pos < cookiesString.length) {
let start = pos;
let cookiesSeparatorFound = false;

while (skipWhiteSpace()) {
const ch = cookiesString.charAt(pos);
if (ch === ',') {
const lastComma = pos;
pos += 1;

skipWhiteSpace();
const nextStart = pos;

while (pos < cookiesString.length && notSpecialChar()) {
pos += 1;
}

if (pos < cookiesString.length && cookiesString.charAt(pos) === '=') {
cookiesSeparatorFound = true;
pos = nextStart;
cookiesStrings.push(cookiesString.substring(start, lastComma));
start = pos;
} else {
pos = lastComma + 1;
}
} else {
pos += 1;
}
}

if (!cookiesSeparatorFound || pos >= cookiesString.length) {
cookiesStrings.push(cookiesString.substring(start, cookiesString.length));
}
}

return cookiesStrings;
}
}
27 changes: 12 additions & 15 deletions packages/happy-dom/src/fetch/Headers.ts
Expand Up @@ -3,15 +3,14 @@ import * as PropertySymbol from '../PropertySymbol.js';
import DOMExceptionNameEnum from '../exception/DOMExceptionNameEnum.js';
import IHeaders from './types/IHeaders.js';
import IHeadersInit from './types/IHeadersInit.js';
import CookieStringUtility from '../cookie/urilities/CookieStringUtility.js';

/**
* Fetch headers.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Headers
*/
export default class Headers implements IHeaders {
public [PropertySymbol.entries]: { [k: string]: { name: string; value: string } } = {};
public [PropertySymbol.entries]: { [k: string]: { name: string; value: string[] } } = {};

/**
* Constructor.
Expand Down Expand Up @@ -49,11 +48,11 @@ export default class Headers implements IHeaders {
public append(name: string, value: string): void {
const lowerName = name.toLowerCase();
if (this[PropertySymbol.entries][lowerName]) {
this[PropertySymbol.entries][lowerName].value += `, ${value}`;
this[PropertySymbol.entries][lowerName].value.push(value);
} else {
this[PropertySymbol.entries][lowerName] = {
name,
value
value: [value]
};
}
}
Expand All @@ -74,7 +73,7 @@ export default class Headers implements IHeaders {
* @returns Value.
*/
public get(name: string): string | null {
return this[PropertySymbol.entries][name.toLowerCase()]?.value ?? null;
return this[PropertySymbol.entries][name.toLowerCase()]?.value.join(', ') ?? null;
}

/**
Expand All @@ -86,7 +85,7 @@ export default class Headers implements IHeaders {
public set(name: string, value: string): void {
this[PropertySymbol.entries][name.toLowerCase()] = {
name,
value
value: [value]
};
}

Expand All @@ -96,13 +95,11 @@ export default class Headers implements IHeaders {
* @returns An array of strings representing the values of all the different Set-Cookie headers.
*/
public getSetCookie(): string[] {
const cookiesString = this.get('Set-Cookie');
if (cookiesString === null) {
const entry = this[PropertySymbol.entries]['set-cookie'];
if (!entry) {
return [];
} else if (cookiesString === '') {
return [''];
}
return CookieStringUtility.splitCookiesString(cookiesString);
return entry.value;
}

/**
Expand All @@ -122,7 +119,7 @@ export default class Headers implements IHeaders {
*/
public forEach(callback: (name: string, value: string, thisArg: IHeaders) => void): void {
for (const header of Object.values(this[PropertySymbol.entries])) {
callback(header.value, header.name, this);
callback(header.value.join(', '), header.name, this);
}
}

Expand All @@ -144,7 +141,7 @@ export default class Headers implements IHeaders {
*/
public *values(): IterableIterator<string> {
for (const header of Object.values(this[PropertySymbol.entries])) {
yield header.value;
yield header.value.join(', ');
}
}

Expand All @@ -155,7 +152,7 @@ export default class Headers implements IHeaders {
*/
public *entries(): IterableIterator<[string, string]> {
for (const header of Object.values(this[PropertySymbol.entries])) {
yield [header.name, header.value];
yield [header.name, header.value.join(', ')];
}
}

Expand All @@ -166,7 +163,7 @@ export default class Headers implements IHeaders {
*/
public *[Symbol.iterator](): IterableIterator<[string, string]> {
for (const header of Object.values(this[PropertySymbol.entries])) {
yield [header.name, header.value];
yield [header.name, header.value.join(', ')];
}
}
}

This file was deleted.

25 changes: 25 additions & 0 deletions packages/happy-dom/test/fetch/Headers.test.ts
Expand Up @@ -132,6 +132,31 @@ describe('Headers', () => {
'a=1',
'b=2; Expires=Fri, 01 Jan 2100 00:00:00 GMT'
]);

const headers2 = new Headers();

headers2.append(
'Set-Cookie',
'key=value; HttpOnly; Path=/; Expires=Fri, 01 Jan 2100 00:00:00 GMT'
);

expect(headers2.getSetCookie()).toEqual([
'key=value; HttpOnly; Path=/; Expires=Fri, 01 Jan 2100 00:00:00 GMT'
]);

const headers3 = new Headers();

headers3.append(
'Set-Cookie',
'key1=value1; HttpOnly; Path=/; Expires=Fri, 01 Jan 2100 00:00:00 GMT'
);

headers3.append('Set-Cookie', 'key2=value2; Domain=example.com; Max-Age=1');

expect(headers3.getSetCookie()).toEqual([
'key1=value1; HttpOnly; Path=/; Expires=Fri, 01 Jan 2100 00:00:00 GMT',
'key2=value2; Domain=example.com; Max-Age=1'
]);
});
});

Expand Down

0 comments on commit 8a4e309

Please sign in to comment.