63 lines
2.1 KiB
JavaScript
Executable File
63 lines
2.1 KiB
JavaScript
Executable File
/**
|
|
* 将发往字面量 IPv4 的 https 请求改写为 http。
|
|
* 用于云控面板 HTTP 入口对浏览器返回 307 升级 HTTPS、但 IP 上 443 不可达的场景。
|
|
*/
|
|
'use strict';
|
|
|
|
function rewriteHttpsToHttpForLiteralIp(url) {
|
|
try {
|
|
const parsed = new URL(url);
|
|
if (parsed.protocol !== 'https:') {
|
|
return url;
|
|
}
|
|
if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(parsed.hostname)) {
|
|
return url;
|
|
}
|
|
parsed.protocol = 'http:';
|
|
return parsed.toString();
|
|
} catch (_) {
|
|
return url;
|
|
}
|
|
}
|
|
|
|
async function attachHttpIpRewriteInterceptor(page, contextLabel = 'page', options = {}) {
|
|
const shareToken = typeof options.shareToken === 'string' ? options.shareToken : '';
|
|
const blockHeavyResources = options.blockHeavyResources !== false;
|
|
await page.setRequestInterception(true);
|
|
page.on('request', (req) => {
|
|
if (req.isInterceptResolutionHandled()) {
|
|
return;
|
|
}
|
|
if (blockHeavyResources) {
|
|
const resourceType = req.resourceType();
|
|
if (['image', 'media', 'font'].includes(resourceType)) {
|
|
req.abort();
|
|
return;
|
|
}
|
|
}
|
|
const originalUrl = req.url();
|
|
const rewrittenUrl = rewriteHttpsToHttpForLiteralIp(originalUrl);
|
|
if (rewrittenUrl !== originalUrl) {
|
|
const continueOptions = { url: rewrittenUrl };
|
|
if (shareToken) {
|
|
const headers = { ...req.headers() };
|
|
const existingCookie = headers.cookie || headers.Cookie || '';
|
|
if (!existingCookie.includes('share_token=')) {
|
|
headers.cookie = existingCookie
|
|
? `${existingCookie}; share_token=${shareToken}`
|
|
: `share_token=${shareToken}`;
|
|
}
|
|
continueOptions.headers = headers;
|
|
}
|
|
req.continue(continueOptions);
|
|
return;
|
|
}
|
|
req.continue();
|
|
});
|
|
}
|
|
|
|
module.exports = {
|
|
rewriteHttpsToHttpForLiteralIp,
|
|
attachHttpIpRewriteInterceptor,
|
|
};
|