Buckets:
| /** | |
| * Request.js | |
| * | |
| * Request class contains server only options | |
| * | |
| * All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/. | |
| */ | |
| import {format as formatUrl} from 'node:url'; | |
| import {deprecate} from 'node:util'; | |
| import Headers from './headers.js'; | |
| import Body, {clone, extractContentType, getTotalBytes} from './body.js'; | |
| import {isAbortSignal} from './utils/is.js'; | |
| import {getSearch} from './utils/get-search.js'; | |
| import { | |
| validateReferrerPolicy, determineRequestsReferrer, DEFAULT_REFERRER_POLICY | |
| } from './utils/referrer.js'; | |
| const INTERNALS = Symbol('Request internals'); | |
| /** | |
| * Check if `obj` is an instance of Request. | |
| * | |
| * @param {*} object | |
| * @return {boolean} | |
| */ | |
| const isRequest = object => { | |
| return ( | |
| typeof object === 'object' && | |
| typeof object[INTERNALS] === 'object' | |
| ); | |
| }; | |
| const doBadDataWarn = deprecate(() => {}, | |
| '.data is not a valid RequestInit property, use .body instead', | |
| 'https://github.com/node-fetch/node-fetch/issues/1000 (request)'); | |
| /** | |
| * Request class | |
| * | |
| * Ref: https://fetch.spec.whatwg.org/#request-class | |
| * | |
| * @param Mixed input Url or Request instance | |
| * @param Object init Custom options | |
| * @return Void | |
| */ | |
| export default class Request extends Body { | |
| constructor(input, init = {}) { | |
| let parsedURL; | |
| // Normalize input and force URL to be encoded as UTF-8 (https://github.com/node-fetch/node-fetch/issues/245) | |
| if (isRequest(input)) { | |
| parsedURL = new URL(input.url); | |
| } else { | |
| parsedURL = new URL(input); | |
| input = {}; | |
| } | |
| if (parsedURL.username !== '' || parsedURL.password !== '') { | |
| throw new TypeError(`${parsedURL} is an url with embedded credentials.`); | |
| } | |
| let method = init.method || input.method || 'GET'; | |
| if (/^(delete|get|head|options|post|put)$/i.test(method)) { | |
| method = method.toUpperCase(); | |
| } | |
| if (!isRequest(init) && 'data' in init) { | |
| doBadDataWarn(); | |
| } | |
| // eslint-disable-next-line no-eq-null, eqeqeq | |
| if ((init.body != null || (isRequest(input) && input.body !== null)) && | |
| (method === 'GET' || method === 'HEAD')) { | |
| throw new TypeError('Request with GET/HEAD method cannot have body'); | |
| } | |
| const inputBody = init.body ? | |
| init.body : | |
| (isRequest(input) && input.body !== null ? | |
| clone(input) : | |
| null); | |
| super(inputBody, { | |
| size: init.size || input.size || 0 | |
| }); | |
| const headers = new Headers(init.headers || input.headers || {}); | |
| if (inputBody !== null && !headers.has('Content-Type')) { | |
| const contentType = extractContentType(inputBody, this); | |
| if (contentType) { | |
| headers.set('Content-Type', contentType); | |
| } | |
| } | |
| let signal = isRequest(input) ? | |
| input.signal : | |
| null; | |
| if ('signal' in init) { | |
| signal = init.signal; | |
| } | |
| // eslint-disable-next-line no-eq-null, eqeqeq | |
| if (signal != null && !isAbortSignal(signal)) { | |
| throw new TypeError('Expected signal to be an instanceof AbortSignal or EventTarget'); | |
| } | |
| // §5.4, Request constructor steps, step 15.1 | |
| // eslint-disable-next-line no-eq-null, eqeqeq | |
| let referrer = init.referrer == null ? input.referrer : init.referrer; | |
| if (referrer === '') { | |
| // §5.4, Request constructor steps, step 15.2 | |
| referrer = 'no-referrer'; | |
| } else if (referrer) { | |
| // §5.4, Request constructor steps, step 15.3.1, 15.3.2 | |
| const parsedReferrer = new URL(referrer); | |
| // §5.4, Request constructor steps, step 15.3.3, 15.3.4 | |
| referrer = /^about:(\/\/)?client$/.test(parsedReferrer) ? 'client' : parsedReferrer; | |
| } else { | |
| referrer = undefined; | |
| } | |
| this[INTERNALS] = { | |
| method, | |
| redirect: init.redirect || input.redirect || 'follow', | |
| headers, | |
| parsedURL, | |
| signal, | |
| referrer | |
| }; | |
| // Node-fetch-only options | |
| this.follow = init.follow === undefined ? (input.follow === undefined ? 20 : input.follow) : init.follow; | |
| this.compress = init.compress === undefined ? (input.compress === undefined ? true : input.compress) : init.compress; | |
| this.counter = init.counter || input.counter || 0; | |
| this.agent = init.agent || input.agent; | |
| this.highWaterMark = init.highWaterMark || input.highWaterMark || 16384; | |
| this.insecureHTTPParser = init.insecureHTTPParser || input.insecureHTTPParser || false; | |
| // §5.4, Request constructor steps, step 16. | |
| // Default is empty string per https://fetch.spec.whatwg.org/#concept-request-referrer-policy | |
| this.referrerPolicy = init.referrerPolicy || input.referrerPolicy || ''; | |
| } | |
| /** @returns {string} */ | |
| get method() { | |
| return this[INTERNALS].method; | |
| } | |
| /** @returns {string} */ | |
| get url() { | |
| return formatUrl(this[INTERNALS].parsedURL); | |
| } | |
| /** @returns {Headers} */ | |
| get headers() { | |
| return this[INTERNALS].headers; | |
| } | |
| get redirect() { | |
| return this[INTERNALS].redirect; | |
| } | |
| /** @returns {AbortSignal} */ | |
| get signal() { | |
| return this[INTERNALS].signal; | |
| } | |
| // https://fetch.spec.whatwg.org/#dom-request-referrer | |
| get referrer() { | |
| if (this[INTERNALS].referrer === 'no-referrer') { | |
| return ''; | |
| } | |
| if (this[INTERNALS].referrer === 'client') { | |
| return 'about:client'; | |
| } | |
| if (this[INTERNALS].referrer) { | |
| return this[INTERNALS].referrer.toString(); | |
| } | |
| return undefined; | |
| } | |
| get referrerPolicy() { | |
| return this[INTERNALS].referrerPolicy; | |
| } | |
| set referrerPolicy(referrerPolicy) { | |
| this[INTERNALS].referrerPolicy = validateReferrerPolicy(referrerPolicy); | |
| } | |
| /** | |
| * Clone this request | |
| * | |
| * @return Request | |
| */ | |
| clone() { | |
| return new Request(this); | |
| } | |
| get [Symbol.toStringTag]() { | |
| return 'Request'; | |
| } | |
| } | |
| Object.defineProperties(Request.prototype, { | |
| method: {enumerable: true}, | |
| url: {enumerable: true}, | |
| headers: {enumerable: true}, | |
| redirect: {enumerable: true}, | |
| clone: {enumerable: true}, | |
| signal: {enumerable: true}, | |
| referrer: {enumerable: true}, | |
| referrerPolicy: {enumerable: true} | |
| }); | |
| /** | |
| * Convert a Request to Node.js http request options. | |
| * | |
| * @param {Request} request - A Request instance | |
| * @return The options object to be passed to http.request | |
| */ | |
| export const getNodeRequestOptions = request => { | |
| const {parsedURL} = request[INTERNALS]; | |
| const headers = new Headers(request[INTERNALS].headers); | |
| // Fetch step 1.3 | |
| if (!headers.has('Accept')) { | |
| headers.set('Accept', '*/*'); | |
| } | |
| // HTTP-network-or-cache fetch steps 2.4-2.7 | |
| let contentLengthValue = null; | |
| if (request.body === null && /^(post|put)$/i.test(request.method)) { | |
| contentLengthValue = '0'; | |
| } | |
| if (request.body !== null) { | |
| const totalBytes = getTotalBytes(request); | |
| // Set Content-Length if totalBytes is a number (that is not NaN) | |
| if (typeof totalBytes === 'number' && !Number.isNaN(totalBytes)) { | |
| contentLengthValue = String(totalBytes); | |
| } | |
| } | |
| if (contentLengthValue) { | |
| headers.set('Content-Length', contentLengthValue); | |
| } | |
| // 4.1. Main fetch, step 2.6 | |
| // > If request's referrer policy is the empty string, then set request's referrer policy to the | |
| // > default referrer policy. | |
| if (request.referrerPolicy === '') { | |
| request.referrerPolicy = DEFAULT_REFERRER_POLICY; | |
| } | |
| // 4.1. Main fetch, step 2.7 | |
| // > If request's referrer is not "no-referrer", set request's referrer to the result of invoking | |
| // > determine request's referrer. | |
| if (request.referrer && request.referrer !== 'no-referrer') { | |
| request[INTERNALS].referrer = determineRequestsReferrer(request); | |
| } else { | |
| request[INTERNALS].referrer = 'no-referrer'; | |
| } | |
| // 4.5. HTTP-network-or-cache fetch, step 6.9 | |
| // > If httpRequest's referrer is a URL, then append `Referer`/httpRequest's referrer, serialized | |
| // > and isomorphic encoded, to httpRequest's header list. | |
| if (request[INTERNALS].referrer instanceof URL) { | |
| headers.set('Referer', request.referrer); | |
| } | |
| // HTTP-network-or-cache fetch step 2.11 | |
| if (!headers.has('User-Agent')) { | |
| headers.set('User-Agent', 'node-fetch'); | |
| } | |
| // HTTP-network-or-cache fetch step 2.15 | |
| if (request.compress && !headers.has('Accept-Encoding')) { | |
| headers.set('Accept-Encoding', 'gzip, deflate, br'); | |
| } | |
| let {agent} = request; | |
| if (typeof agent === 'function') { | |
| agent = agent(parsedURL); | |
| } | |
| // HTTP-network fetch step 4.2 | |
| // chunked encoding is handled by Node.js | |
| const search = getSearch(parsedURL); | |
| // Pass the full URL directly to request(), but overwrite the following | |
| // options: | |
| const options = { | |
| // Overwrite search to retain trailing ? (issue #776) | |
| path: parsedURL.pathname + search, | |
| // The following options are not expressed in the URL | |
| method: request.method, | |
| headers: headers[Symbol.for('nodejs.util.inspect.custom')](), | |
| insecureHTTPParser: request.insecureHTTPParser, | |
| agent | |
| }; | |
| return { | |
| /** @type {URL} */ | |
| parsedURL, | |
| options | |
| }; | |
| }; | |
Xet Storage Details
- Size:
- 8.62 kB
- Xet hash:
- 302902e76d1a37cada5cb982861d65b153a57a6f4357aaab8c7026ea6d8472d1
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.