From 44d77471ac256b75b0818518908e05fd5404751b Mon Sep 17 00:00:00 2001 From: jnizet Date: Fri, 13 Sep 2024 09:39:37 +0200 Subject: [PATCH] fix(http): preserve all headers from Headers object when initialized from a `Headers` object containing multiple values for the same header, `HttpHeaders` now contains all the header values instead of only having one of them. Fixes #57798 --- packages/common/http/src/headers.ts | 22 +++++++++++++--------- packages/common/http/test/headers_spec.ts | 10 ++++++++++ 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/packages/common/http/src/headers.ts b/packages/common/http/src/headers.ts index 89e138c1e0d1..a9f82aa5ba58 100644 --- a/packages/common/http/src/headers.ts +++ b/packages/common/http/src/headers.ts @@ -56,21 +56,15 @@ export class HttpHeaders { const index = line.indexOf(':'); if (index > 0) { const name = line.slice(0, index); - const key = name.toLowerCase(); const value = line.slice(index + 1).trim(); - this.maybeSetNormalizedName(name, key); - if (this.headers.has(key)) { - this.headers.get(key)!.push(value); - } else { - this.headers.set(key, [value]); - } + this.addHeaderEntry(name, value); } }); }; } else if (typeof Headers !== 'undefined' && headers instanceof Headers) { this.headers = new Map(); - headers.forEach((values: string, name: string) => { - this.setHeaderEntries(name, values); + headers.forEach((value: string, name: string) => { + this.addHeaderEntry(name, value); }); } else { this.lazyInit = () => { @@ -249,6 +243,16 @@ export class HttpHeaders { } } + private addHeaderEntry(name: string, value: string) { + const key = name.toLowerCase(); + this.maybeSetNormalizedName(name, key); + if (this.headers.has(key)) { + this.headers.get(key)!.push(value); + } else { + this.headers.set(key, [value]); + } + } + private setHeaderEntries(name: string, values: any) { const headerValues = (Array.isArray(values) ? values : [values]).map((value) => value.toString(), diff --git a/packages/common/http/test/headers_spec.ts b/packages/common/http/test/headers_spec.ts index 6657cbb65435..1394dc6b1b48 100644 --- a/packages/common/http/test/headers_spec.ts +++ b/packages/common/http/test/headers_spec.ts @@ -46,6 +46,16 @@ describe('HttpHeaders', () => { expect(headers.getAll('foo')).toEqual(['second']); }); + it('should keep all values when initialized from a Headers object with duplicate headers', () => { + const standardHeaders = new Headers([ + ['Set-Cookie', 'cookie1=foo'], + ['Set-Cookie', 'cookie2=bar'], + ]); + const headers = new HttpHeaders(standardHeaders); + + expect(headers.getAll('Set-Cookie')).toEqual(['cookie1=foo', 'cookie2=bar']); + }); + it('should throw an error when null is passed as header', () => { // Note: the `strictNullChecks` set to `false` in TS config would make `null` // valid value within the headers object, thus this test verifies this scenario.