From 48e29c3c864b7b8c08bc1ab471342131bdde3c48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BF=B7=E6=B8=A1?= Date: Sat, 29 Dec 2018 20:30:11 +0800 Subject: [PATCH] make `Headers` follow spec (#1427) --- js/headers.ts | 16 +++++++++++++--- js/headers_test.ts | 25 ++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/js/headers.ts b/js/headers.ts index 7cc38181f8..92077a03f3 100644 --- a/js/headers.ts +++ b/js/headers.ts @@ -31,10 +31,11 @@ class HeadersBase { // https://github.com/bitinn/node-fetch/blob/master/src/headers.js // Copyright (c) 2016 David Frank. MIT License. private _validateName(name: string) { - if (invalidTokenRegex.test(name)) { + if (invalidTokenRegex.test(name) || name === "") { throw new TypeError(`${name} is not a legal HTTP header name`); } } + private _validateValue(value: string) { if (invalidHeaderCharRegex.test(value)) { throw new TypeError(`${value} is not a legal HTTP header value`); @@ -51,8 +52,17 @@ class HeadersBase { } else { this[headerMap] = new Map(); if (Array.isArray(init)) { - for (const [rawName, rawValue] of init) { - const [name, value] = this._normalizeParams(rawName, rawValue); + for (const tuple of init) { + // If header does not contain exactly two items, + // then throw a TypeError. + // ref: https://fetch.spec.whatwg.org/#concept-headers-fill + if (tuple.length !== 2) { + // tslint:disable:max-line-length + // prettier-ignore + throw new TypeError("Failed to construct 'Headers'; Each header pair must be an iterable [name, value] tuple"); + } + + const [name, value] = this._normalizeParams(tuple[0], tuple[1]); this._validateName(name); this._validateValue(value); const existingValue = this[headerMap].get(name); diff --git a/js/headers_test.ts b/js/headers_test.ts index 9591b24f82..1433ba58e5 100644 --- a/js/headers_test.ts +++ b/js/headers_test.ts @@ -224,11 +224,34 @@ test(function headerIllegalReject() { } catch (e) { errorCount++; } - assertEqual(errorCount, 8); + try { + headers.set("", "ok"); + } catch (e) { + errorCount++; + } + assertEqual(errorCount, 9); // 'o k' is valid value but invalid name new Headers({ "He-y": "o k" }); }); +// If pair does not contain exactly two items,then throw a TypeError. +test(function headerParamsShouldThrowTypeError() { + let hasThrown = 0; + + try { + new Headers(([["1"]] as unknown) as Array<[string, string]>); + hasThrown = 1; + } catch (err) { + if (err instanceof TypeError) { + hasThrown = 2; + } else { + hasThrown = 3; + } + } + + assertEqual(hasThrown, 2); +}); + test(function headerParamsArgumentsCheck() { const methodRequireOneParam = ["delete", "get", "has", "forEach"];