First Commit
This commit is contained in:
621
node_modules/playwright-core/lib/server/fetch.js
generated
vendored
Normal file
621
node_modules/playwright-core/lib/server/fetch.js
generated
vendored
Normal file
@@ -0,0 +1,621 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var fetch_exports = {};
|
||||
__export(fetch_exports, {
|
||||
APIRequestContext: () => APIRequestContext,
|
||||
BrowserContextAPIRequestContext: () => BrowserContextAPIRequestContext,
|
||||
GlobalAPIRequestContext: () => GlobalAPIRequestContext
|
||||
});
|
||||
module.exports = __toCommonJS(fetch_exports);
|
||||
var import_http = __toESM(require("http"));
|
||||
var import_https = __toESM(require("https"));
|
||||
var import_stream = require("stream");
|
||||
var import_tls = require("tls");
|
||||
var zlib = __toESM(require("zlib"));
|
||||
var import_utils = require("../utils");
|
||||
var import_crypto = require("./utils/crypto");
|
||||
var import_userAgent = require("./utils/userAgent");
|
||||
var import_browserContext = require("./browserContext");
|
||||
var import_cookieStore = require("./cookieStore");
|
||||
var import_formData = require("./formData");
|
||||
var import_instrumentation = require("./instrumentation");
|
||||
var import_progress = require("./progress");
|
||||
var import_socksClientCertificatesInterceptor = require("./socksClientCertificatesInterceptor");
|
||||
var import_happyEyeballs = require("./utils/happyEyeballs");
|
||||
var import_tracing = require("./trace/recorder/tracing");
|
||||
class APIRequestContext extends import_instrumentation.SdkObject {
|
||||
constructor(parent) {
|
||||
super(parent, "request-context");
|
||||
this.fetchResponses = /* @__PURE__ */ new Map();
|
||||
this.fetchLog = /* @__PURE__ */ new Map();
|
||||
APIRequestContext.allInstances.add(this);
|
||||
}
|
||||
static {
|
||||
this.Events = {
|
||||
Dispose: "dispose",
|
||||
Request: "request",
|
||||
RequestFinished: "requestfinished"
|
||||
};
|
||||
}
|
||||
static {
|
||||
this.allInstances = /* @__PURE__ */ new Set();
|
||||
}
|
||||
static findResponseBody(guid) {
|
||||
for (const request of APIRequestContext.allInstances) {
|
||||
const body = request.fetchResponses.get(guid);
|
||||
if (body)
|
||||
return body;
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
_disposeImpl() {
|
||||
APIRequestContext.allInstances.delete(this);
|
||||
this.fetchResponses.clear();
|
||||
this.fetchLog.clear();
|
||||
this.emit(APIRequestContext.Events.Dispose);
|
||||
}
|
||||
disposeResponse(fetchUid) {
|
||||
this.fetchResponses.delete(fetchUid);
|
||||
this.fetchLog.delete(fetchUid);
|
||||
}
|
||||
_storeResponseBody(body) {
|
||||
const uid = (0, import_crypto.createGuid)();
|
||||
this.fetchResponses.set(uid, body);
|
||||
return uid;
|
||||
}
|
||||
async fetch(progress, params) {
|
||||
const defaults = this._defaultOptions();
|
||||
const headers = {
|
||||
"user-agent": defaults.userAgent,
|
||||
"accept": "*/*",
|
||||
"accept-encoding": "gzip,deflate,br"
|
||||
};
|
||||
if (defaults.extraHTTPHeaders) {
|
||||
for (const { name, value } of defaults.extraHTTPHeaders)
|
||||
setHeader(headers, name, value);
|
||||
}
|
||||
if (params.headers) {
|
||||
for (const { name, value } of params.headers)
|
||||
setHeader(headers, name, value);
|
||||
}
|
||||
const requestUrl = new URL((0, import_utils.constructURLBasedOnBaseURL)(defaults.baseURL, params.url));
|
||||
if (params.encodedParams) {
|
||||
requestUrl.search = params.encodedParams;
|
||||
} else if (params.params) {
|
||||
for (const { name, value } of params.params)
|
||||
requestUrl.searchParams.append(name, value);
|
||||
}
|
||||
const credentials = this._getHttpCredentials(requestUrl);
|
||||
if (credentials?.send === "always")
|
||||
setBasicAuthorizationHeader(headers, credentials);
|
||||
const method = params.method?.toUpperCase() || "GET";
|
||||
const proxy = defaults.proxy;
|
||||
let agent;
|
||||
if (proxy?.server !== "per-context")
|
||||
agent = (0, import_utils.createProxyAgent)(proxy, requestUrl);
|
||||
let maxRedirects = params.maxRedirects ?? (defaults.maxRedirects ?? 20);
|
||||
maxRedirects = maxRedirects === 0 ? -1 : maxRedirects;
|
||||
const options = {
|
||||
method,
|
||||
headers,
|
||||
agent,
|
||||
maxRedirects,
|
||||
...(0, import_socksClientCertificatesInterceptor.getMatchingTLSOptionsForOrigin)(this._defaultOptions().clientCertificates, requestUrl.origin),
|
||||
__testHookLookup: params.__testHookLookup
|
||||
};
|
||||
if (params.ignoreHTTPSErrors || defaults.ignoreHTTPSErrors)
|
||||
options.rejectUnauthorized = false;
|
||||
const postData = serializePostData(params, headers);
|
||||
if (postData)
|
||||
setHeader(headers, "content-length", String(postData.byteLength));
|
||||
const fetchResponse = await this._sendRequestWithRetries(progress, requestUrl, options, postData, params.maxRetries);
|
||||
const fetchUid = this._storeResponseBody(fetchResponse.body);
|
||||
this.fetchLog.set(fetchUid, progress.metadata.log);
|
||||
const failOnStatusCode = params.failOnStatusCode !== void 0 ? params.failOnStatusCode : !!defaults.failOnStatusCode;
|
||||
if (failOnStatusCode && (fetchResponse.status < 200 || fetchResponse.status >= 400)) {
|
||||
let responseText = "";
|
||||
if (fetchResponse.body.byteLength) {
|
||||
let text = fetchResponse.body.toString("utf8");
|
||||
if (text.length > 1e3)
|
||||
text = text.substring(0, 997) + "...";
|
||||
responseText = `
|
||||
Response text:
|
||||
${text}`;
|
||||
}
|
||||
throw new Error(`${fetchResponse.status} ${fetchResponse.statusText}${responseText}`);
|
||||
}
|
||||
return { ...fetchResponse, fetchUid };
|
||||
}
|
||||
_parseSetCookieHeader(responseUrl, setCookie) {
|
||||
if (!setCookie)
|
||||
return [];
|
||||
const url = new URL(responseUrl);
|
||||
const defaultPath = "/" + url.pathname.substr(1).split("/").slice(0, -1).join("/");
|
||||
const cookies = [];
|
||||
for (const header of setCookie) {
|
||||
const cookie = parseCookie(header);
|
||||
if (!cookie)
|
||||
continue;
|
||||
if (!cookie.domain)
|
||||
cookie.domain = url.hostname;
|
||||
else
|
||||
(0, import_utils.assert)(cookie.domain.startsWith(".") || !cookie.domain.includes("."));
|
||||
if (!(0, import_cookieStore.domainMatches)(url.hostname, cookie.domain))
|
||||
continue;
|
||||
if (!cookie.path || !cookie.path.startsWith("/"))
|
||||
cookie.path = defaultPath;
|
||||
cookies.push(cookie);
|
||||
}
|
||||
return cookies;
|
||||
}
|
||||
async _updateRequestCookieHeader(progress, url, headers) {
|
||||
if (getHeader(headers, "cookie") !== void 0)
|
||||
return;
|
||||
const contextCookies = await progress.race(this._cookies(url));
|
||||
const cookies = contextCookies.filter((c) => new import_cookieStore.Cookie(c).matches(url));
|
||||
if (cookies.length) {
|
||||
const valueArray = cookies.map((c) => `${c.name}=${c.value}`);
|
||||
setHeader(headers, "cookie", valueArray.join("; "));
|
||||
}
|
||||
}
|
||||
async _sendRequestWithRetries(progress, url, options, postData, maxRetries) {
|
||||
maxRetries ??= 0;
|
||||
let backoff = 250;
|
||||
for (let i = 0; i <= maxRetries; i++) {
|
||||
try {
|
||||
return await this._sendRequest(progress, url, options, postData);
|
||||
} catch (e) {
|
||||
if ((0, import_progress.isAbortError)(e))
|
||||
throw e;
|
||||
e = (0, import_socksClientCertificatesInterceptor.rewriteOpenSSLErrorIfNeeded)(e);
|
||||
if (maxRetries === 0)
|
||||
throw e;
|
||||
if (i === maxRetries)
|
||||
throw new Error(`Failed after ${i + 1} attempt(s): ${e}`);
|
||||
if (e.code !== "ECONNRESET")
|
||||
throw e;
|
||||
progress.log(` Received ECONNRESET, will retry after ${backoff}ms.`);
|
||||
await progress.wait(backoff);
|
||||
backoff *= 2;
|
||||
}
|
||||
}
|
||||
throw new Error("Unreachable");
|
||||
}
|
||||
async _sendRequest(progress, url, options, postData) {
|
||||
await this._updateRequestCookieHeader(progress, url, options.headers);
|
||||
const requestCookies = getHeader(options.headers, "cookie")?.split(";").map((p) => {
|
||||
const [name, value] = p.split("=").map((v) => v.trim());
|
||||
return { name, value };
|
||||
}) || [];
|
||||
const requestEvent = {
|
||||
url,
|
||||
method: options.method,
|
||||
headers: options.headers,
|
||||
cookies: requestCookies,
|
||||
postData
|
||||
};
|
||||
this.emit(APIRequestContext.Events.Request, requestEvent);
|
||||
let destroyRequest;
|
||||
const resultPromise = new Promise((fulfill, reject) => {
|
||||
const requestConstructor = (url.protocol === "https:" ? import_https.default : import_http.default).request;
|
||||
const agent = options.agent || (url.protocol === "https:" ? import_happyEyeballs.httpsHappyEyeballsAgent : import_happyEyeballs.httpHappyEyeballsAgent);
|
||||
const requestOptions = { ...options, agent };
|
||||
const startAt = (0, import_utils.monotonicTime)();
|
||||
let reusedSocketAt;
|
||||
let dnsLookupAt;
|
||||
let tcpConnectionAt;
|
||||
let tlsHandshakeAt;
|
||||
let requestFinishAt;
|
||||
let serverIPAddress;
|
||||
let serverPort;
|
||||
let securityDetails;
|
||||
const listeners = [];
|
||||
const request = requestConstructor(url, requestOptions, async (response) => {
|
||||
const responseAt = (0, import_utils.monotonicTime)();
|
||||
const notifyRequestFinished = (body2) => {
|
||||
const endAt = (0, import_utils.monotonicTime)();
|
||||
const connectEnd = tlsHandshakeAt ?? tcpConnectionAt;
|
||||
const timings = {
|
||||
send: requestFinishAt - startAt,
|
||||
wait: responseAt - requestFinishAt,
|
||||
receive: endAt - responseAt,
|
||||
dns: dnsLookupAt ? dnsLookupAt - startAt : -1,
|
||||
connect: connectEnd ? connectEnd - startAt : -1,
|
||||
// "If [ssl] is defined then the time is also included in the connect field "
|
||||
ssl: tlsHandshakeAt ? tlsHandshakeAt - tcpConnectionAt : -1,
|
||||
blocked: reusedSocketAt ? reusedSocketAt - startAt : -1
|
||||
};
|
||||
const requestFinishedEvent = {
|
||||
requestEvent,
|
||||
httpVersion: response.httpVersion,
|
||||
statusCode: response.statusCode || 0,
|
||||
statusMessage: response.statusMessage || "",
|
||||
headers: response.headers,
|
||||
rawHeaders: response.rawHeaders,
|
||||
cookies,
|
||||
body: body2,
|
||||
timings,
|
||||
serverIPAddress,
|
||||
serverPort,
|
||||
securityDetails
|
||||
};
|
||||
this.emit(APIRequestContext.Events.RequestFinished, requestFinishedEvent);
|
||||
};
|
||||
progress.log(`\u2190 ${response.statusCode} ${response.statusMessage}`);
|
||||
for (const [name, value] of Object.entries(response.headers))
|
||||
progress.log(` ${name}: ${value}`);
|
||||
const cookies = this._parseSetCookieHeader(response.url || url.toString(), response.headers["set-cookie"]);
|
||||
if (cookies.length) {
|
||||
try {
|
||||
await this._addCookies(cookies);
|
||||
} catch (e) {
|
||||
await Promise.all(cookies.map((c) => this._addCookies([c]).catch(() => {
|
||||
})));
|
||||
}
|
||||
}
|
||||
if (redirectStatus.includes(response.statusCode) && options.maxRedirects >= 0) {
|
||||
if (options.maxRedirects === 0) {
|
||||
reject(new Error("Max redirect count exceeded"));
|
||||
request.destroy();
|
||||
return;
|
||||
}
|
||||
const headers = { ...options.headers };
|
||||
removeHeader(headers, `cookie`);
|
||||
const status = response.statusCode;
|
||||
let method = options.method;
|
||||
if ((status === 301 || status === 302) && method === "POST" || status === 303 && !["GET", "HEAD"].includes(method)) {
|
||||
method = "GET";
|
||||
postData = void 0;
|
||||
removeHeader(headers, `content-encoding`);
|
||||
removeHeader(headers, `content-language`);
|
||||
removeHeader(headers, `content-length`);
|
||||
removeHeader(headers, `content-location`);
|
||||
removeHeader(headers, `content-type`);
|
||||
}
|
||||
const redirectOptions = {
|
||||
method,
|
||||
headers,
|
||||
agent: options.agent,
|
||||
maxRedirects: options.maxRedirects - 1,
|
||||
...(0, import_socksClientCertificatesInterceptor.getMatchingTLSOptionsForOrigin)(this._defaultOptions().clientCertificates, url.origin),
|
||||
__testHookLookup: options.__testHookLookup
|
||||
};
|
||||
if (options.rejectUnauthorized === false)
|
||||
redirectOptions.rejectUnauthorized = false;
|
||||
const locationHeaderValue = Buffer.from(response.headers.location ?? "", "latin1").toString("utf8");
|
||||
if (locationHeaderValue) {
|
||||
let locationURL;
|
||||
try {
|
||||
locationURL = new URL(locationHeaderValue, url);
|
||||
} catch (error) {
|
||||
reject(new Error(`uri requested responds with an invalid redirect URL: ${locationHeaderValue}`));
|
||||
request.destroy();
|
||||
return;
|
||||
}
|
||||
if (headers["host"])
|
||||
headers["host"] = locationURL.host;
|
||||
notifyRequestFinished();
|
||||
fulfill(this._sendRequest(progress, locationURL, redirectOptions, postData));
|
||||
request.destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (response.statusCode === 401 && !getHeader(options.headers, "authorization")) {
|
||||
const auth = response.headers["www-authenticate"];
|
||||
const credentials = this._getHttpCredentials(url);
|
||||
if (auth?.trim().startsWith("Basic") && credentials) {
|
||||
setBasicAuthorizationHeader(options.headers, credentials);
|
||||
notifyRequestFinished();
|
||||
fulfill(this._sendRequest(progress, url, options, postData));
|
||||
request.destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
response.on("aborted", () => reject(new Error("aborted")));
|
||||
const chunks = [];
|
||||
const notifyBodyFinished = () => {
|
||||
const body2 = Buffer.concat(chunks);
|
||||
notifyRequestFinished(body2);
|
||||
fulfill({
|
||||
url: response.url || url.toString(),
|
||||
status: response.statusCode || 0,
|
||||
statusText: response.statusMessage || "",
|
||||
headers: toHeadersArray(response.rawHeaders),
|
||||
body: body2
|
||||
});
|
||||
};
|
||||
let body = response;
|
||||
let transform;
|
||||
const encoding = response.headers["content-encoding"];
|
||||
if (encoding === "gzip" || encoding === "x-gzip") {
|
||||
transform = zlib.createGunzip({
|
||||
flush: zlib.constants.Z_SYNC_FLUSH,
|
||||
finishFlush: zlib.constants.Z_SYNC_FLUSH
|
||||
});
|
||||
} else if (encoding === "br") {
|
||||
transform = zlib.createBrotliDecompress({
|
||||
flush: zlib.constants.BROTLI_OPERATION_FLUSH,
|
||||
finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH
|
||||
});
|
||||
} else if (encoding === "deflate") {
|
||||
transform = zlib.createInflate();
|
||||
}
|
||||
if (transform) {
|
||||
const emptyStreamTransform = new SafeEmptyStreamTransform(notifyBodyFinished);
|
||||
body = (0, import_stream.pipeline)(response, emptyStreamTransform, transform, (e) => {
|
||||
if (e)
|
||||
reject(new Error(`failed to decompress '${encoding}' encoding: ${e.message}`));
|
||||
});
|
||||
body.on("error", (e) => reject(new Error(`failed to decompress '${encoding}' encoding: ${e}`)));
|
||||
} else {
|
||||
body.on("error", reject);
|
||||
}
|
||||
body.on("data", (chunk) => chunks.push(chunk));
|
||||
body.on("end", notifyBodyFinished);
|
||||
});
|
||||
request.on("error", reject);
|
||||
destroyRequest = () => request.destroy();
|
||||
listeners.push(
|
||||
import_utils.eventsHelper.addEventListener(this, APIRequestContext.Events.Dispose, () => {
|
||||
reject(new Error("Request context disposed."));
|
||||
request.destroy();
|
||||
})
|
||||
);
|
||||
request.on("close", () => import_utils.eventsHelper.removeEventListeners(listeners));
|
||||
request.on("socket", (socket) => {
|
||||
if (request.reusedSocket) {
|
||||
reusedSocketAt = (0, import_utils.monotonicTime)();
|
||||
return;
|
||||
}
|
||||
const happyEyeBallsTimings = (0, import_happyEyeballs.timingForSocket)(socket);
|
||||
dnsLookupAt = happyEyeBallsTimings.dnsLookupAt;
|
||||
tcpConnectionAt = happyEyeBallsTimings.tcpConnectionAt;
|
||||
listeners.push(
|
||||
import_utils.eventsHelper.addEventListener(socket, "lookup", () => {
|
||||
dnsLookupAt = (0, import_utils.monotonicTime)();
|
||||
}),
|
||||
import_utils.eventsHelper.addEventListener(socket, "connect", () => {
|
||||
tcpConnectionAt = (0, import_utils.monotonicTime)();
|
||||
}),
|
||||
import_utils.eventsHelper.addEventListener(socket, "secureConnect", () => {
|
||||
tlsHandshakeAt = (0, import_utils.monotonicTime)();
|
||||
if (socket instanceof import_tls.TLSSocket) {
|
||||
const peerCertificate = socket.getPeerCertificate();
|
||||
securityDetails = {
|
||||
protocol: socket.getProtocol() ?? void 0,
|
||||
subjectName: peerCertificate.subject.CN,
|
||||
validFrom: new Date(peerCertificate.valid_from).getTime() / 1e3,
|
||||
validTo: new Date(peerCertificate.valid_to).getTime() / 1e3,
|
||||
issuer: peerCertificate.issuer.CN
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
serverIPAddress = socket.remoteAddress;
|
||||
serverPort = socket.remotePort;
|
||||
});
|
||||
request.on("finish", () => {
|
||||
requestFinishAt = (0, import_utils.monotonicTime)();
|
||||
});
|
||||
progress.log(`\u2192 ${options.method} ${url.toString()}`);
|
||||
if (options.headers) {
|
||||
for (const [name, value] of Object.entries(options.headers))
|
||||
progress.log(` ${name}: ${value}`);
|
||||
}
|
||||
if (postData)
|
||||
request.write(postData);
|
||||
request.end();
|
||||
});
|
||||
return progress.race(resultPromise).catch((error) => {
|
||||
destroyRequest?.();
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
_getHttpCredentials(url) {
|
||||
if (!this._defaultOptions().httpCredentials?.origin || url.origin.toLowerCase() === this._defaultOptions().httpCredentials?.origin?.toLowerCase())
|
||||
return this._defaultOptions().httpCredentials;
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
class SafeEmptyStreamTransform extends import_stream.Transform {
|
||||
constructor(onEmptyStreamCallback) {
|
||||
super();
|
||||
this._receivedSomeData = false;
|
||||
this._onEmptyStreamCallback = onEmptyStreamCallback;
|
||||
}
|
||||
_transform(chunk, encoding, callback) {
|
||||
this._receivedSomeData = true;
|
||||
callback(null, chunk);
|
||||
}
|
||||
_flush(callback) {
|
||||
if (this._receivedSomeData)
|
||||
callback(null);
|
||||
else
|
||||
this._onEmptyStreamCallback();
|
||||
}
|
||||
}
|
||||
class BrowserContextAPIRequestContext extends APIRequestContext {
|
||||
constructor(context) {
|
||||
super(context);
|
||||
this._context = context;
|
||||
context.once(import_browserContext.BrowserContext.Events.Close, () => this._disposeImpl());
|
||||
}
|
||||
tracing() {
|
||||
return this._context.tracing;
|
||||
}
|
||||
async dispose(options) {
|
||||
this._closeReason = options.reason;
|
||||
this.fetchResponses.clear();
|
||||
}
|
||||
_defaultOptions() {
|
||||
return {
|
||||
userAgent: this._context._options.userAgent || this._context._browser.userAgent(),
|
||||
extraHTTPHeaders: this._context._options.extraHTTPHeaders,
|
||||
failOnStatusCode: void 0,
|
||||
httpCredentials: this._context._options.httpCredentials,
|
||||
proxy: this._context._options.proxy || this._context._browser.options.proxy,
|
||||
ignoreHTTPSErrors: this._context._options.ignoreHTTPSErrors,
|
||||
baseURL: this._context._options.baseURL,
|
||||
clientCertificates: this._context._options.clientCertificates
|
||||
};
|
||||
}
|
||||
async _addCookies(cookies) {
|
||||
await this._context.addCookies(cookies);
|
||||
}
|
||||
async _cookies(url) {
|
||||
return await this._context.cookies(url.toString());
|
||||
}
|
||||
async storageState(progress, indexedDB) {
|
||||
return this._context.storageState(progress, indexedDB);
|
||||
}
|
||||
}
|
||||
class GlobalAPIRequestContext extends APIRequestContext {
|
||||
constructor(playwright, options) {
|
||||
super(playwright);
|
||||
this._cookieStore = new import_cookieStore.CookieStore();
|
||||
this.attribution.context = this;
|
||||
if (options.storageState) {
|
||||
this._origins = options.storageState.origins?.map((origin) => ({ indexedDB: [], ...origin }));
|
||||
this._cookieStore.addCookies(options.storageState.cookies || []);
|
||||
}
|
||||
(0, import_browserContext.verifyClientCertificates)(options.clientCertificates);
|
||||
this._options = {
|
||||
baseURL: options.baseURL,
|
||||
userAgent: options.userAgent || (0, import_userAgent.getUserAgent)(),
|
||||
extraHTTPHeaders: options.extraHTTPHeaders,
|
||||
failOnStatusCode: !!options.failOnStatusCode,
|
||||
ignoreHTTPSErrors: !!options.ignoreHTTPSErrors,
|
||||
maxRedirects: options.maxRedirects,
|
||||
httpCredentials: options.httpCredentials,
|
||||
clientCertificates: options.clientCertificates,
|
||||
proxy: options.proxy
|
||||
};
|
||||
this._tracing = new import_tracing.Tracing(this, options.tracesDir);
|
||||
}
|
||||
tracing() {
|
||||
return this._tracing;
|
||||
}
|
||||
async dispose(options) {
|
||||
this._closeReason = options.reason;
|
||||
await this._tracing.flush();
|
||||
await this._tracing.deleteTmpTracesDir();
|
||||
this._disposeImpl();
|
||||
}
|
||||
_defaultOptions() {
|
||||
return this._options;
|
||||
}
|
||||
async _addCookies(cookies) {
|
||||
this._cookieStore.addCookies(cookies);
|
||||
}
|
||||
async _cookies(url) {
|
||||
return this._cookieStore.cookies(url);
|
||||
}
|
||||
async storageState(progress, indexedDB = false) {
|
||||
return {
|
||||
cookies: this._cookieStore.allCookies(),
|
||||
origins: (this._origins || []).map((origin) => ({ ...origin, indexedDB: indexedDB ? origin.indexedDB : [] }))
|
||||
};
|
||||
}
|
||||
}
|
||||
function toHeadersArray(rawHeaders) {
|
||||
const result = [];
|
||||
for (let i = 0; i < rawHeaders.length; i += 2)
|
||||
result.push({ name: rawHeaders[i], value: rawHeaders[i + 1] });
|
||||
return result;
|
||||
}
|
||||
const redirectStatus = [301, 302, 303, 307, 308];
|
||||
function parseCookie(header) {
|
||||
const raw = (0, import_cookieStore.parseRawCookie)(header);
|
||||
if (!raw)
|
||||
return null;
|
||||
const cookie = {
|
||||
domain: "",
|
||||
path: "",
|
||||
expires: -1,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
|
||||
// The cookie-sending behavior if SameSite is not specified is SameSite=Lax.
|
||||
sameSite: "Lax",
|
||||
...raw
|
||||
};
|
||||
return cookie;
|
||||
}
|
||||
function serializePostData(params, headers) {
|
||||
(0, import_utils.assert)((params.postData ? 1 : 0) + (params.jsonData ? 1 : 0) + (params.formData ? 1 : 0) + (params.multipartData ? 1 : 0) <= 1, `Only one of 'data', 'form' or 'multipart' can be specified`);
|
||||
if (params.jsonData !== void 0) {
|
||||
setHeader(headers, "content-type", "application/json", true);
|
||||
return Buffer.from(params.jsonData, "utf8");
|
||||
} else if (params.formData) {
|
||||
const searchParams = new URLSearchParams();
|
||||
for (const { name, value } of params.formData)
|
||||
searchParams.append(name, value);
|
||||
setHeader(headers, "content-type", "application/x-www-form-urlencoded", true);
|
||||
return Buffer.from(searchParams.toString(), "utf8");
|
||||
} else if (params.multipartData) {
|
||||
const formData = new import_formData.MultipartFormData();
|
||||
for (const field of params.multipartData) {
|
||||
if (field.file)
|
||||
formData.addFileField(field.name, field.file);
|
||||
else if (field.value)
|
||||
formData.addField(field.name, field.value);
|
||||
}
|
||||
setHeader(headers, "content-type", formData.contentTypeHeader(), true);
|
||||
return formData.finish();
|
||||
} else if (params.postData !== void 0) {
|
||||
setHeader(headers, "content-type", "application/octet-stream", true);
|
||||
return params.postData;
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
function setHeader(headers, name, value, keepExisting = false) {
|
||||
const existing = Object.entries(headers).find((pair) => pair[0].toLowerCase() === name.toLowerCase());
|
||||
if (!existing)
|
||||
headers[name] = value;
|
||||
else if (!keepExisting)
|
||||
headers[existing[0]] = value;
|
||||
}
|
||||
function getHeader(headers, name) {
|
||||
const existing = Object.entries(headers).find((pair) => pair[0].toLowerCase() === name.toLowerCase());
|
||||
return existing ? existing[1] : void 0;
|
||||
}
|
||||
function removeHeader(headers, name) {
|
||||
delete headers[name];
|
||||
}
|
||||
function setBasicAuthorizationHeader(headers, credentials) {
|
||||
const { username, password } = credentials;
|
||||
const encoded = Buffer.from(`${username || ""}:${password || ""}`).toString("base64");
|
||||
setHeader(headers, "authorization", `Basic ${encoded}`);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
APIRequestContext,
|
||||
BrowserContextAPIRequestContext,
|
||||
GlobalAPIRequestContext
|
||||
});
|
Reference in New Issue
Block a user