diff options
Diffstat (limited to 'node_modules/jsdom/lib/jsdom/living/fetch/Headers-impl.js')
-rw-r--r-- | node_modules/jsdom/lib/jsdom/living/fetch/Headers-impl.js | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/node_modules/jsdom/lib/jsdom/living/fetch/Headers-impl.js b/node_modules/jsdom/lib/jsdom/living/fetch/Headers-impl.js new file mode 100644 index 0000000..e84ba3f --- /dev/null +++ b/node_modules/jsdom/lib/jsdom/living/fetch/Headers-impl.js @@ -0,0 +1,165 @@ +"use strict"; + +const { + isForbidden, + isForbiddenResponse, + isPrivilegedNoCORSRequest, + isNoCORSSafelistedRequest, + isCORSWhitelisted +} = require("./header-types"); +const HeaderList = require("./header-list"); + +function assertName(name) { + if (!name.match(/^[!#$%&'*+\-.^`|~\w]+$/)) { + throw new TypeError("name is invalid"); + } +} + +function assertValue(value) { + if (value.match(/[\0\r\n]/)) { + throw new TypeError("value is invalid"); + } +} + +class HeadersImpl { + constructor(globalObject, args) { + this.guard = "none"; + this.headersList = new HeaderList(); + + if (args[0]) { + this._fill(args[0]); + } + } + + _fill(init) { + if (Array.isArray(init)) { + for (const header of init) { + if (header.length !== 2) { + throw new TypeError("init is invalid"); + } + this.append(header[0], header[1]); + } + } else { + for (const key of Object.keys(init)) { + this.append(key, init[key]); + } + } + } + + has(name) { + assertName(name); + return this.headersList.contains(name); + } + + get(name) { + assertName(name); + return this.headersList.get(name); + } + + _removePrivilegedNoCORSHeaders() { + this.headersList.delete("range"); + } + + append(name, value) { + value = value.trim(); + assertName(name); + assertValue(value); + + switch (this.guard) { + case "immutable": + throw new TypeError("Headers is immutable"); + case "request": + if (isForbidden(name)) { + return; + } + break; + case "request-no-cors": { + let temporaryValue = this.get(name); + if (temporaryValue === null) { + temporaryValue = value; + } else { + temporaryValue += `, ${value}`; + } + if (!isCORSWhitelisted(name, value)) { + return; + } + break; + } + case "response": + if (isForbiddenResponse(name)) { + return; + } + break; + } + + this.headersList.append(name, value); + this._removePrivilegedNoCORSHeaders(); + } + + set(name, value) { + value = value.trim(); + assertName(name); + assertValue(value); + + switch (this.guard) { + case "immutable": + throw new TypeError("Headers is immutable"); + case "request": + if (isForbidden(name)) { + return; + } + break; + case "request-no-cors": { + if (!isCORSWhitelisted(name, value)) { + return; + } + break; + } + case "response": + if (isForbiddenResponse(name)) { + return; + } + break; + } + this.headersList.set(name, value); + this._removePrivilegedNoCORSHeaders(); + } + + delete(name) { + assertName(name); + + switch (this.guard) { + case "immutable": + throw new TypeError("Headers is immutable"); + case "request": + if (isForbidden(name)) { + return; + } + break; + case "request-no-cors": { + if ( + !isNoCORSSafelistedRequest(name) && + !isPrivilegedNoCORSRequest(name) + ) { + return; + } + break; + } + case "response": + if (isForbiddenResponse(name)) { + return; + } + break; + } + this.headersList.delete(name); + this._removePrivilegedNoCORSHeaders(); + } + + * [Symbol.iterator]() { + for (const header of this.headersList.sortAndCombine()) { + yield header; + } + } +} + +exports.implementation = HeadersImpl; |