diff options
Diffstat (limited to 'school/node_modules/follow-redirects')
-rw-r--r-- | school/node_modules/follow-redirects/LICENSE | 18 | ||||
-rw-r--r-- | school/node_modules/follow-redirects/README.md | 155 | ||||
-rw-r--r-- | school/node_modules/follow-redirects/debug.js | 15 | ||||
-rw-r--r-- | school/node_modules/follow-redirects/http.js | 1 | ||||
-rw-r--r-- | school/node_modules/follow-redirects/https.js | 1 | ||||
-rw-r--r-- | school/node_modules/follow-redirects/index.js | 621 | ||||
-rw-r--r-- | school/node_modules/follow-redirects/package.json | 59 |
7 files changed, 870 insertions, 0 deletions
diff --git a/school/node_modules/follow-redirects/LICENSE b/school/node_modules/follow-redirects/LICENSE new file mode 100644 index 0000000..742cbad --- /dev/null +++ b/school/node_modules/follow-redirects/LICENSE @@ -0,0 +1,18 @@ +Copyright 2014–present Olivier Lalonde <olalonde@gmail.com>, James Talmage <james@talmage.io>, Ruben Verborgh + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/school/node_modules/follow-redirects/README.md b/school/node_modules/follow-redirects/README.md new file mode 100644 index 0000000..eb869a6 --- /dev/null +++ b/school/node_modules/follow-redirects/README.md @@ -0,0 +1,155 @@ +## Follow Redirects + +Drop-in replacement for Node's `http` and `https` modules that automatically follows redirects. + +[![npm version](https://img.shields.io/npm/v/follow-redirects.svg)](https://www.npmjs.com/package/follow-redirects) +[![Build Status](https://github.com/follow-redirects/follow-redirects/workflows/CI/badge.svg)](https://github.com/follow-redirects/follow-redirects/actions) +[![Coverage Status](https://coveralls.io/repos/follow-redirects/follow-redirects/badge.svg?branch=master)](https://coveralls.io/r/follow-redirects/follow-redirects?branch=master) +[![npm downloads](https://img.shields.io/npm/dm/follow-redirects.svg)](https://www.npmjs.com/package/follow-redirects) +[![Sponsor on GitHub](https://img.shields.io/static/v1?label=Sponsor&message=%F0%9F%92%96&logo=GitHub)](https://github.com/sponsors/RubenVerborgh) + +`follow-redirects` provides [request](https://nodejs.org/api/http.html#http_http_request_options_callback) and [get](https://nodejs.org/api/http.html#http_http_get_options_callback) + methods that behave identically to those found on the native [http](https://nodejs.org/api/http.html#http_http_request_options_callback) and [https](https://nodejs.org/api/https.html#https_https_request_options_callback) + modules, with the exception that they will seamlessly follow redirects. + +```javascript +const { http, https } = require('follow-redirects'); + +http.get('http://bit.ly/900913', response => { + response.on('data', chunk => { + console.log(chunk); + }); +}).on('error', err => { + console.error(err); +}); +``` + +You can inspect the final redirected URL through the `responseUrl` property on the `response`. +If no redirection happened, `responseUrl` is the original request URL. + +```javascript +const request = https.request({ + host: 'bitly.com', + path: '/UHfDGO', +}, response => { + console.log(response.responseUrl); + // 'http://duckduckgo.com/robots.txt' +}); +request.end(); +``` + +## Options +### Global options +Global options are set directly on the `follow-redirects` module: + +```javascript +const followRedirects = require('follow-redirects'); +followRedirects.maxRedirects = 10; +followRedirects.maxBodyLength = 20 * 1024 * 1024; // 20 MB +``` + +The following global options are supported: + +- `maxRedirects` (default: `21`) – sets the maximum number of allowed redirects; if exceeded, an error will be emitted. + +- `maxBodyLength` (default: 10MB) – sets the maximum size of the request body; if exceeded, an error will be emitted. + +### Per-request options +Per-request options are set by passing an `options` object: + +```javascript +const url = require('url'); +const { http, https } = require('follow-redirects'); + +const options = url.parse('http://bit.ly/900913'); +options.maxRedirects = 10; +options.beforeRedirect = (options, response, request) => { + // Use this to adjust the request options upon redirecting, + // to inspect the latest response headers, + // or to cancel the request by throwing an error + + // response.headers = the redirect response headers + // response.statusCode = the redirect response code (eg. 301, 307, etc.) + + // request.url = the requested URL that resulted in a redirect + // request.headers = the headers in the request that resulted in a redirect + // request.method = the method of the request that resulted in a redirect + if (options.hostname === "example.com") { + options.auth = "user:password"; + } +}; +http.request(options); +``` + +In addition to the [standard HTTP](https://nodejs.org/api/http.html#http_http_request_options_callback) and [HTTPS options](https://nodejs.org/api/https.html#https_https_request_options_callback), +the following per-request options are supported: +- `followRedirects` (default: `true`) – whether redirects should be followed. + +- `maxRedirects` (default: `21`) – sets the maximum number of allowed redirects; if exceeded, an error will be emitted. + +- `maxBodyLength` (default: 10MB) – sets the maximum size of the request body; if exceeded, an error will be emitted. + +- `beforeRedirect` (default: `undefined`) – optionally change the request `options` on redirects, or abort the request by throwing an error. + +- `agents` (default: `undefined`) – sets the `agent` option per protocol, since HTTP and HTTPS use different agents. Example value: `{ http: new http.Agent(), https: new https.Agent() }` + +- `trackRedirects` (default: `false`) – whether to store the redirected response details into the `redirects` array on the response object. + + +### Advanced usage +By default, `follow-redirects` will use the Node.js default implementations +of [`http`](https://nodejs.org/api/http.html) +and [`https`](https://nodejs.org/api/https.html). +To enable features such as caching and/or intermediate request tracking, +you might instead want to wrap `follow-redirects` around custom protocol implementations: + +```javascript +const { http, https } = require('follow-redirects').wrap({ + http: require('your-custom-http'), + https: require('your-custom-https'), +}); +``` + +Such custom protocols only need an implementation of the `request` method. + +## Browser Usage + +Due to the way the browser works, +the `http` and `https` browser equivalents perform redirects by default. + +By requiring `follow-redirects` this way: +```javascript +const http = require('follow-redirects/http'); +const https = require('follow-redirects/https'); +``` +you can easily tell webpack and friends to replace +`follow-redirect` by the built-in versions: + +```json +{ + "follow-redirects/http" : "http", + "follow-redirects/https" : "https" +} +``` + +## Contributing + +Pull Requests are always welcome. Please [file an issue](https://github.com/follow-redirects/follow-redirects/issues) + detailing your proposal before you invest your valuable time. Additional features and bug fixes should be accompanied + by tests. You can run the test suite locally with a simple `npm test` command. + +## Debug Logging + +`follow-redirects` uses the excellent [debug](https://www.npmjs.com/package/debug) for logging. To turn on logging + set the environment variable `DEBUG=follow-redirects` for debug output from just this module. When running the test + suite it is sometimes advantageous to set `DEBUG=*` to see output from the express server as well. + +## Authors + +- [Ruben Verborgh](https://ruben.verborgh.org/) +- [Olivier Lalonde](mailto:olalonde@gmail.com) +- [James Talmage](mailto:james@talmage.io) + +## License + +[MIT License](https://github.com/follow-redirects/follow-redirects/blob/master/LICENSE) diff --git a/school/node_modules/follow-redirects/debug.js b/school/node_modules/follow-redirects/debug.js new file mode 100644 index 0000000..decb77d --- /dev/null +++ b/school/node_modules/follow-redirects/debug.js @@ -0,0 +1,15 @@ +var debug; + +module.exports = function () { + if (!debug) { + try { + /* eslint global-require: off */ + debug = require("debug")("follow-redirects"); + } + catch (error) { /* */ } + if (typeof debug !== "function") { + debug = function () { /* */ }; + } + } + debug.apply(null, arguments); +}; diff --git a/school/node_modules/follow-redirects/http.js b/school/node_modules/follow-redirects/http.js new file mode 100644 index 0000000..695e356 --- /dev/null +++ b/school/node_modules/follow-redirects/http.js @@ -0,0 +1 @@ +module.exports = require("./").http; diff --git a/school/node_modules/follow-redirects/https.js b/school/node_modules/follow-redirects/https.js new file mode 100644 index 0000000..d21c921 --- /dev/null +++ b/school/node_modules/follow-redirects/https.js @@ -0,0 +1 @@ +module.exports = require("./").https; diff --git a/school/node_modules/follow-redirects/index.js b/school/node_modules/follow-redirects/index.js new file mode 100644 index 0000000..3e199c1 --- /dev/null +++ b/school/node_modules/follow-redirects/index.js @@ -0,0 +1,621 @@ +var url = require("url"); +var URL = url.URL; +var http = require("http"); +var https = require("https"); +var Writable = require("stream").Writable; +var assert = require("assert"); +var debug = require("./debug"); + +// Create handlers that pass events from native requests +var events = ["abort", "aborted", "connect", "error", "socket", "timeout"]; +var eventHandlers = Object.create(null); +events.forEach(function (event) { + eventHandlers[event] = function (arg1, arg2, arg3) { + this._redirectable.emit(event, arg1, arg2, arg3); + }; +}); + +var InvalidUrlError = createErrorType( + "ERR_INVALID_URL", + "Invalid URL", + TypeError +); +// Error types with codes +var RedirectionError = createErrorType( + "ERR_FR_REDIRECTION_FAILURE", + "Redirected request failed" +); +var TooManyRedirectsError = createErrorType( + "ERR_FR_TOO_MANY_REDIRECTS", + "Maximum number of redirects exceeded" +); +var MaxBodyLengthExceededError = createErrorType( + "ERR_FR_MAX_BODY_LENGTH_EXCEEDED", + "Request body larger than maxBodyLength limit" +); +var WriteAfterEndError = createErrorType( + "ERR_STREAM_WRITE_AFTER_END", + "write after end" +); + +// An HTTP(S) request that can be redirected +function RedirectableRequest(options, responseCallback) { + // Initialize the request + Writable.call(this); + this._sanitizeOptions(options); + this._options = options; + this._ended = false; + this._ending = false; + this._redirectCount = 0; + this._redirects = []; + this._requestBodyLength = 0; + this._requestBodyBuffers = []; + + // Attach a callback if passed + if (responseCallback) { + this.on("response", responseCallback); + } + + // React to responses of native requests + var self = this; + this._onNativeResponse = function (response) { + self._processResponse(response); + }; + + // Perform the first request + this._performRequest(); +} +RedirectableRequest.prototype = Object.create(Writable.prototype); + +RedirectableRequest.prototype.abort = function () { + abortRequest(this._currentRequest); + this.emit("abort"); +}; + +// Writes buffered data to the current native request +RedirectableRequest.prototype.write = function (data, encoding, callback) { + // Writing is not allowed if end has been called + if (this._ending) { + throw new WriteAfterEndError(); + } + + // Validate input and shift parameters if necessary + if (!isString(data) && !isBuffer(data)) { + throw new TypeError("data should be a string, Buffer or Uint8Array"); + } + if (isFunction(encoding)) { + callback = encoding; + encoding = null; + } + + // Ignore empty buffers, since writing them doesn't invoke the callback + // https://github.com/nodejs/node/issues/22066 + if (data.length === 0) { + if (callback) { + callback(); + } + return; + } + // Only write when we don't exceed the maximum body length + if (this._requestBodyLength + data.length <= this._options.maxBodyLength) { + this._requestBodyLength += data.length; + this._requestBodyBuffers.push({ data: data, encoding: encoding }); + this._currentRequest.write(data, encoding, callback); + } + // Error when we exceed the maximum body length + else { + this.emit("error", new MaxBodyLengthExceededError()); + this.abort(); + } +}; + +// Ends the current native request +RedirectableRequest.prototype.end = function (data, encoding, callback) { + // Shift parameters if necessary + if (isFunction(data)) { + callback = data; + data = encoding = null; + } + else if (isFunction(encoding)) { + callback = encoding; + encoding = null; + } + + // Write data if needed and end + if (!data) { + this._ended = this._ending = true; + this._currentRequest.end(null, null, callback); + } + else { + var self = this; + var currentRequest = this._currentRequest; + this.write(data, encoding, function () { + self._ended = true; + currentRequest.end(null, null, callback); + }); + this._ending = true; + } +}; + +// Sets a header value on the current native request +RedirectableRequest.prototype.setHeader = function (name, value) { + this._options.headers[name] = value; + this._currentRequest.setHeader(name, value); +}; + +// Clears a header value on the current native request +RedirectableRequest.prototype.removeHeader = function (name) { + delete this._options.headers[name]; + this._currentRequest.removeHeader(name); +}; + +// Global timeout for all underlying requests +RedirectableRequest.prototype.setTimeout = function (msecs, callback) { + var self = this; + + // Destroys the socket on timeout + function destroyOnTimeout(socket) { + socket.setTimeout(msecs); + socket.removeListener("timeout", socket.destroy); + socket.addListener("timeout", socket.destroy); + } + + // Sets up a timer to trigger a timeout event + function startTimer(socket) { + if (self._timeout) { + clearTimeout(self._timeout); + } + self._timeout = setTimeout(function () { + self.emit("timeout"); + clearTimer(); + }, msecs); + destroyOnTimeout(socket); + } + + // 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); + } + if (!self.socket) { + self._currentRequest.removeListener("socket", startTimer); + } + } + + // Attach callback if passed + if (callback) { + this.on("timeout", callback); + } + + // Start the timer if or when the socket is opened + if (this.socket) { + startTimer(this.socket); + } + else { + this._currentRequest.once("socket", startTimer); + } + + // Clean up on events + this.on("socket", destroyOnTimeout); + this.on("abort", clearTimer); + this.on("error", clearTimer); + this.on("response", clearTimer); + + return this; +}; + +// Proxy all other public ClientRequest methods +[ + "flushHeaders", "getHeader", + "setNoDelay", "setSocketKeepAlive", +].forEach(function (method) { + RedirectableRequest.prototype[method] = function (a, b) { + return this._currentRequest[method](a, b); + }; +}); + +// Proxy all public ClientRequest properties +["aborted", "connection", "socket"].forEach(function (property) { + Object.defineProperty(RedirectableRequest.prototype, property, { + get: function () { return this._currentRequest[property]; }, + }); +}); + +RedirectableRequest.prototype._sanitizeOptions = function (options) { + // Ensure headers are always present + if (!options.headers) { + options.headers = {}; + } + + // Since http.request treats host as an alias of hostname, + // but the url module interprets host as hostname plus port, + // eliminate the host property to avoid confusion. + if (options.host) { + // Use hostname if set, because it has precedence + if (!options.hostname) { + options.hostname = options.host; + } + delete options.host; + } + + // Complete the URL object when necessary + if (!options.pathname && options.path) { + var searchPos = options.path.indexOf("?"); + if (searchPos < 0) { + options.pathname = options.path; + } + else { + options.pathname = options.path.substring(0, searchPos); + options.search = options.path.substring(searchPos); + } + } +}; + + +// Executes the next native request (initial or redirect) +RedirectableRequest.prototype._performRequest = function () { + // Load the native protocol + var protocol = this._options.protocol; + var nativeProtocol = this._options.nativeProtocols[protocol]; + if (!nativeProtocol) { + this.emit("error", new TypeError("Unsupported protocol " + protocol)); + return; + } + + // If specified, use the agent corresponding to the protocol + // (HTTP and HTTPS use different types of agents) + if (this._options.agents) { + var scheme = protocol.slice(0, -1); + this._options.agent = this._options.agents[scheme]; + } + + // Create the native request and set up its event handlers + var request = this._currentRequest = + nativeProtocol.request(this._options, this._onNativeResponse); + request._redirectable = this; + for (var event of events) { + request.on(event, eventHandlers[event]); + } + + // RFC7230§5.3.1: When making a request directly to an origin server, […] + // a client MUST send only the absolute path […] as the request-target. + this._currentUrl = /^\//.test(this._options.path) ? + url.format(this._options) : + // When making a request to a proxy, […] + // a client MUST send the target URI in absolute-form […]. + this._options.path; + + // End a redirected request + // (The first request must be ended explicitly with RedirectableRequest#end) + if (this._isRedirect) { + // Write the request entity and end + var i = 0; + var self = this; + var buffers = this._requestBodyBuffers; + (function writeNext(error) { + // Only write if this request has not been redirected yet + /* istanbul ignore else */ + if (request === self._currentRequest) { + // Report any write errors + /* istanbul ignore if */ + if (error) { + self.emit("error", error); + } + // Write the next buffer if there are still left + else if (i < buffers.length) { + var buffer = buffers[i++]; + /* istanbul ignore else */ + if (!request.finished) { + request.write(buffer.data, buffer.encoding, writeNext); + } + } + // End the request if `end` has been called on us + else if (self._ended) { + request.end(); + } + } + }()); + } +}; + +// Processes a response from the current native request +RedirectableRequest.prototype._processResponse = function (response) { + // Store the redirected response + var statusCode = response.statusCode; + if (this._options.trackRedirects) { + this._redirects.push({ + url: this._currentUrl, + headers: response.headers, + statusCode: statusCode, + }); + } + + // RFC7231§6.4: The 3xx (Redirection) class of status code indicates + // that further action needs to be taken by the user agent in order to + // fulfill the request. If a Location header field is provided, + // 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) { + 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: 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 (isFunction(beforeRedirect)) { + 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: cause })); + } +}; + +// Wraps the key/value object of protocols with redirect functionality +function wrap(protocols) { + // Default settings + var exports = { + maxRedirects: 21, + maxBodyLength: 10 * 1024 * 1024, + }; + + // Wrap each protocol + var nativeProtocols = {}; + Object.keys(protocols).forEach(function (scheme) { + var protocol = scheme + ":"; + var nativeProtocol = nativeProtocols[protocol] = protocols[scheme]; + var wrappedProtocol = exports[scheme] = Object.create(nativeProtocol); + + // Executes a request, following redirects + function request(input, options, callback) { + // Parse parameters + if (isString(input)) { + var parsed; + try { + parsed = urlToOptions(new URL(input)); + } + catch (err) { + /* istanbul ignore next */ + parsed = url.parse(input); + } + if (!isString(parsed.protocol)) { + throw new InvalidUrlError({ input }); + } + input = parsed; + } + else if (URL && (input instanceof URL)) { + input = urlToOptions(input); + } + else { + callback = options; + options = input; + input = { protocol: protocol }; + } + if (isFunction(options)) { + callback = options; + options = null; + } + + // Set defaults + options = Object.assign({ + maxRedirects: exports.maxRedirects, + maxBodyLength: exports.maxBodyLength, + }, input, options); + options.nativeProtocols = nativeProtocols; + if (!isString(options.host) && !isString(options.hostname)) { + options.hostname = "::1"; + } + + assert.equal(options.protocol, protocol, "protocol mismatch"); + debug("options", options); + return new RedirectableRequest(options, callback); + } + + // Executes a GET request, following redirects + function get(input, options, callback) { + var wrappedRequest = wrappedProtocol.request(input, options, callback); + wrappedRequest.end(); + return wrappedRequest; + } + + // Expose the properties on the wrapped protocol + Object.defineProperties(wrappedProtocol, { + request: { value: request, configurable: true, enumerable: true, writable: true }, + get: { value: get, configurable: true, enumerable: true, writable: true }, + }); + }); + return exports; +} + +/* istanbul ignore next */ +function noop() { /* empty */ } + +// from https://github.com/nodejs/node/blob/master/lib/internal/url.js +function urlToOptions(urlObject) { + var options = { + protocol: urlObject.protocol, + hostname: urlObject.hostname.startsWith("[") ? + /* istanbul ignore next */ + urlObject.hostname.slice(1, -1) : + urlObject.hostname, + hash: urlObject.hash, + search: urlObject.search, + pathname: urlObject.pathname, + path: urlObject.pathname + urlObject.search, + href: urlObject.href, + }; + if (urlObject.port !== "") { + options.port = Number(urlObject.port); + } + return options; +} + +function removeMatchingHeaders(regex, headers) { + var lastValue; + for (var header in headers) { + if (regex.test(header)) { + lastValue = headers[header]; + delete headers[header]; + } + } + return (lastValue === null || typeof lastValue === "undefined") ? + undefined : String(lastValue).trim(); +} + +function createErrorType(code, message, baseClass) { + // Create constructor + function CustomError(properties) { + Error.captureStackTrace(this, this.constructor); + Object.assign(this, properties || {}); + this.code = code; + this.message = this.cause ? message + ": " + this.cause.message : message; + } + + // Attach constructor and set default properties + CustomError.prototype = new (baseClass || Error)(); + CustomError.prototype.constructor = CustomError; + CustomError.prototype.name = "Error [" + code + "]"; + return CustomError; +} + +function abortRequest(request) { + for (var event of events) { + request.removeListener(event, eventHandlers[event]); + } + request.on("error", noop); + request.abort(); +} + +function isSubdomain(subdomain, domain) { + assert(isString(subdomain) && isString(domain)); + var dot = subdomain.length - domain.length - 1; + return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain); +} + +function isString(value) { + return typeof value === "string" || value instanceof String; +} + +function isFunction(value) { + return typeof value === "function"; +} + +function isBuffer(value) { + return typeof value === "object" && ("length" in value); +} + +// Exports +module.exports = wrap({ http: http, https: https }); +module.exports.wrap = wrap; diff --git a/school/node_modules/follow-redirects/package.json b/school/node_modules/follow-redirects/package.json new file mode 100644 index 0000000..97717c5 --- /dev/null +++ b/school/node_modules/follow-redirects/package.json @@ -0,0 +1,59 @@ +{ + "name": "follow-redirects", + "version": "1.15.2", + "description": "HTTP and HTTPS modules that follow redirects.", + "license": "MIT", + "main": "index.js", + "files": [ + "*.js" + ], + "engines": { + "node": ">=4.0" + }, + "scripts": { + "test": "npm run lint && npm run mocha", + "lint": "eslint *.js test", + "mocha": "nyc mocha" + }, + "repository": { + "type": "git", + "url": "git@github.com:follow-redirects/follow-redirects.git" + }, + "homepage": "https://github.com/follow-redirects/follow-redirects", + "bugs": { + "url": "https://github.com/follow-redirects/follow-redirects/issues" + }, + "keywords": [ + "http", + "https", + "url", + "redirect", + "client", + "location", + "utility" + ], + "author": "Ruben Verborgh <ruben@verborgh.org> (https://ruben.verborgh.org/)", + "contributors": [ + "Olivier Lalonde <olalonde@gmail.com> (http://www.syskall.com)", + "James Talmage <james@talmage.io>" + ], + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "peerDependenciesMeta": { + "debug": { + "optional": true + } + }, + "devDependencies": { + "concat-stream": "^2.0.0", + "eslint": "^5.16.0", + "express": "^4.16.4", + "lolex": "^3.1.0", + "mocha": "^6.0.2", + "nyc": "^14.1.1" + } +} |