UNPKG

superagent

Version:

elegant & feature rich browser / node HTTP with a fluent API

158 lines (149 loc) • 18.7 kB
"use strict"; /** * Module dependencies. */ const net = require('node:net'); const { CookieJar } = require('cookiejar'); const { CookieAccessInfo } = require('cookiejar'); const methods = require('methods'); const request = require('../..'); const AgentBase = require('../agent-base'); function defaultCookiePath(pathname) { const lastSlash = pathname.lastIndexOf('/'); return lastSlash > 0 ? pathname.slice(0, lastSlash) : '/'; } /** * Whether `requestHost` domain-matches the cookie `domain` attribute * (RFC 6265 Section 5.1.3). IP addresses only match themselves. * * @param {String} requestHost * @param {String} domain * @return {Boolean} * @api private */ function domainMatches(requestHost, domain) { if (requestHost === domain) return true; return requestHost.endsWith(`.${domain}`) && net.isIP(requestHost) === 0 && !/^\[/.test(requestHost); } /** * Filter Set-Cookie values so that a server can only set cookies for itself. * * `cookiejar` stores any explicit `Domain` attribute as given, which would * let one host plant cookies that the jar then sends to an unrelated host * (session fixation across the hosts an agent talks to, e.g. through a * redirect chain). Per RFC 6265 Section 5.3 step 6 a cookie whose domain * attribute does not domain-match the request host is ignored; a domain * without any dot (a bare public suffix such as "com") is ignored as well * unless it is the request host itself (e.g. "localhost"). * * @param {String[]} cookies raw Set-Cookie header values * @param {String} requestHost lower-cased hostname the response came from * @return {String[]} * @api private */ function filterCookiesForHost(cookies, requestHost) { return cookies.filter(cookie => { if (typeof cookie !== 'string') return false; const parts = cookie.split(';'); for (const part of parts.slice(1)) { const index = part.indexOf('='); const name = (index === -1 ? part : part.slice(0, index)).trim().toLowerCase(); if (name !== 'domain') continue; const domain = (index === -1 ? '' : part.slice(index + 1)).trim().replace(/^\./, '').toLowerCase(); // an empty Domain attribute means "host-only"; cookiejar treats it // the same way if (!domain) return true; if (domain !== requestHost && !domain.includes('.')) return false; return domainMatches(requestHost, domain); } return true; }); } /** * Initialize a new `Agent`. * * @api public */ class Agent extends AgentBase { constructor(options) { super(); this.jar = new CookieJar(); if (options) { if (options.ca) { this.ca(options.ca); } if (options.key) { this.key(options.key); } if (options.pfx) { this.pfx(options.pfx); } if (options.cert) { this.cert(options.cert); } if (options.rejectUnauthorized === false) { this.disableTLSCerts(); } } } /** * Save the cookies in the given `res` to * the agent's cookie jar for persistence. * * @param {Response} res * @api private */ _saveCookies(res) { let cookies = res.headers['set-cookie']; if (cookies) { const url = new URL(res.request && res.request.url || ''); if (!Array.isArray(cookies)) cookies = [cookies]; cookies = filterCookiesForHost(cookies, url.hostname.toLowerCase()); if (cookies.length === 0) return; this.jar.setCookies(cookies, url.hostname, defaultCookiePath(url.pathname)); } } /** * Attach cookies when available to the given `req`. * * @param {Request} req * @api private */ _attachCookies(request_) { const url = new URL(request_.url); const access = new CookieAccessInfo(url.hostname, url.pathname, url.protocol === 'https:'); const cookies = this.jar.getCookies(access).toValueString(); request_.cookies = cookies; } } for (const name of methods) { const method = name.toUpperCase(); if (method === 'QUERY') continue; Agent.prototype[name] = function (url, fn) { const request_ = new request.Request(method, url); request_.on('response', this._saveCookies.bind(this)); request_.on('pre-redirect', this._saveCookies.bind(this)); request_.on('redirect', this._attachCookies.bind(this, request_)); this._setDefaults(request_); this._attachCookies(request_); if (fn) { request_.end(fn); } return request_; }; } Agent.prototype.del = Agent.prototype.delete; // create a Proxy that can instantiate a new Agent without using `new` keyword // (for backward compatibility and chaining) const proxyAgent = new Proxy(Agent, { apply(target, thisArgument, argumentsList) { // eslint-disable-next-line new-cap return new target(...argumentsList); } }); module.exports = proxyAgent; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJuZXQiLCJyZXF1aXJlIiwiQ29va2llSmFyIiwiQ29va2llQWNjZXNzSW5mbyIsIm1ldGhvZHMiLCJyZXF1ZXN0IiwiQWdlbnRCYXNlIiwiZGVmYXVsdENvb2tpZVBhdGgiLCJwYXRobmFtZSIsImxhc3RTbGFzaCIsImxhc3RJbmRleE9mIiwic2xpY2UiLCJkb21haW5NYXRjaGVzIiwicmVxdWVzdEhvc3QiLCJkb21haW4iLCJlbmRzV2l0aCIsImlzSVAiLCJ0ZXN0IiwiZmlsdGVyQ29va2llc0Zvckhvc3QiLCJjb29raWVzIiwiZmlsdGVyIiwiY29va2llIiwicGFydHMiLCJzcGxpdCIsInBhcnQiLCJpbmRleCIsImluZGV4T2YiLCJuYW1lIiwidHJpbSIsInRvTG93ZXJDYXNlIiwicmVwbGFjZSIsImluY2x1ZGVzIiwiQWdlbnQiLCJjb25zdHJ1Y3RvciIsIm9wdGlvbnMiLCJqYXIiLCJjYSIsImtleSIsInBmeCIsImNlcnQiLCJyZWplY3RVbmF1dGhvcml6ZWQiLCJkaXNhYmxlVExTQ2VydHMiLCJfc2F2ZUNvb2tpZXMiLCJyZXMiLCJoZWFkZXJzIiwidXJsIiwiVVJMIiwiQXJyYXkiLCJpc0FycmF5IiwiaG9zdG5hbWUiLCJsZW5ndGgiLCJzZXRDb29raWVzIiwiX2F0dGFjaENvb2tpZXMiLCJyZXF1ZXN0XyIsImFjY2VzcyIsInByb3RvY29sIiwiZ2V0Q29va2llcyIsInRvVmFsdWVTdHJpbmciLCJtZXRob2QiLCJ0b1VwcGVyQ2FzZSIsInByb3RvdHlwZSIsImZuIiwiUmVxdWVzdCIsIm9uIiwiYmluZCIsIl9zZXREZWZhdWx0cyIsImVuZCIsImRlbCIsImRlbGV0ZSIsInByb3h5QWdlbnQiLCJQcm94eSIsImFwcGx5IiwidGFyZ2V0IiwidGhpc0FyZ3VtZW50IiwiYXJndW1lbnRzTGlzdCIsIm1vZHVsZSIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvbm9kZS9hZ2VudC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxuY29uc3QgbmV0ID0gcmVxdWlyZSgnbm9kZTpuZXQnKTtcbmNvbnN0IHsgQ29va2llSmFyIH0gPSByZXF1aXJlKCdjb29raWVqYXInKTtcbmNvbnN0IHsgQ29va2llQWNjZXNzSW5mbyB9ID0gcmVxdWlyZSgnY29va2llamFyJyk7XG5jb25zdCBtZXRob2RzID0gcmVxdWlyZSgnbWV0aG9kcycpO1xuY29uc3QgcmVxdWVzdCA9IHJlcXVpcmUoJy4uLy4uJyk7XG5jb25zdCBBZ2VudEJhc2UgPSByZXF1aXJlKCcuLi9hZ2VudC1iYXNlJyk7XG5cbmZ1bmN0aW9uIGRlZmF1bHRDb29raWVQYXRoKHBhdGhuYW1lKSB7XG4gIGNvbnN0IGxhc3RTbGFzaCA9IHBhdGhuYW1lLmxhc3RJbmRleE9mKCcvJyk7XG4gIHJldHVybiBsYXN0U2xhc2ggPiAwID8gcGF0aG5hbWUuc2xpY2UoMCwgbGFzdFNsYXNoKSA6ICcvJztcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGByZXF1ZXN0SG9zdGAgZG9tYWluLW1hdGNoZXMgdGhlIGNvb2tpZSBgZG9tYWluYCBhdHRyaWJ1dGVcbiAqIChSRkMgNjI2NSBTZWN0aW9uIDUuMS4zKS4gSVAgYWRkcmVzc2VzIG9ubHkgbWF0Y2ggdGhlbXNlbHZlcy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcmVxdWVzdEhvc3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBkb21haW5cbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZG9tYWluTWF0Y2hlcyhyZXF1ZXN0SG9zdCwgZG9tYWluKSB7XG4gIGlmIChyZXF1ZXN0SG9zdCA9PT0gZG9tYWluKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIChcbiAgICByZXF1ZXN0SG9zdC5lbmRzV2l0aChgLiR7ZG9tYWlufWApICYmXG4gICAgbmV0LmlzSVAocmVxdWVzdEhvc3QpID09PSAwICYmXG4gICAgIS9eXFxbLy50ZXN0KHJlcXVlc3RIb3N0KVxuICApO1xufVxuXG4vKipcbiAqIEZpbHRlciBTZXQtQ29va2llIHZhbHVlcyBzbyB0aGF0IGEgc2VydmVyIGNhbiBvbmx5IHNldCBjb29raWVzIGZvciBpdHNlbGYuXG4gKlxuICogYGNvb2tpZWphcmAgc3RvcmVzIGFueSBleHBsaWNpdCBgRG9tYWluYCBhdHRyaWJ1dGUgYXMgZ2l2ZW4sIHdoaWNoIHdvdWxkXG4gKiBsZXQgb25lIGhvc3QgcGxhbnQgY29va2llcyB0aGF0IHRoZSBqYXIgdGhlbiBzZW5kcyB0byBhbiB1bnJlbGF0ZWQgaG9zdFxuICogKHNlc3Npb24gZml4YXRpb24gYWNyb3NzIHRoZSBob3N0cyBhbiBhZ2VudCB0YWxrcyB0bywgZS5nLiB0aHJvdWdoIGFcbiAqIHJlZGlyZWN0IGNoYWluKS4gUGVyIFJGQyA2MjY1IFNlY3Rpb24gNS4zIHN0ZXAgNiBhIGNvb2tpZSB3aG9zZSBkb21haW5cbiAqIGF0dHJpYnV0ZSBkb2VzIG5vdCBkb21haW4tbWF0Y2ggdGhlIHJlcXVlc3QgaG9zdCBpcyBpZ25vcmVkOyBhIGRvbWFpblxuICogd2l0aG91dCBhbnkgZG90IChhIGJhcmUgcHVibGljIHN1ZmZpeCBzdWNoIGFzIFwiY29tXCIpIGlzIGlnbm9yZWQgYXMgd2VsbFxuICogdW5sZXNzIGl0IGlzIHRoZSByZXF1ZXN0IGhvc3QgaXRzZWxmIChlLmcuIFwibG9jYWxob3N0XCIpLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nW119IGNvb2tpZXMgcmF3IFNldC1Db29raWUgaGVhZGVyIHZhbHVlc1xuICogQHBhcmFtIHtTdHJpbmd9IHJlcXVlc3RIb3N0IGxvd2VyLWNhc2VkIGhvc3RuYW1lIHRoZSByZXNwb25zZSBjYW1lIGZyb21cbiAqIEByZXR1cm4ge1N0cmluZ1tdfVxuICogQGFwaSBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckNvb2tpZXNGb3JIb3N0KGNvb2tpZXMsIHJlcXVlc3RIb3N0KSB7XG4gIHJldHVybiBjb29raWVzLmZpbHRlcigoY29va2llKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBjb29raWUgIT09ICdzdHJpbmcnKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgcGFydHMgPSBjb29raWUuc3BsaXQoJzsnKTtcbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMuc2xpY2UoMSkpIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gcGFydC5pbmRleE9mKCc9Jyk7XG4gICAgICBjb25zdCBuYW1lID0gKGluZGV4ID09PSAtMSA/IHBhcnQgOiBwYXJ0LnNsaWNlKDAsIGluZGV4KSlcbiAgICAgICAgLnRyaW0oKVxuICAgICAgICAudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChuYW1lICE9PSAnZG9tYWluJykgY29udGludWU7XG4gICAgICBjb25zdCBkb21haW4gPSAoaW5kZXggPT09IC0xID8gJycgOiBwYXJ0LnNsaWNlKGluZGV4ICsgMSkpXG4gICAgICAgIC50cmltKClcbiAgICAgICAgLnJlcGxhY2UoL15cXC4vLCAnJylcbiAgICAgICAgLnRvTG93ZXJDYXNlKCk7XG4gICAgICAvLyBhbiBlbXB0eSBEb21haW4gYXR0cmlidXRlIG1lYW5zIFwiaG9zdC1vbmx5XCI7IGNvb2tpZWphciB0cmVhdHMgaXRcbiAgICAgIC8vIHRoZSBzYW1lIHdheVxuICAgICAgaWYgKCFkb21haW4pIHJldHVybiB0cnVlO1xuICAgICAgaWYgKGRvbWFpbiAhPT0gcmVxdWVzdEhvc3QgJiYgIWRvbWFpbi5pbmNsdWRlcygnLicpKSByZXR1cm4gZmFsc2U7XG4gICAgICByZXR1cm4gZG9tYWluTWF0Y2hlcyhyZXF1ZXN0SG9zdCwgZG9tYWluKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSk7XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgQWdlbnRgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuY2xhc3MgQWdlbnQgZXh0ZW5kcyBBZ2VudEJhc2Uge1xuICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuamFyID0gbmV3IENvb2tpZUphcigpO1xuXG4gICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgIGlmIChvcHRpb25zLmNhKSB7XG4gICAgICAgIHRoaXMuY2Eob3B0aW9ucy5jYSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLmtleSkge1xuICAgICAgICB0aGlzLmtleShvcHRpb25zLmtleSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLnBmeCkge1xuICAgICAgICB0aGlzLnBmeChvcHRpb25zLnBmeCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLmNlcnQpIHtcbiAgICAgICAgdGhpcy5jZXJ0KG9wdGlvbnMuY2VydCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLnJlamVjdFVuYXV0aG9yaXplZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5kaXNhYmxlVExTQ2VydHMoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2F2ZSB0aGUgY29va2llcyBpbiB0aGUgZ2l2ZW4gYHJlc2AgdG9cbiAgICogdGhlIGFnZW50J3MgY29va2llIGphciBmb3IgcGVyc2lzdGVuY2UuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVzcG9uc2V9IHJlc1xuICAgKiBAYXBpIHByaXZhdGVcbiAgICovXG4gIF9zYXZlQ29va2llcyhyZXMpIHtcbiAgICBsZXQgY29va2llcyA9IHJlcy5oZWFkZXJzWydzZXQtY29va2llJ107XG4gICAgaWYgKGNvb2tpZXMpIHtcbiAgICAgIGNvbnN0IHVybCA9IG5ldyBVUkwoKHJlcy5yZXF1ZXN0ICYmIHJlcy5yZXF1ZXN0LnVybCkgfHwgJycpO1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGNvb2tpZXMpKSBjb29raWVzID0gW2Nvb2tpZXNdO1xuICAgICAgY29va2llcyA9IGZpbHRlckNvb2tpZXNGb3JIb3N0KGNvb2tpZXMsIHVybC5ob3N0bmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIGlmIChjb29raWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgdGhpcy5qYXIuc2V0Q29va2llcyhcbiAgICAgICAgY29va2llcyxcbiAgICAgICAgdXJsLmhvc3RuYW1lLFxuICAgICAgICBkZWZhdWx0Q29va2llUGF0aCh1cmwucGF0aG5hbWUpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRhY2ggY29va2llcyB3aGVuIGF2YWlsYWJsZSB0byB0aGUgZ2l2ZW4gYHJlcWAuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVxdWVzdH0gcmVxXG4gICAqIEBhcGkgcHJpdmF0ZVxuICAgKi9cbiAgX2F0dGFjaENvb2tpZXMocmVxdWVzdF8pIHtcbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHJlcXVlc3RfLnVybCk7XG4gICAgY29uc3QgYWNjZXNzID0gbmV3IENvb2tpZUFjY2Vzc0luZm8oXG4gICAgICB1cmwuaG9zdG5hbWUsXG4gICAgICB1cmwucGF0aG5hbWUsXG4gICAgICB1cmwucHJvdG9jb2wgPT09ICdodHRwczonXG4gICAgKTtcbiAgICBjb25zdCBjb29raWVzID0gdGhpcy5qYXIuZ2V0Q29va2llcyhhY2Nlc3MpLnRvVmFsdWVTdHJpbmcoKTtcbiAgICByZXF1ZXN0Xy5jb29raWVzID0gY29va2llcztcbiAgfVxufVxuXG5mb3IgKGNvbnN0IG5hbWUgb2YgbWV0aG9kcykge1xuICBjb25zdCBtZXRob2QgPSBuYW1lLnRvVXBwZXJDYXNlKCk7XG4gIGlmIChtZXRob2QgPT09ICdRVUVSWScpIGNvbnRpbnVlO1xuICBBZ2VudC5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbiAodXJsLCBmbikge1xuICAgIGNvbnN0IHJlcXVlc3RfID0gbmV3IHJlcXVlc3QuUmVxdWVzdChtZXRob2QsIHVybCk7XG5cbiAgICByZXF1ZXN0Xy5vbigncmVzcG9uc2UnLCB0aGlzLl9zYXZlQ29va2llcy5iaW5kKHRoaXMpKTtcbiAgICByZXF1ZXN0Xy5vbigncHJlLXJlZGlyZWN0JywgdGhpcy5fc2F2ZUNvb2tpZXMuYmluZCh0aGlzKSk7XG4gICAgcmVxdWVzdF8ub24oJ3JlZGlyZWN0JywgdGhpcy5fYXR0YWNoQ29va2llcy5iaW5kKHRoaXMsIHJlcXVlc3RfKSk7XG4gICAgdGhpcy5fc2V0RGVmYXVsdHMocmVxdWVzdF8pO1xuICAgIHRoaXMuX2F0dGFjaENvb2tpZXMocmVxdWVzdF8pO1xuXG4gICAgaWYgKGZuKSB7XG4gICAgICByZXF1ZXN0Xy5lbmQoZm4pO1xuICAgIH1cblxuICAgIHJldHVybiByZXF1ZXN0XztcbiAgfTtcbn1cblxuQWdlbnQucHJvdG90eXBlLmRlbCA9IEFnZW50LnByb3RvdHlwZS5kZWxldGU7XG5cbi8vIGNyZWF0ZSBhIFByb3h5IHRoYXQgY2FuIGluc3RhbnRpYXRlIGEgbmV3IEFnZW50IHdpdGhvdXQgdXNpbmcgYG5ld2Aga2V5d29yZFxuLy8gKGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IGFuZCBjaGFpbmluZylcbmNvbnN0IHByb3h5QWdlbnQgPSBuZXcgUHJveHkoQWdlbnQsIHtcbiAgYXBwbHkodGFyZ2V0LCB0aGlzQXJndW1lbnQsIGFyZ3VtZW50c0xpc3QpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbmV3LWNhcFxuICAgIHJldHVybiBuZXcgdGFyZ2V0KC4uLmFyZ3VtZW50c0xpc3QpO1xuICB9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBwcm94eUFnZW50O1xuIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTs7QUFFQSxNQUFNQSxHQUFHLEdBQUdDLE9BQU8sQ0FBQyxVQUFVLENBQUM7QUFDL0IsTUFBTTtFQUFFQztBQUFVLENBQUMsR0FBR0QsT0FBTyxDQUFDLFdBQVcsQ0FBQztBQUMxQyxNQUFNO0VBQUVFO0FBQWlCLENBQUMsR0FBR0YsT0FBTyxDQUFDLFdBQVcsQ0FBQztBQUNqRCxNQUFNRyxPQUFPLEdBQUdILE9BQU8sQ0FBQyxTQUFTLENBQUM7QUFDbEMsTUFBTUksT0FBTyxHQUFHSixPQUFPLENBQUMsT0FBTyxDQUFDO0FBQ2hDLE1BQU1LLFNBQVMsR0FBR0ws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