superagent
Version:
elegant & feature rich browser / node HTTP with a fluent API
158 lines (149 loc) • 18.7 kB
JavaScript
;
/**
* 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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