From 9bdb95c9e34cef640534e5e5a1e2225a80442000 Mon Sep 17 00:00:00 2001 From: HelenHuang <LinHuang@pollex.com.tw> Date: 星期四, 09 六月 2022 15:48:15 +0800 Subject: [PATCH] TODO#139894 [ footer -最下方說明與保經代合作 ] 文案修改 --- PAMapp/node_modules/follow-redirects/index.js | 211 +++++++++++++++++++++++++++++++++------------------- 1 files changed, 133 insertions(+), 78 deletions(-) diff --git a/PAMapp/node_modules/follow-redirects/index.js b/PAMapp/node_modules/follow-redirects/index.js index 61aab2e..252c9bf 100644 --- a/PAMapp/node_modules/follow-redirects/index.js +++ b/PAMapp/node_modules/follow-redirects/index.js @@ -18,7 +18,7 @@ // Error types with codes var RedirectionError = createErrorType( "ERR_FR_REDIRECTION_FAILURE", - "" + "Redirected request failed" ); var TooManyRedirectsError = createErrorType( "ERR_FR_TOO_MANY_REDIRECTS", @@ -169,10 +169,16 @@ // Stops a timeout from triggering function clearTimer() { + // Clear the timeout if (self._timeout) { clearTimeout(self._timeout); self._timeout = null; } + + // Clean up all attached listeners + self.removeListener("abort", clearTimer); + self.removeListener("error", clearTimer); + self.removeListener("response", clearTimer); if (callback) { self.removeListener("timeout", callback); } @@ -196,8 +202,9 @@ // Clean up on events this.on("socket", destroyOnTimeout); - this.once("response", clearTimer); - this.once("error", clearTimer); + this.on("abort", clearTimer); + this.on("error", clearTimer); + this.on("response", clearTimer); return this; }; @@ -263,7 +270,7 @@ // If specified, use the agent corresponding to the protocol // (HTTP and HTTPS use different types of agents) if (this._options.agents) { - var scheme = protocol.substr(0, protocol.length - 1); + var scheme = protocol.slice(0, -1); this._options.agent = this._options.agents[scheme]; } @@ -329,84 +336,120 @@ // the user agent MAY automatically redirect its request to the URI // referenced by the Location field value, // even if the specific status code is not understood. + + // If the response is not a redirect; return it as-is var location = response.headers.location; - if (location && this._options.followRedirects !== false && - statusCode >= 300 && statusCode < 400) { - // Abort the current request - abortRequest(this._currentRequest); - // Discard the remainder of the response to avoid waiting for data - response.destroy(); - - // RFC7231禮6.4: A client SHOULD detect and intervene - // in cyclical redirections (i.e., "infinite" redirection loops). - if (++this._redirectCount > this._options.maxRedirects) { - this.emit("error", new TooManyRedirectsError()); - return; - } - - // RFC7231禮6.4: Automatic redirection needs to done with - // care for methods not known to be safe, [�因 - // RFC7231禮6.4.2��3: For historical reasons, a user agent MAY change - // the request method from POST to GET for the subsequent request. - if ((statusCode === 301 || statusCode === 302) && this._options.method === "POST" || - // RFC7231禮6.4.4: The 303 (See Other) status code indicates that - // the server is redirecting the user agent to a different resource [�因 - // A user agent can perform a retrieval request targeting that URI - // (a GET or HEAD request if using HTTP) [�因 - (statusCode === 303) && !/^(?:GET|HEAD)$/.test(this._options.method)) { - this._options.method = "GET"; - // Drop a possible entity and headers related to it - this._requestBodyBuffers = []; - removeMatchingHeaders(/^content-/i, this._options.headers); - } - - // Drop the Host header, as the redirect might lead to a different host - var previousHostName = removeMatchingHeaders(/^host$/i, this._options.headers) || - url.parse(this._currentUrl).hostname; - - // Create the redirected request - var redirectUrl = url.resolve(this._currentUrl, location); - debug("redirecting to", redirectUrl); - this._isRedirect = true; - var redirectUrlParts = url.parse(redirectUrl); - Object.assign(this._options, redirectUrlParts); - - // Drop the Authorization header if redirecting to another host - if (redirectUrlParts.hostname !== previousHostName) { - removeMatchingHeaders(/^authorization$/i, this._options.headers); - } - - // Evaluate the beforeRedirect callback - if (typeof this._options.beforeRedirect === "function") { - var responseDetails = { headers: response.headers }; - try { - this._options.beforeRedirect.call(null, this._options, responseDetails); - } - catch (err) { - this.emit("error", err); - return; - } - this._sanitizeOptions(this._options); - } - - // Perform the redirected request - try { - this._performRequest(); - } - catch (cause) { - var error = new RedirectionError("Redirected request failed: " + cause.message); - error.cause = cause; - this.emit("error", error); - } - } - else { - // The response is not a redirect; return it as-is + if (!location || this._options.followRedirects === false || + statusCode < 300 || statusCode >= 400) { response.responseUrl = this._currentUrl; response.redirects = this._redirects; this.emit("response", response); // Clean up this._requestBodyBuffers = []; + return; + } + + // The response is a redirect, so abort the current request + abortRequest(this._currentRequest); + // Discard the remainder of the response to avoid waiting for data + response.destroy(); + + // RFC7231禮6.4: A client SHOULD detect and intervene + // in cyclical redirections (i.e., "infinite" redirection loops). + if (++this._redirectCount > this._options.maxRedirects) { + this.emit("error", new TooManyRedirectsError()); + return; + } + + // Store the request headers if applicable + var requestHeaders; + var beforeRedirect = this._options.beforeRedirect; + if (beforeRedirect) { + requestHeaders = Object.assign({ + // The Host header was set by nativeProtocol.request + Host: response.req.getHeader("host"), + }, this._options.headers); + } + + // RFC7231禮6.4: Automatic redirection needs to done with + // care for methods not known to be safe, [�因 + // RFC7231禮6.4.2��3: For historical reasons, a user agent MAY change + // the request method from POST to GET for the subsequent request. + var method = this._options.method; + if ((statusCode === 301 || statusCode === 302) && this._options.method === "POST" || + // RFC7231禮6.4.4: The 303 (See Other) status code indicates that + // the server is redirecting the user agent to a different resource [�因 + // A user agent can perform a retrieval request targeting that URI + // (a GET or HEAD request if using HTTP) [�因 + (statusCode === 303) && !/^(?:GET|HEAD)$/.test(this._options.method)) { + this._options.method = "GET"; + // Drop a possible entity and headers related to it + this._requestBodyBuffers = []; + removeMatchingHeaders(/^content-/i, this._options.headers); + } + + // Drop the Host header, as the redirect might lead to a different host + var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers); + + // If the redirect is relative, carry over the host of the last request + var currentUrlParts = url.parse(this._currentUrl); + var currentHost = currentHostHeader || currentUrlParts.host; + var currentUrl = /^\w+:/.test(location) ? this._currentUrl : + url.format(Object.assign(currentUrlParts, { host: currentHost })); + + // Determine the URL of the redirection + var redirectUrl; + try { + redirectUrl = url.resolve(currentUrl, location); + } + catch (cause) { + this.emit("error", new RedirectionError(cause)); + return; + } + + // Create the redirected request + debug("redirecting to", redirectUrl); + this._isRedirect = true; + var redirectUrlParts = url.parse(redirectUrl); + Object.assign(this._options, redirectUrlParts); + + // Drop confidential headers when redirecting to a less secure protocol + // or to a different domain that is not a superdomain + if (redirectUrlParts.protocol !== currentUrlParts.protocol && + redirectUrlParts.protocol !== "https:" || + redirectUrlParts.host !== currentHost && + !isSubdomain(redirectUrlParts.host, currentHost)) { + removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers); + } + + // Evaluate the beforeRedirect callback + if (typeof beforeRedirect === "function") { + var responseDetails = { + headers: response.headers, + statusCode: statusCode, + }; + var requestDetails = { + url: currentUrl, + method: method, + headers: requestHeaders, + }; + try { + beforeRedirect(this._options, responseDetails, requestDetails); + } + catch (err) { + this.emit("error", err); + return; + } + this._sanitizeOptions(this._options); + } + + // Perform the redirected request + try { + this._performRequest(); + } + catch (cause) { + this.emit("error", new RedirectionError(cause)); } }; @@ -510,13 +553,20 @@ delete headers[header]; } } - return lastValue; + return (lastValue === null || typeof lastValue === "undefined") ? + undefined : String(lastValue).trim(); } function createErrorType(code, defaultMessage) { - function CustomError(message) { + function CustomError(cause) { Error.captureStackTrace(this, this.constructor); - this.message = message || defaultMessage; + if (!cause) { + this.message = defaultMessage; + } + else { + this.message = defaultMessage + ": " + cause.message; + this.cause = cause; + } } CustomError.prototype = new Error(); CustomError.prototype.constructor = CustomError; @@ -533,6 +583,11 @@ request.abort(); } +function isSubdomain(subdomain, domain) { + const dot = subdomain.length - domain.length - 1; + return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain); +} + // Exports module.exports = wrap({ http: http, https: https }); module.exports.wrap = wrap; -- Gitblit v1.8.0