import { createRequester } from "./_chunks/createRequester-VFTkDs_7.js"; import decompressResponse from "decompress-response"; import follow from "follow-redirects"; import http from "http"; import https from "https"; import toStream from "into-stream"; import isStream from "is-stream"; import progressStream from "progress-stream"; import qs from "querystring"; import url from "url"; import * as tunnel from "tunnel-agent"; function lowerCaseHeaders(headers) { return Object.keys(headers || {}).reduce((acc, header) => (acc[header.toLowerCase()] = headers[header], acc), {}); } function formatHostname(hostname) { return hostname.replace(/^\.*/, ".").toLowerCase(); } function parseNoProxyZone(zoneStr) { const zone = zoneStr.trim().toLowerCase(), zoneParts = zone.split(":", 2), zoneHost = formatHostname(zoneParts[0]), zonePort = zoneParts[1], hasPort = zone.indexOf(":") > -1; return { hostname: zoneHost, port: zonePort, hasPort }; } function uriInNoProxy(uri, noProxy) { const port = uri.port || (uri.protocol === "https:" ? "443" : "80"), hostname = formatHostname(uri.hostname); return noProxy.split(",").map(parseNoProxyZone).some((noProxyZone) => { const isMatchedAt = hostname.indexOf(noProxyZone.hostname), hostnameMatched = isMatchedAt > -1 && isMatchedAt === hostname.length - noProxyZone.hostname.length; return noProxyZone.hasPort ? port === noProxyZone.port && hostnameMatched : hostnameMatched; }); } function getProxyFromUri(uri) { const noProxy = process.env.NO_PROXY || process.env.no_proxy || ""; return noProxy === "*" || noProxy !== "" && uriInNoProxy(uri, noProxy) ? null : uri.protocol === "http:" ? process.env.HTTP_PROXY || process.env.http_proxy || null : uri.protocol === "https:" && (process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy) || null; } function getHostFromUri(uri) { let host = uri.host; return uri.port && (uri.port === "80" && uri.protocol === "http:" || uri.port === "443" && uri.protocol === "https:") && (host = uri.hostname), host; } function getHostHeaderWithPort(uri) { const port = uri.port || (uri.protocol === "https:" ? "443" : "80"); return `${uri.hostname}:${port}`; } function rewriteUriForProxy(reqOpts, uri, proxy) { const headers = reqOpts.headers || {}, options = Object.assign({}, reqOpts, { headers }); return headers.host = headers.host || getHostHeaderWithPort(uri), options.protocol = proxy.protocol || options.protocol, options.hostname = proxy.host.replace(/:\d+/, ""), options.port = proxy.port, options.host = getHostFromUri(Object.assign({}, uri, proxy)), options.href = `${options.protocol}//${options.host}${options.path}`, options.path = url.format(uri), options; } function getProxyOptions(options) { let proxy; if (options.hasOwnProperty("proxy")) proxy = options.proxy; else { const uri = url.parse(options.url); proxy = getProxyFromUri(uri); } return typeof proxy == "string" ? url.parse(proxy) : proxy; } /*! simple-concat. MIT License. Feross Aboukhadijeh */ function concat(stream, cb) { const chunks = []; stream.on("data", function(chunk) { chunks.push(chunk); }), stream.once("end", function() { cb && cb(null, Buffer.concat(chunks)), cb = null; }), stream.once("error", function(err) { cb && cb(err), cb = null; }); } function timedOut(req, time) { if (req.timeoutTimer) return req; const delays = isNaN(time) ? time : { socket: time, connect: time }, hostHeader = req.getHeader("host"), host = hostHeader ? " to " + hostHeader : ""; delays.connect !== void 0 && (req.timeoutTimer = setTimeout(function() { req.abort(); const e = new Error("Connection timed out on request" + host); e.code = "ETIMEDOUT", req.emit("error", e); }, delays.connect)), req.on("socket", function(socket) { if (!(socket.connecting || socket._connecting)) { connect(); return; } socket.once("connect", connect); }); function clear() { req.timeoutTimer && (clearTimeout(req.timeoutTimer), req.timeoutTimer = null); } function connect() { clear(), delays.socket !== void 0 && req.setTimeout(delays.socket, function() { req.abort(); const e = new Error("Socket timed out on request" + host); e.code = "ESOCKETTIMEDOUT", req.emit("error", e); }); } return req.on("error", clear); } const uriParts = [ "protocol", "slashes", "auth", "host", "port", "hostname", "hash", "search", "query", "pathname", "path", "href" ], defaultProxyHeaderWhiteList = [ "accept", "accept-charset", "accept-encoding", "accept-language", "accept-ranges", "cache-control", "content-encoding", "content-language", "content-location", "content-md5", "content-range", "content-type", "connection", "date", "expect", "max-forwards", "pragma", "referer", "te", "user-agent", "via" ], defaultProxyHeaderExclusiveList = ["proxy-authorization"]; function shouldEnable(options) { return typeof options.tunnel < "u" ? !!options.tunnel : url.parse(options.url).protocol === "https:"; } function applyAgent(opts = {}, proxy) { const options = Object.assign({}, opts), proxyHeaderWhiteList = defaultProxyHeaderWhiteList.concat(options.proxyHeaderWhiteList || []).map((header) => header.toLowerCase()), proxyHeaderExclusiveList = defaultProxyHeaderExclusiveList.concat(options.proxyHeaderExclusiveList || []).map((header) => header.toLowerCase()), proxyHeaders = getAllowedProxyHeaders(options.headers, proxyHeaderWhiteList); proxyHeaders.host = constructProxyHost(options), options.headers = Object.keys(options.headers || {}).reduce((headers, header) => (proxyHeaderExclusiveList.indexOf(header.toLowerCase()) === -1 && (headers[header] = options.headers[header]), headers), {}); const tunnelFn = getTunnelFn(options, proxy), tunnelOptions = constructTunnelOptions(options, proxy, proxyHeaders); return options.agent = tunnelFn(tunnelOptions), options; } function getTunnelFn(options, proxy) { const uri = getUriParts(options), tunnelFnName = constructTunnelFnName(uri, proxy); return tunnel[tunnelFnName]; } function getUriParts(options) { return uriParts.reduce((uri, part) => (uri[part] = options[part], uri), {}); } function constructTunnelFnName(uri, proxy) { const uriProtocol = uri.protocol === "https:" ? "https" : "http", proxyProtocol = proxy.protocol === "https:" ? "Https" : "Http"; return `${uriProtocol}Over${proxyProtocol}`; } function constructProxyHost(uri) { const port = uri.port, protocol = uri.protocol; let proxyHost = `${uri.hostname}:`; return port ? proxyHost += port : protocol === "https:" ? proxyHost += "443" : proxyHost += "80", proxyHost; } function getAllowedProxyHeaders(headers, whiteList) { return Object.keys(headers).filter((header) => whiteList.indexOf(header.toLowerCase()) !== -1).reduce((set, header) => (set[header] = headers[header], set), {}); } function constructTunnelOptions(options, proxy, proxyHeaders) { return { proxy: { host: proxy.hostname, port: +proxy.port, proxyAuth: proxy.auth, headers: proxyHeaders }, headers: options.headers, ca: options.ca, cert: options.cert, key: options.key, passphrase: options.passphrase, pfx: options.pfx, ciphers: options.ciphers, rejectUnauthorized: options.rejectUnauthorized, secureOptions: options.secureOptions, secureProtocol: options.secureProtocol }; } const adapter = "node", reduceResponse = (res, reqUrl, method, body) => ({ body, url: reqUrl, method, headers: res.headers, statusCode: res.statusCode, statusMessage: res.statusMessage }), httpRequester = (context, cb) => { const { options } = context, uri = Object.assign({}, url.parse(options.url)); if (typeof fetch == "function" && options.fetch) { const controller = new AbortController(), reqOpts2 = context.applyMiddleware("finalizeOptions", { ...uri, method: options.method, headers: { ...typeof options.fetch == "object" && options.fetch.headers ? lowerCaseHeaders(options.fetch.headers) : {}, ...lowerCaseHeaders(options.headers) }, maxRedirects: options.maxRedirects }), fetchOpts = { credentials: options.withCredentials ? "include" : "omit", ...typeof options.fetch == "object" ? options.fetch : {}, method: reqOpts2.method, headers: reqOpts2.headers, body: options.body, signal: controller.signal }, injectedResponse2 = context.applyMiddleware("interceptRequest", void 0, { adapter, context }); if (injectedResponse2) { const cbTimer = setTimeout(cb, 0, null, injectedResponse2); return { abort: () => clearTimeout(cbTimer) }; } const request2 = fetch(options.url, fetchOpts); return context.applyMiddleware("onRequest", { options, adapter, request: request2, context }), request2.then(async (res) => { const body = options.rawBody ? res.body : await res.text(), headers = {}; res.headers.forEach((value, key) => { headers[key] = value; }), cb(null, { body, url: res.url, method: options.method, headers, statusCode: res.status, statusMessage: res.statusText }); }).catch((err) => { err.name != "AbortError" && cb(err); }), { abort: () => controller.abort() }; } const bodyType = isStream(options.body) ? "stream" : typeof options.body; if (bodyType !== "undefined" && bodyType !== "stream" && bodyType !== "string" && !Buffer.isBuffer(options.body)) throw new Error(`Request body must be a string, buffer or stream, got ${bodyType}`); const lengthHeader = {}; options.bodySize ? lengthHeader["content-length"] = options.bodySize : options.body && bodyType !== "stream" && (lengthHeader["content-length"] = Buffer.byteLength(options.body)); let aborted = !1; const callback = (err, res) => !aborted && cb(err, res); context.channels.abort.subscribe(() => { aborted = !0; }); let reqOpts = Object.assign({}, uri, { method: options.method, headers: Object.assign({}, lowerCaseHeaders(options.headers), lengthHeader), maxRedirects: options.maxRedirects }); const proxy = getProxyOptions(options), tunnel2 = proxy && shouldEnable(options), injectedResponse = context.applyMiddleware("interceptRequest", void 0, { adapter, context }); if (injectedResponse) { const cbTimer = setImmediate(callback, null, injectedResponse); return { abort: () => clearImmediate(cbTimer) }; } if (options.maxRedirects !== 0 && (reqOpts.maxRedirects = options.maxRedirects || 5), proxy && tunnel2 ? reqOpts = applyAgent(reqOpts, proxy) : proxy && !tunnel2 && (reqOpts = rewriteUriForProxy(reqOpts, uri, proxy)), !tunnel2 && proxy && proxy.auth && !reqOpts.headers["proxy-authorization"]) { const [username, password] = proxy.auth.username ? [proxy.auth.username, proxy.auth.password] : proxy.auth.split(":").map((item) => qs.unescape(item)), authBase64 = Buffer.from(`${username}:${password}`, "utf8").toString("base64"); reqOpts.headers["proxy-authorization"] = `Basic ${authBase64}`; } const transport = getRequestTransport(reqOpts, proxy, tunnel2); typeof options.debug == "function" && proxy && options.debug( "Proxying using %s", reqOpts.agent ? "tunnel agent" : `${reqOpts.host}:${reqOpts.port}` ); const tryCompressed = reqOpts.method !== "HEAD"; tryCompressed && !reqOpts.headers["accept-encoding"] && options.compress !== !1 && (reqOpts.headers["accept-encoding"] = "br, gzip, deflate"); const finalOptions = context.applyMiddleware( "finalizeOptions", reqOpts ), request = transport.request(finalOptions, (response) => { const res = tryCompressed ? decompressResponse(response) : response, resStream = context.applyMiddleware("onHeaders", res, { headers: response.headers, adapter, context }), reqUrl = "responseUrl" in response ? response.responseUrl : options.url; if (options.stream) { callback(null, reduceResponse(res, reqUrl, reqOpts.method, resStream)); return; } concat(resStream, (err, data) => { if (err) return callback(err); const body = options.rawBody ? data : data.toString(), reduced = reduceResponse(res, reqUrl, reqOpts.method, body); return callback(null, reduced); }); }); options.timeout && timedOut(request, options.timeout), request.once("error", callback); const { bodyStream, progress } = getProgressStream(options); return context.applyMiddleware("onRequest", { options, adapter, request, context, progress }), bodyStream ? bodyStream.pipe(request) : request.end(options.body), { abort: () => request.abort() }; }; function getProgressStream(options) { if (!options.body) return {}; const bodyIsStream = isStream(options.body), length = options.bodySize || (bodyIsStream ? null : Buffer.byteLength(options.body)); if (!length) return bodyIsStream ? { bodyStream: options.body } : {}; const progress = progressStream({ time: 16, length }); return { bodyStream: (bodyIsStream ? options.body : toStream(options.body)).pipe(progress), progress }; } function getRequestTransport(reqOpts, proxy, tunnel2) { const isHttpsRequest = reqOpts.protocol === "https:", transports = reqOpts.maxRedirects === 0 ? { http, https } : { http: follow.http, https: follow.https }; if (!proxy || tunnel2) return isHttpsRequest ? transports.https : transports.http; let isHttpsProxy = proxy.port === 443; return proxy.protocol && (isHttpsProxy = /^https:?/.test(proxy.protocol)), isHttpsProxy ? transports.https : transports.http; } const getIt = (initMiddleware = [], httpRequest = httpRequester) => createRequester(initMiddleware, httpRequest), environment = "node"; export { adapter, environment, getIt }; //# sourceMappingURL=index.js.map