http-cookie-agent
Version:
Allows cookies with every Node.js HTTP clients.
114 lines (113 loc) • 3.79 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createCookieAgent = createCookieAgent;
var _nodeUrl = _interopRequireDefault(require("node:url"));
var _create_cookie_header_value = require("../utils/create_cookie_header_value");
var _save_cookies_from_header = require("../utils/save_cookies_from_header");
var _validate_cookie_options = require("../utils/validate_cookie_options");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const kCookieOptions = Symbol('cookieOptions');
const kReimplicitHeader = Symbol('reimplicitHeader');
const kRecreateFirstChunk = Symbol('recreateFirstChunk');
const kOverrideRequest = Symbol('overrideRequest');
function createCookieAgent(BaseAgentClass) {
// @ts-expect-error -- BaseAgentClass is type definition.
class CookieAgent extends BaseAgentClass {
constructor(...params) {
const {
cookies: cookieOptions
} = params.find(opt => {
return opt != null && typeof opt === 'object' && 'cookies' in opt;
}) ?? {};
super(...params);
if (cookieOptions) {
(0, _validate_cookie_options.validateCookieOptions)(cookieOptions);
}
this[kCookieOptions] = cookieOptions;
}
[kReimplicitHeader](req) {
const _headerSent = req._headerSent;
req._header = null;
req._implicitHeader();
req._headerSent = _headerSent;
}
[kRecreateFirstChunk](req) {
const firstChunk = req.outputData[0];
if (req._header == null || firstChunk == null) {
return;
}
const prevData = firstChunk.data;
const prevHeaderLength = prevData.indexOf('\r\n\r\n');
if (prevHeaderLength === -1) {
firstChunk.data = req._header;
} else {
firstChunk.data = `${req._header}${prevData.slice(prevHeaderLength + 4)}`;
}
const diffSize = firstChunk.data.length - prevData.length;
req.outputSize += diffSize;
req._onPendingData(diffSize);
}
[kOverrideRequest](req, requestUrl, cookieOptions) {
const _implicitHeader = req._implicitHeader.bind(req);
req._implicitHeader = () => {
try {
const cookieHeader = (0, _create_cookie_header_value.createCookieHeaderValue)({
cookieOptions,
passedValues: [req.getHeader('Cookie')].flat(),
requestUrl
});
if (cookieHeader) {
req.setHeader('Cookie', cookieHeader);
}
} catch (err) {
req.destroy(err);
return;
}
_implicitHeader();
};
const emit = req.emit.bind(req);
req.emit = (event, ...args) => {
if (event === 'response') {
try {
const res = args[0];
(0, _save_cookies_from_header.saveCookiesFromHeader)({
cookieOptions,
cookies: res.headers['set-cookie'],
requestUrl
});
} catch (err) {
req.destroy(err);
return false;
}
}
return emit(event, ...args);
};
}
addRequest(req, options) {
const cookieOptions = this[kCookieOptions];
if (cookieOptions) {
try {
const requestUrl = _nodeUrl.default.format({
host: req.host,
pathname: req.path,
protocol: req.protocol
});
this[kOverrideRequest](req, requestUrl, cookieOptions);
if (req._header != null) {
this[kReimplicitHeader](req);
}
if (req._headerSent) {
this[kRecreateFirstChunk](req);
}
} catch (err) {
req.destroy(err);
return;
}
}
super.addRequest(req, options);
}
}
return CookieAgent;
}
;