@skrillex1224/playwright-toolkit 2.1.26 → 2.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +67 -31
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +68 -32
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1282,9 +1282,18 @@ var Captcha = {
|
|
|
1282
1282
|
};
|
|
1283
1283
|
|
|
1284
1284
|
// src/sse.js
|
|
1285
|
-
var
|
|
1286
|
-
var
|
|
1285
|
+
var import_got_scraping = require("got-scraping");
|
|
1286
|
+
var import_http = require("http");
|
|
1287
|
+
var import_https = require("https");
|
|
1287
1288
|
var logger7 = createLogger("Sse");
|
|
1289
|
+
var SHARED_HTTP_AGENT = new import_http.Agent({ keepAlive: false });
|
|
1290
|
+
var SHARED_HTTPS_AGENT = new import_https.Agent({ keepAlive: false, rejectUnauthorized: false });
|
|
1291
|
+
var SHARED_GOT_OPTIONS = {
|
|
1292
|
+
http2: false,
|
|
1293
|
+
retry: { limit: 0 },
|
|
1294
|
+
throwHttpErrors: false,
|
|
1295
|
+
decompress: false
|
|
1296
|
+
};
|
|
1288
1297
|
var Sse = {
|
|
1289
1298
|
/**
|
|
1290
1299
|
* 解析 SSE 流文本
|
|
@@ -1311,7 +1320,7 @@ var Sse = {
|
|
|
1311
1320
|
return events;
|
|
1312
1321
|
},
|
|
1313
1322
|
/**
|
|
1314
|
-
* 拦截网络请求并使用
|
|
1323
|
+
* 拦截网络请求并使用 got-scraping 转发,以解决流式数据捕获问题。
|
|
1315
1324
|
* @param {import('playwright').Page} page
|
|
1316
1325
|
* @param {string|RegExp} urlPattern - 拦截的 URL 模式
|
|
1317
1326
|
* @param {object} options
|
|
@@ -1319,7 +1328,7 @@ var Sse = {
|
|
|
1319
1328
|
* @param {function(string, function): void} [options.onEnd] - (fullText, resolve) => void
|
|
1320
1329
|
* @param {function(Error, function): void} [options.onTimeout] - (error, reject) => void
|
|
1321
1330
|
* @param {number} [options.initialTimeout=90000] - 初始数据接收超时 (ms),默认 90s
|
|
1322
|
-
* @param {number} [options.
|
|
1331
|
+
* @param {number} [options.overallTimeout=180000] - 整体请求超时时间 (ms),默认 180s
|
|
1323
1332
|
* @returns {Promise<any>} - 返回 Promise,当流满足条件时 resolve
|
|
1324
1333
|
*/
|
|
1325
1334
|
async intercept(page, urlPattern, options = {}) {
|
|
@@ -1345,19 +1354,39 @@ var Sse = {
|
|
|
1345
1354
|
logger7.info(`[MITM] \u5DF2\u62E6\u622A\u8BF7\u6C42: ${request.url()}`);
|
|
1346
1355
|
try {
|
|
1347
1356
|
const headers = await request.allHeaders();
|
|
1348
|
-
|
|
1349
|
-
const urlObj = new import_url.URL(request.url());
|
|
1357
|
+
delete headers["host"];
|
|
1350
1358
|
delete headers["accept-encoding"];
|
|
1351
1359
|
delete headers["content-length"];
|
|
1360
|
+
const currentAcceptLanguage = headers["accept-language"] || "";
|
|
1361
|
+
AntiCheat.applyLocaleHeaders(headers, currentAcceptLanguage);
|
|
1362
|
+
const resolvedAcceptLanguage = headers["accept-language"] || "";
|
|
1363
|
+
const userAgent = headers["user-agent"] || "";
|
|
1364
|
+
const method = request.method();
|
|
1365
|
+
const postData = method !== "GET" && method !== "HEAD" ? request.postDataBuffer() : void 0;
|
|
1352
1366
|
const reqOptions = {
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
method: request.method(),
|
|
1367
|
+
...SHARED_GOT_OPTIONS,
|
|
1368
|
+
url: request.url(),
|
|
1369
|
+
method,
|
|
1357
1370
|
headers,
|
|
1358
|
-
|
|
1371
|
+
headerGeneratorOptions: AntiCheat.getTlsFingerprintOptions(userAgent, resolvedAcceptLanguage),
|
|
1372
|
+
agent: {
|
|
1373
|
+
http: SHARED_HTTP_AGENT,
|
|
1374
|
+
https: SHARED_HTTPS_AGENT
|
|
1375
|
+
},
|
|
1376
|
+
timeout: { request: overallTimeout }
|
|
1377
|
+
};
|
|
1378
|
+
if (postData) {
|
|
1379
|
+
reqOptions.body = postData;
|
|
1380
|
+
}
|
|
1381
|
+
const stream = import_got_scraping.gotScraping.stream(reqOptions);
|
|
1382
|
+
const handleStreamError = (error) => {
|
|
1383
|
+
clearAllTimers();
|
|
1384
|
+
stream.destroy();
|
|
1385
|
+
route.abort().catch(() => {
|
|
1386
|
+
});
|
|
1387
|
+
reject(error);
|
|
1359
1388
|
};
|
|
1360
|
-
|
|
1389
|
+
stream.on("response", (res) => {
|
|
1361
1390
|
const chunks = [];
|
|
1362
1391
|
let accumulatedText = "";
|
|
1363
1392
|
res.on("data", (chunk) => {
|
|
@@ -1380,6 +1409,7 @@ var Sse = {
|
|
|
1380
1409
|
}
|
|
1381
1410
|
}
|
|
1382
1411
|
});
|
|
1412
|
+
res.on("error", handleStreamError);
|
|
1383
1413
|
res.on("end", () => {
|
|
1384
1414
|
logger7.info("[MITM] \u4E0A\u6E38\u54CD\u5E94\u7ED3\u675F");
|
|
1385
1415
|
clearAllTimers();
|
|
@@ -1392,22 +1422,28 @@ var Sse = {
|
|
|
1392
1422
|
} else if (!onData) {
|
|
1393
1423
|
resolve(accumulatedText);
|
|
1394
1424
|
}
|
|
1425
|
+
const resHeaders = {};
|
|
1426
|
+
for (const [key, value] of Object.entries(res.headers || {})) {
|
|
1427
|
+
if (Array.isArray(value)) {
|
|
1428
|
+
resHeaders[key] = value.join(", ");
|
|
1429
|
+
} else if (value) {
|
|
1430
|
+
resHeaders[key] = String(value);
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
delete resHeaders["content-encoding"];
|
|
1434
|
+
delete resHeaders["content-length"];
|
|
1435
|
+
delete resHeaders["transfer-encoding"];
|
|
1436
|
+
delete resHeaders["connection"];
|
|
1437
|
+
delete resHeaders["keep-alive"];
|
|
1395
1438
|
route.fulfill({
|
|
1396
|
-
status: res.statusCode,
|
|
1397
|
-
headers:
|
|
1439
|
+
status: res.statusCode || 200,
|
|
1440
|
+
headers: resHeaders,
|
|
1398
1441
|
body: Buffer.concat(chunks)
|
|
1399
1442
|
}).catch(() => {
|
|
1400
1443
|
});
|
|
1401
1444
|
});
|
|
1402
1445
|
});
|
|
1403
|
-
|
|
1404
|
-
clearAllTimers();
|
|
1405
|
-
route.abort().catch(() => {
|
|
1406
|
-
});
|
|
1407
|
-
reject(e);
|
|
1408
|
-
});
|
|
1409
|
-
if (postData) req.write(postData);
|
|
1410
|
-
req.end();
|
|
1446
|
+
stream.on("error", handleStreamError);
|
|
1411
1447
|
} catch (e) {
|
|
1412
1448
|
clearAllTimers();
|
|
1413
1449
|
route.continue().catch(() => {
|
|
@@ -1466,12 +1502,12 @@ var Sse = {
|
|
|
1466
1502
|
};
|
|
1467
1503
|
|
|
1468
1504
|
// src/interception.js
|
|
1469
|
-
var
|
|
1470
|
-
var
|
|
1505
|
+
var import_got_scraping2 = require("got-scraping");
|
|
1506
|
+
var import_http2 = require("http");
|
|
1471
1507
|
var import_https2 = require("https");
|
|
1472
1508
|
var logger8 = createLogger("Interception");
|
|
1473
|
-
var
|
|
1474
|
-
var
|
|
1509
|
+
var SHARED_HTTP_AGENT2 = new import_http2.Agent({ keepAlive: false });
|
|
1510
|
+
var SHARED_HTTPS_AGENT2 = new import_https2.Agent({ keepAlive: false, rejectUnauthorized: false });
|
|
1475
1511
|
var DirectConfig = {
|
|
1476
1512
|
/** 直连请求超时时间(秒) */
|
|
1477
1513
|
directTimeout: 12,
|
|
@@ -1524,7 +1560,7 @@ var DEFAULT_BLOCKING_CONFIG = {
|
|
|
1524
1560
|
/** 额外自定义扩展名列表 */
|
|
1525
1561
|
customExtensions: []
|
|
1526
1562
|
};
|
|
1527
|
-
var
|
|
1563
|
+
var SHARED_GOT_OPTIONS2 = {
|
|
1528
1564
|
http2: false,
|
|
1529
1565
|
// 禁用 HTTP2 避免在拦截场景下的握手兼容性问题
|
|
1530
1566
|
retry: { limit: 0 },
|
|
@@ -1633,8 +1669,8 @@ var Interception = {
|
|
|
1633
1669
|
const userAgent = reqHeaders["user-agent"] || "";
|
|
1634
1670
|
const method = request.method();
|
|
1635
1671
|
const postData = method !== "GET" && method !== "HEAD" ? request.postDataBuffer() : void 0;
|
|
1636
|
-
const response = await (0,
|
|
1637
|
-
...
|
|
1672
|
+
const response = await (0, import_got_scraping2.gotScraping)({
|
|
1673
|
+
...SHARED_GOT_OPTIONS2,
|
|
1638
1674
|
// 应用通用配置
|
|
1639
1675
|
url,
|
|
1640
1676
|
method,
|
|
@@ -1646,8 +1682,8 @@ var Interception = {
|
|
|
1646
1682
|
headerGeneratorOptions: AntiCheat.getTlsFingerprintOptions(userAgent, resolvedAcceptLanguage),
|
|
1647
1683
|
// 使用共享的 Agent 单例(keepAlive: false,不会池化连接)
|
|
1648
1684
|
agent: {
|
|
1649
|
-
http:
|
|
1650
|
-
https:
|
|
1685
|
+
http: SHARED_HTTP_AGENT2,
|
|
1686
|
+
https: SHARED_HTTPS_AGENT2
|
|
1651
1687
|
},
|
|
1652
1688
|
// 超时时间
|
|
1653
1689
|
timeout: { request: DirectConfig.directTimeout * 1e3 }
|