mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
fix(http): prevent headers from throwing an error when initializing numerical values (#49379)
Some libraries could use numbers in headers. this fix prevents Angular from throwing an error by casting those numerical values into strings. Fixes #49353 PR Close #49379
This commit is contained in:
parent
5ac8ca4f55
commit
ab5e2d9387
4 changed files with 39 additions and 15 deletions
|
|
@ -1782,7 +1782,7 @@ export class HttpHeaderResponse extends HttpResponseBase {
|
|||
// @public
|
||||
export class HttpHeaders {
|
||||
constructor(headers?: string | {
|
||||
[name: string]: string | string[];
|
||||
[name: string]: string | number | (string | number)[];
|
||||
});
|
||||
append(name: string, value: string | string[]): HttpHeaders;
|
||||
delete(name: string, value?: string | string[]): HttpHeaders;
|
||||
|
|
|
|||
28
packages/common/http/src/headers.ts
Executable file → Normal file
28
packages/common/http/src/headers.ts
Executable file → Normal file
|
|
@ -45,7 +45,7 @@ export class HttpHeaders {
|
|||
|
||||
/** Constructs a new HTTP header object with the given values.*/
|
||||
|
||||
constructor(headers?: string|{[name: string]: string | string[]}) {
|
||||
constructor(headers?: string|{[name: string]: string | number | (string | number)[]}) {
|
||||
if (!headers) {
|
||||
this.headers = new Map<string, string[]>();
|
||||
} else if (typeof headers === 'string') {
|
||||
|
|
@ -72,14 +72,20 @@ export class HttpHeaders {
|
|||
assertValidHeaders(headers);
|
||||
}
|
||||
this.headers = new Map<string, string[]>();
|
||||
Object.keys(headers).forEach(name => {
|
||||
let values: string|string[] = headers[name];
|
||||
const key = name.toLowerCase();
|
||||
Object.entries(headers).forEach(([name, values]) => {
|
||||
let headerValues: string[];
|
||||
|
||||
if (typeof values === 'string') {
|
||||
values = [values];
|
||||
headerValues = [values];
|
||||
} else if (typeof values === 'number') {
|
||||
headerValues = [values.toString()];
|
||||
} else {
|
||||
headerValues = values.map((value) => value.toString());
|
||||
}
|
||||
if (values.length > 0) {
|
||||
this.headers.set(key, values);
|
||||
|
||||
if (headerValues.length > 0) {
|
||||
const key = name.toLowerCase();
|
||||
this.headers.set(key, headerValues);
|
||||
this.maybeSetNormalizedName(name, key);
|
||||
}
|
||||
});
|
||||
|
|
@ -264,16 +270,16 @@ export class HttpHeaders {
|
|||
|
||||
/**
|
||||
* Verifies that the headers object has the right shape: the values
|
||||
* must be either strings or arrays. Throws an error if an invalid
|
||||
* must be either strings, numbers or arrays. Throws an error if an invalid
|
||||
* header value is present.
|
||||
*/
|
||||
function assertValidHeaders(headers: Record<string, unknown>):
|
||||
asserts headers is Record<string, string|string[]> {
|
||||
asserts headers is Record<string, string|string[]|number|number[]> {
|
||||
for (const [key, value] of Object.entries(headers)) {
|
||||
if (typeof value !== 'string' && !Array.isArray(value)) {
|
||||
if (!(typeof value === 'string' || typeof value === 'number') && !Array.isArray(value)) {
|
||||
throw new Error(
|
||||
`Unexpected value of the \`${key}\` header provided. ` +
|
||||
`Expecting either a string or an array, but got: \`${value}\`.`);
|
||||
`Expecting either a string, a number or an array, but got: \`${value}\`.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ import {toArray} from 'rxjs/operators';
|
|||
expect(() => backend.expectOne('/test').request.headers.has('random-header'))
|
||||
.toThrowError(
|
||||
'Unexpected value of the `foo` header provided. ' +
|
||||
'Expecting either a string or an array, but got: `null`.');
|
||||
'Expecting either a string, a number or an array, but got: `null`.');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ import {HttpHeaders} from '@angular/common/http/src/headers';
|
|||
expect(() => headers.get('foo'))
|
||||
.toThrowError(
|
||||
'Unexpected value of the `foo` header provided. ' +
|
||||
'Expecting either a string or an array, but got: `null`.');
|
||||
'Expecting either a string, a number or an array, but got: `null`.');
|
||||
});
|
||||
|
||||
it('should throw an error when undefined is passed as header', () => {
|
||||
|
|
@ -64,7 +64,25 @@ import {HttpHeaders} from '@angular/common/http/src/headers';
|
|||
expect(() => headers.get('bar'))
|
||||
.toThrowError(
|
||||
'Unexpected value of the `bar` header provided. ' +
|
||||
'Expecting either a string or an array, but got: `undefined`.');
|
||||
'Expecting either a string, a number or an array, but got: `undefined`.');
|
||||
});
|
||||
|
||||
it('should not throw an error when a number is passed as header', () => {
|
||||
const headers = new HttpHeaders({'Content-Length': 100});
|
||||
const value = headers.get('Content-Length');
|
||||
expect(value).toEqual('100');
|
||||
});
|
||||
|
||||
it('should not throw an error when a numerical array is passed as header', () => {
|
||||
const headers = new HttpHeaders({'some-key': [123]});
|
||||
const value = headers.get('some-key');
|
||||
expect(value).toEqual('123');
|
||||
});
|
||||
|
||||
it('should not throw an error when an array of strings is passed as header', () => {
|
||||
const headers = new HttpHeaders({'some-key': ['myValue']});
|
||||
const value = headers.get('some-key');
|
||||
expect(value).toEqual('myValue');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue