@maintainer-pro/ai-bridge 0.1.23 → 0.1.24
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/package.json +1 -1
- package/src/daemon.mjs +245 -3
- package/src/share-rewrite.mjs +124 -18
package/package.json
CHANGED
package/src/daemon.mjs
CHANGED
|
@@ -2309,6 +2309,7 @@ function shareProxyContext(msg, ws, appId) {
|
|
|
2309
2309
|
acceptEncoding,
|
|
2310
2310
|
port: localPortForProxy(ws, appId),
|
|
2311
2311
|
portUrls: { ...fromWs, ...fromMsg },
|
|
2312
|
+
bypassCors: msg?.bypassCors === true,
|
|
2312
2313
|
};
|
|
2313
2314
|
}
|
|
2314
2315
|
|
|
@@ -2342,9 +2343,13 @@ function replyShareInterceptor(id, ctx, path) {
|
|
|
2342
2343
|
let body = "";
|
|
2343
2344
|
if (pathname === "/__mp/sw.js") {
|
|
2344
2345
|
headers["service-worker-allowed"] = tokenRoot;
|
|
2345
|
-
body = shareServiceWorkerScript(ctx.portUrls, tokenRoot);
|
|
2346
|
+
body = shareServiceWorkerScript(ctx.portUrls, tokenRoot, ctx.bypassCors);
|
|
2346
2347
|
} else {
|
|
2347
|
-
body = shareShimScript(
|
|
2348
|
+
body = shareShimScript(
|
|
2349
|
+
publicPathPrefix(ctx.publicBase),
|
|
2350
|
+
ctx.portUrls,
|
|
2351
|
+
ctx.bypassCors
|
|
2352
|
+
);
|
|
2348
2353
|
}
|
|
2349
2354
|
replyProxyHttp(id, 200, headers, body);
|
|
2350
2355
|
return true;
|
|
@@ -2476,6 +2481,234 @@ async function handleAiProxyHttpFromAdmin(msg, ws) {
|
|
|
2476
2481
|
});
|
|
2477
2482
|
}
|
|
2478
2483
|
|
|
2484
|
+
const EXTERNAL_PROXY_TIMEOUT_MS = 10 * 60 * 1000;
|
|
2485
|
+
const EXTERNAL_PROXY_MAX_REDIRECTS = 5;
|
|
2486
|
+
const EXTERNAL_PROXY_DROP_HEADERS = new Set([
|
|
2487
|
+
"cookie",
|
|
2488
|
+
"set-cookie",
|
|
2489
|
+
"host",
|
|
2490
|
+
"origin",
|
|
2491
|
+
"referer",
|
|
2492
|
+
"referrer",
|
|
2493
|
+
"connection",
|
|
2494
|
+
"keep-alive",
|
|
2495
|
+
"transfer-encoding",
|
|
2496
|
+
"upgrade",
|
|
2497
|
+
"content-length",
|
|
2498
|
+
"te",
|
|
2499
|
+
"trailer",
|
|
2500
|
+
"x-mp-target",
|
|
2501
|
+
"x-forwarded-proto",
|
|
2502
|
+
"x-forwarded-host",
|
|
2503
|
+
"x-forwarded-for",
|
|
2504
|
+
]);
|
|
2505
|
+
|
|
2506
|
+
function parseExternalProxyUrl(value) {
|
|
2507
|
+
let parsed;
|
|
2508
|
+
try {
|
|
2509
|
+
parsed = new URL(String(value || ""));
|
|
2510
|
+
} catch {
|
|
2511
|
+
return null;
|
|
2512
|
+
}
|
|
2513
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return null;
|
|
2514
|
+
const parts = parsed.pathname.split("/").filter(Boolean);
|
|
2515
|
+
if (parts[0] === "p" && parts[2] === "__cors") return null;
|
|
2516
|
+
return parsed;
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
function externalProxyHeaders(incoming, targetHost) {
|
|
2520
|
+
/** @type {Record<string, string>} */
|
|
2521
|
+
const headers = {};
|
|
2522
|
+
if (incoming && typeof incoming === "object") {
|
|
2523
|
+
for (const [key, value] of Object.entries(incoming)) {
|
|
2524
|
+
const lower = String(key).toLowerCase();
|
|
2525
|
+
if (EXTERNAL_PROXY_DROP_HEADERS.has(lower)) continue;
|
|
2526
|
+
if (lower.startsWith("sec-fetch-")) continue;
|
|
2527
|
+
if (typeof value === "string" && value) headers[key] = value;
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
headers.host = targetHost;
|
|
2531
|
+
return headers;
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
function failExternalProxyHttp(id, error) {
|
|
2535
|
+
proxyHttpReqs.delete(id);
|
|
2536
|
+
bridgeSend({
|
|
2537
|
+
type: "proxy.http.error",
|
|
2538
|
+
id,
|
|
2539
|
+
error: error instanceof Error ? error.message : String(error || "Upstream error"),
|
|
2540
|
+
});
|
|
2541
|
+
}
|
|
2542
|
+
|
|
2543
|
+
function streamExternalProxyHttp(id, res) {
|
|
2544
|
+
const stream = randomBytes(8).toString("hex");
|
|
2545
|
+
/** @type {Record<string, string>} */
|
|
2546
|
+
const outHeaders = {};
|
|
2547
|
+
for (const [key, value] of Object.entries(res.headers || {})) {
|
|
2548
|
+
if (value == null) continue;
|
|
2549
|
+
const lower = String(key).toLowerCase();
|
|
2550
|
+
if (lower === "set-cookie" || lower === "cookie") continue;
|
|
2551
|
+
outHeaders[key] = Array.isArray(value) ? value.join(", ") : String(value);
|
|
2552
|
+
}
|
|
2553
|
+
bridgeSend({
|
|
2554
|
+
type: "proxy.http.start",
|
|
2555
|
+
id,
|
|
2556
|
+
stream,
|
|
2557
|
+
status: res.statusCode || 502,
|
|
2558
|
+
headers: outHeaders,
|
|
2559
|
+
});
|
|
2560
|
+
res.on("data", (chunk) => {
|
|
2561
|
+
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
2562
|
+
for (let offset = 0; offset < buf.length; offset += PROXY_CHUNK_BYTES) {
|
|
2563
|
+
const end = Math.min(offset + PROXY_CHUNK_BYTES, buf.length);
|
|
2564
|
+
bridgeSend({
|
|
2565
|
+
type: "proxy.http.chunk",
|
|
2566
|
+
id,
|
|
2567
|
+
stream,
|
|
2568
|
+
data: Buffer.from(buf.subarray(offset, end)).toString("base64"),
|
|
2569
|
+
eof: false,
|
|
2570
|
+
});
|
|
2571
|
+
}
|
|
2572
|
+
});
|
|
2573
|
+
res.on("end", () => {
|
|
2574
|
+
proxyHttpReqs.delete(id);
|
|
2575
|
+
bridgeSend({
|
|
2576
|
+
type: "proxy.http.chunk",
|
|
2577
|
+
id,
|
|
2578
|
+
stream,
|
|
2579
|
+
data: "",
|
|
2580
|
+
eof: true,
|
|
2581
|
+
});
|
|
2582
|
+
});
|
|
2583
|
+
res.on("error", (err) => {
|
|
2584
|
+
failExternalProxyHttp(id, err);
|
|
2585
|
+
});
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2588
|
+
function fetchExternalProxyUrl(entry, url, method, headers, body, redirectsLeft) {
|
|
2589
|
+
const parsed = parseExternalProxyUrl(url);
|
|
2590
|
+
if (!parsed) {
|
|
2591
|
+
failExternalProxyHttp(entry.id, "Invalid external URL");
|
|
2592
|
+
return;
|
|
2593
|
+
}
|
|
2594
|
+
const lib = parsed.protocol === "https:" ? https : http;
|
|
2595
|
+
/** @type {Record<string, string>} */
|
|
2596
|
+
const reqHeaders = { ...headers, host: parsed.host };
|
|
2597
|
+
const sendBody =
|
|
2598
|
+
body?.length && method !== "GET" && method !== "HEAD" ? body : null;
|
|
2599
|
+
if (sendBody) reqHeaders["content-length"] = String(sendBody.length);
|
|
2600
|
+
else delete reqHeaders["content-length"];
|
|
2601
|
+
|
|
2602
|
+
let req;
|
|
2603
|
+
try {
|
|
2604
|
+
req = lib.request(
|
|
2605
|
+
{
|
|
2606
|
+
protocol: parsed.protocol,
|
|
2607
|
+
hostname: parsed.hostname,
|
|
2608
|
+
port: parsed.port || undefined,
|
|
2609
|
+
path: `${parsed.pathname}${parsed.search}`,
|
|
2610
|
+
method,
|
|
2611
|
+
headers: reqHeaders,
|
|
2612
|
+
},
|
|
2613
|
+
(res) => {
|
|
2614
|
+
const status = res.statusCode || 502;
|
|
2615
|
+
const loc = res.headers.location;
|
|
2616
|
+
if (
|
|
2617
|
+
loc &&
|
|
2618
|
+
status >= 300 &&
|
|
2619
|
+
status < 400 &&
|
|
2620
|
+
redirectsLeft > 0
|
|
2621
|
+
) {
|
|
2622
|
+
res.resume();
|
|
2623
|
+
let next;
|
|
2624
|
+
try {
|
|
2625
|
+
next = new URL(loc, parsed).href;
|
|
2626
|
+
} catch {
|
|
2627
|
+
failExternalProxyHttp(entry.id, "Invalid redirect");
|
|
2628
|
+
return;
|
|
2629
|
+
}
|
|
2630
|
+
const preserve = status === 307 || status === 308;
|
|
2631
|
+
const nextMethod = preserve
|
|
2632
|
+
? method
|
|
2633
|
+
: method === "HEAD"
|
|
2634
|
+
? "HEAD"
|
|
2635
|
+
: "GET";
|
|
2636
|
+
const nextBody =
|
|
2637
|
+
preserve && nextMethod !== "GET" && nextMethod !== "HEAD"
|
|
2638
|
+
? body
|
|
2639
|
+
: Buffer.alloc(0);
|
|
2640
|
+
fetchExternalProxyUrl(
|
|
2641
|
+
entry,
|
|
2642
|
+
next,
|
|
2643
|
+
nextMethod,
|
|
2644
|
+
headers,
|
|
2645
|
+
nextBody,
|
|
2646
|
+
redirectsLeft - 1
|
|
2647
|
+
);
|
|
2648
|
+
return;
|
|
2649
|
+
}
|
|
2650
|
+
streamExternalProxyHttp(entry.id, res);
|
|
2651
|
+
}
|
|
2652
|
+
);
|
|
2653
|
+
} catch (err) {
|
|
2654
|
+
failExternalProxyHttp(entry.id, err);
|
|
2655
|
+
return;
|
|
2656
|
+
}
|
|
2657
|
+
req.setTimeout(EXTERNAL_PROXY_TIMEOUT_MS, () => {
|
|
2658
|
+
req.destroy(new Error("Upstream timeout"));
|
|
2659
|
+
});
|
|
2660
|
+
req.on("error", (err) => {
|
|
2661
|
+
failExternalProxyHttp(entry.id, err);
|
|
2662
|
+
});
|
|
2663
|
+
entry.req = req;
|
|
2664
|
+
if (sendBody) req.write(sendBody);
|
|
2665
|
+
req.end();
|
|
2666
|
+
}
|
|
2667
|
+
|
|
2668
|
+
function startExternalProxyHttp(entry) {
|
|
2669
|
+
const body = Buffer.concat(entry.chunks || []);
|
|
2670
|
+
fetchExternalProxyUrl(
|
|
2671
|
+
entry,
|
|
2672
|
+
entry.url,
|
|
2673
|
+
entry.method,
|
|
2674
|
+
entry.headers,
|
|
2675
|
+
body,
|
|
2676
|
+
EXTERNAL_PROXY_MAX_REDIRECTS
|
|
2677
|
+
);
|
|
2678
|
+
}
|
|
2679
|
+
|
|
2680
|
+
function handleExternalProxyHttpFromAdmin(msg) {
|
|
2681
|
+
const id = typeof msg.id === "string" ? msg.id : "";
|
|
2682
|
+
const parsed = parseExternalProxyUrl(msg.externalUrl);
|
|
2683
|
+
if (!id) return;
|
|
2684
|
+
if (!parsed) {
|
|
2685
|
+
failExternalProxyHttp(id, "Invalid external URL");
|
|
2686
|
+
return;
|
|
2687
|
+
}
|
|
2688
|
+
const existing = proxyHttpReqs.get(id);
|
|
2689
|
+
if (existing) {
|
|
2690
|
+
destroyProxyHttpReq(existing);
|
|
2691
|
+
proxyHttpReqs.delete(id);
|
|
2692
|
+
}
|
|
2693
|
+
const method = String(msg.method || "GET").toUpperCase();
|
|
2694
|
+
const initialBody =
|
|
2695
|
+
typeof msg.body === "string" && msg.body
|
|
2696
|
+
? Buffer.from(msg.body, "base64")
|
|
2697
|
+
: null;
|
|
2698
|
+
const entry = {
|
|
2699
|
+
req: null,
|
|
2700
|
+
external: true,
|
|
2701
|
+
id,
|
|
2702
|
+
url: parsed.href,
|
|
2703
|
+
method,
|
|
2704
|
+
headers: externalProxyHeaders(msg.headers, parsed.host),
|
|
2705
|
+
chunks: [],
|
|
2706
|
+
};
|
|
2707
|
+
proxyHttpReqs.set(id, entry);
|
|
2708
|
+
if (initialBody?.length) entry.chunks.push(initialBody);
|
|
2709
|
+
if (msg.bodyEof !== false) startExternalProxyHttp(entry);
|
|
2710
|
+
}
|
|
2711
|
+
|
|
2479
2712
|
function handleProxyHttpFromAdmin(msg) {
|
|
2480
2713
|
const id = typeof msg.id === "string" ? msg.id : "";
|
|
2481
2714
|
const sandboxId = typeof msg.sandboxId === "string" ? msg.sandboxId : "";
|
|
@@ -2490,6 +2723,10 @@ function handleProxyHttpFromAdmin(msg) {
|
|
|
2490
2723
|
});
|
|
2491
2724
|
return;
|
|
2492
2725
|
}
|
|
2726
|
+
if (typeof msg.externalUrl === "string" && msg.externalUrl.trim()) {
|
|
2727
|
+
handleExternalProxyHttpFromAdmin(msg);
|
|
2728
|
+
return;
|
|
2729
|
+
}
|
|
2493
2730
|
if (isAiServerAppId(appId, ws)) {
|
|
2494
2731
|
void handleAiProxyHttpFromAdmin(msg, ws);
|
|
2495
2732
|
return;
|
|
@@ -2702,11 +2939,16 @@ function handleProxyHttpBodyFromAdmin(msg) {
|
|
|
2702
2939
|
const id = typeof msg.id === "string" ? msg.id : "";
|
|
2703
2940
|
const entry = proxyHttpReqs.get(id);
|
|
2704
2941
|
if (!entry) return;
|
|
2705
|
-
const req = entry.req || entry;
|
|
2706
2942
|
const chunk =
|
|
2707
2943
|
typeof msg.data === "string" && msg.data
|
|
2708
2944
|
? Buffer.from(msg.data, "base64")
|
|
2709
2945
|
: null;
|
|
2946
|
+
if (entry.external) {
|
|
2947
|
+
if (chunk?.length) entry.chunks.push(chunk);
|
|
2948
|
+
if (msg.eof === true) startExternalProxyHttp(entry);
|
|
2949
|
+
return;
|
|
2950
|
+
}
|
|
2951
|
+
const req = entry.req || entry;
|
|
2710
2952
|
if (entry.rewrite) {
|
|
2711
2953
|
if (chunk?.length) entry.chunks.push(chunk);
|
|
2712
2954
|
if (msg.eof === true) {
|
package/src/share-rewrite.mjs
CHANGED
|
@@ -155,11 +155,33 @@ function isImmutableAssetPath(path) {
|
|
|
155
155
|
return (
|
|
156
156
|
/\/_next\/static\//.test(p) ||
|
|
157
157
|
/\/__nextjs_font\//.test(p) ||
|
|
158
|
-
/\/node_modules\/\.vite\//.test(p) ||
|
|
159
158
|
/\.[0-9a-f]{8,}\.(?:js|css|woff2?)$/i.test(p)
|
|
160
159
|
);
|
|
161
160
|
}
|
|
162
161
|
|
|
162
|
+
function isViteDevSourcePath(path) {
|
|
163
|
+
const raw = String(path || "");
|
|
164
|
+
const p = raw.split("?")[0] || "";
|
|
165
|
+
if (/[?&]t=\d+/.test(raw)) return true;
|
|
166
|
+
if (/\/(?:@vite(?:\/|$)|@react-refresh|@fs\/|@id\/)/.test(p)) return true;
|
|
167
|
+
if (/\/node_modules\/\.vite\//.test(p)) return true;
|
|
168
|
+
if (/\/src\//.test(p)) return true;
|
|
169
|
+
if (
|
|
170
|
+
/\.(?:m?[jt]sx?|vue|svelte|css|scss|sass|less)$/i.test(p) &&
|
|
171
|
+
!/\/node_modules\//.test(p)
|
|
172
|
+
) {
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function isDocumentPath(path) {
|
|
179
|
+
const p = String(path || "").split("?")[0] || "";
|
|
180
|
+
if (!p || p === "/") return true;
|
|
181
|
+
if (/\.html?$/i.test(p)) return true;
|
|
182
|
+
return !/\.[A-Za-z0-9]+$/.test(p);
|
|
183
|
+
}
|
|
184
|
+
|
|
163
185
|
function isNoStorePath(path) {
|
|
164
186
|
const p = String(path || "").split("?")[0] || "";
|
|
165
187
|
return (
|
|
@@ -169,11 +191,9 @@ function isNoStorePath(path) {
|
|
|
169
191
|
/\/_next\/webpack-hmr/i.test(p) ||
|
|
170
192
|
/\/_next\/webpack\/hmr/i.test(p) ||
|
|
171
193
|
/\/__nextjs_original-stack-frames/i.test(p) ||
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
/\/@id\//.test(p) ||
|
|
176
|
-
/\/__mp\//.test(p)
|
|
194
|
+
/\/__mp\//.test(p) ||
|
|
195
|
+
isViteDevSourcePath(path) ||
|
|
196
|
+
isDocumentPath(path)
|
|
177
197
|
);
|
|
178
198
|
}
|
|
179
199
|
|
|
@@ -396,12 +416,12 @@ export function shareTokenRoot(publicBase) {
|
|
|
396
416
|
return prefix.endsWith("/") ? prefix : `${prefix}/`;
|
|
397
417
|
}
|
|
398
418
|
|
|
399
|
-
export function shareShimScript(pathPrefix, portUrls) {
|
|
400
|
-
return `(${shareProxyShim.toString()})(${JSON.stringify(pathPrefix || "")},${JSON.stringify(portUrls || {})},${rewriteMappedLocalUrls.toString()});`;
|
|
419
|
+
export function shareShimScript(pathPrefix, portUrls, bypassCors) {
|
|
420
|
+
return `(${shareProxyShim.toString()})(${JSON.stringify(pathPrefix || "")},${JSON.stringify(portUrls || {})},${rewriteMappedLocalUrls.toString()},${JSON.stringify(Boolean(bypassCors))});`;
|
|
401
421
|
}
|
|
402
422
|
|
|
403
|
-
export function shareServiceWorkerScript(portUrls, tokenRoot) {
|
|
404
|
-
return `(${shareServiceWorkerMain.toString()})(${JSON.stringify(portUrls || {})},${JSON.stringify(tokenRoot || "/")},${rewriteMappedLocalUrls.toString()});`;
|
|
423
|
+
export function shareServiceWorkerScript(portUrls, tokenRoot, bypassCors) {
|
|
424
|
+
return `(${shareServiceWorkerMain.toString()})(${JSON.stringify(portUrls || {})},${JSON.stringify(tokenRoot || "/")},${rewriteMappedLocalUrls.toString()},${JSON.stringify(Boolean(bypassCors))});`;
|
|
405
425
|
}
|
|
406
426
|
|
|
407
427
|
function rewriteHeaderUrls(headers, publicBase, port, portUrls) {
|
|
@@ -596,7 +616,7 @@ function gzipIfRequested(payload, headers, acceptEncoding) {
|
|
|
596
616
|
|
|
597
617
|
function rewriteCacheKey(publicBase, path) {
|
|
598
618
|
if (!isImmutableAssetPath(path) && !isLongCacheScriptPath(path)) return null;
|
|
599
|
-
return `${publicBase || ""}\0${String(path || "")
|
|
619
|
+
return `${publicBase || ""}\0${String(path || "")}`;
|
|
600
620
|
}
|
|
601
621
|
|
|
602
622
|
function rememberRewrite(key, payload, status, headers, etag) {
|
|
@@ -1003,10 +1023,11 @@ function injectMaintainerProEmbed(html, aiPublicBase) {
|
|
|
1003
1023
|
/**
|
|
1004
1024
|
* Intercept every browser request and map listed app ports onto share URLs.
|
|
1005
1025
|
*/
|
|
1006
|
-
function shareProxyShim(p, portMap, rewriteMappedLocalUrls) {
|
|
1026
|
+
function shareProxyShim(p, portMap, rewriteMappedLocalUrls, bypassCors) {
|
|
1007
1027
|
if (!p || window.__MP_SHARE_SHIM__) return;
|
|
1008
1028
|
window.__MP_SHARE_SHIM__ = 1;
|
|
1009
1029
|
window.__MP_PORT_MAP__ = portMap || {};
|
|
1030
|
+
window.__MP_BYPASS_CORS__ = Boolean(bypassCors);
|
|
1010
1031
|
function rewriteText(text) {
|
|
1011
1032
|
if (typeof text !== "string" || !text || typeof rewriteMappedLocalUrls !== "function") {
|
|
1012
1033
|
return text;
|
|
@@ -1108,6 +1129,38 @@ function shareProxyShim(p, portMap, rewriteMappedLocalUrls) {
|
|
|
1108
1129
|
} catch (e) {}
|
|
1109
1130
|
return v;
|
|
1110
1131
|
}
|
|
1132
|
+
function isCorsProxyPath(pathname) {
|
|
1133
|
+
var parts = String(pathname || "").split("/").filter(Boolean);
|
|
1134
|
+
return parts[0] === "p" && parts[2] === "__cors";
|
|
1135
|
+
}
|
|
1136
|
+
function shareToken() {
|
|
1137
|
+
try {
|
|
1138
|
+
var parts = location.pathname.split("/").filter(Boolean);
|
|
1139
|
+
if (parts[0] === "p" && parts[1]) return parts[1];
|
|
1140
|
+
} catch (e) {}
|
|
1141
|
+
return "";
|
|
1142
|
+
}
|
|
1143
|
+
function corsProxy(v) {
|
|
1144
|
+
if (!bypassCors || typeof v !== "string" || !v) return v;
|
|
1145
|
+
if (!/^(https?:)\/\//i.test(v)) return v;
|
|
1146
|
+
try {
|
|
1147
|
+
var u = new URL(v);
|
|
1148
|
+
if (u.protocol !== "http:" && u.protocol !== "https:") return v;
|
|
1149
|
+
if (loopback(u.hostname)) return v;
|
|
1150
|
+
if (u.origin === location.origin) return v;
|
|
1151
|
+
if (isCorsProxyPath(u.pathname)) return v;
|
|
1152
|
+
var token = shareToken();
|
|
1153
|
+
if (!token) return v;
|
|
1154
|
+
return (
|
|
1155
|
+
location.origin +
|
|
1156
|
+
"/p/" +
|
|
1157
|
+
token +
|
|
1158
|
+
"/__cors?__mp_url=" +
|
|
1159
|
+
encodeURIComponent(u.href)
|
|
1160
|
+
);
|
|
1161
|
+
} catch (e) {}
|
|
1162
|
+
return v;
|
|
1163
|
+
}
|
|
1111
1164
|
function addNet(v) {
|
|
1112
1165
|
if (typeof v !== "string" || !v) return v;
|
|
1113
1166
|
var mapped = mapLocal(v);
|
|
@@ -1115,7 +1168,10 @@ function shareProxyShim(p, portMap, rewriteMappedLocalUrls) {
|
|
|
1115
1168
|
if (/^(https?:|wss?:)\/\//i.test(v)) {
|
|
1116
1169
|
try {
|
|
1117
1170
|
var abs = new URL(v);
|
|
1118
|
-
if (!loopback(abs.hostname))
|
|
1171
|
+
if (!loopback(abs.hostname)) {
|
|
1172
|
+
if (/^wss?:/i.test(abs.protocol)) return v;
|
|
1173
|
+
return corsProxy(v);
|
|
1174
|
+
}
|
|
1119
1175
|
} catch (e) {}
|
|
1120
1176
|
}
|
|
1121
1177
|
if (v.charAt(0) === "/" && v.charAt(1) !== "/") {
|
|
@@ -1299,17 +1355,27 @@ function shareProxyShim(p, portMap, rewriteMappedLocalUrls) {
|
|
|
1299
1355
|
try {
|
|
1300
1356
|
var tokenRoot = p.replace(/\/[^/]+$/, "/");
|
|
1301
1357
|
if (navigator.serviceWorker && tokenRoot.indexOf("/p/") === 0) {
|
|
1302
|
-
navigator.serviceWorker.register(p + "/__mp/sw.js", {
|
|
1358
|
+
navigator.serviceWorker.register(p + "/__mp/sw.js", {
|
|
1359
|
+
scope: tokenRoot,
|
|
1360
|
+
updateViaCache: "none",
|
|
1361
|
+
});
|
|
1303
1362
|
}
|
|
1304
1363
|
} catch (e) {}
|
|
1305
1364
|
}
|
|
1306
1365
|
|
|
1307
|
-
function shareServiceWorkerMain(portMap, tokenRoot, rewriteMappedLocalUrls) {
|
|
1366
|
+
function shareServiceWorkerMain(portMap, tokenRoot, rewriteMappedLocalUrls, bypassCors) {
|
|
1308
1367
|
self.addEventListener("install", function (event) {
|
|
1309
1368
|
event.waitUntil(self.skipWaiting());
|
|
1310
1369
|
});
|
|
1311
1370
|
self.addEventListener("activate", function (event) {
|
|
1312
|
-
event.waitUntil(
|
|
1371
|
+
event.waitUntil(
|
|
1372
|
+
self.clients.claim().then(function () {
|
|
1373
|
+
if (!self.caches) return;
|
|
1374
|
+
return self.caches.keys().then(function (keys) {
|
|
1375
|
+
return Promise.all(keys.map(function (key) { return self.caches.delete(key); }));
|
|
1376
|
+
});
|
|
1377
|
+
})
|
|
1378
|
+
);
|
|
1313
1379
|
});
|
|
1314
1380
|
function rewriteText(text) {
|
|
1315
1381
|
if (typeof text !== "string" || !text) return text;
|
|
@@ -1352,12 +1418,49 @@ function shareServiceWorkerMain(portMap, tokenRoot, rewriteMappedLocalUrls) {
|
|
|
1352
1418
|
}
|
|
1353
1419
|
return "";
|
|
1354
1420
|
}
|
|
1421
|
+
function isCorsProxyPath(pathname) {
|
|
1422
|
+
var parts = String(pathname || "").split("/").filter(Boolean);
|
|
1423
|
+
return parts[0] === "p" && parts[2] === "__cors";
|
|
1424
|
+
}
|
|
1425
|
+
function shareToken() {
|
|
1426
|
+
try {
|
|
1427
|
+
var parts = String(self.registration && self.registration.scope || self.location.pathname)
|
|
1428
|
+
.split("/")
|
|
1429
|
+
.filter(Boolean);
|
|
1430
|
+
if (parts[0] === "p" && parts[1]) return parts[1];
|
|
1431
|
+
} catch (e) {}
|
|
1432
|
+
return "";
|
|
1433
|
+
}
|
|
1434
|
+
function corsProxy(v) {
|
|
1435
|
+
if (!bypassCors || typeof v !== "string" || !v) return v;
|
|
1436
|
+
if (!/^(https?:)\/\//i.test(v)) return v;
|
|
1437
|
+
try {
|
|
1438
|
+
var u = new URL(v, self.location.href);
|
|
1439
|
+
if (u.protocol !== "http:" && u.protocol !== "https:") return v;
|
|
1440
|
+
if (loopback(u.hostname)) return v;
|
|
1441
|
+
if (u.origin === self.location.origin) return v;
|
|
1442
|
+
if (isCorsProxyPath(u.pathname)) return v;
|
|
1443
|
+
var token = shareToken();
|
|
1444
|
+
if (!token) return v;
|
|
1445
|
+
return (
|
|
1446
|
+
self.location.origin +
|
|
1447
|
+
"/p/" +
|
|
1448
|
+
token +
|
|
1449
|
+
"/__cors?__mp_url=" +
|
|
1450
|
+
encodeURIComponent(u.href)
|
|
1451
|
+
);
|
|
1452
|
+
} catch (e) {}
|
|
1453
|
+
return v;
|
|
1454
|
+
}
|
|
1355
1455
|
function prefixWith(url, prefix) {
|
|
1356
|
-
if (!prefix) return url;
|
|
1456
|
+
if (!prefix) return corsProxy(url);
|
|
1357
1457
|
try {
|
|
1358
1458
|
if (/^(https?:|wss?:)\/\//i.test(url)) {
|
|
1359
1459
|
var abs = new URL(url);
|
|
1360
|
-
if (!loopback(abs.hostname))
|
|
1460
|
+
if (!loopback(abs.hostname)) {
|
|
1461
|
+
if (/^wss?:/i.test(abs.protocol)) return url;
|
|
1462
|
+
return corsProxy(url);
|
|
1463
|
+
}
|
|
1361
1464
|
}
|
|
1362
1465
|
var u = new URL(url, self.location.href);
|
|
1363
1466
|
var path = u.pathname || "/";
|
|
@@ -1382,11 +1485,13 @@ function shareServiceWorkerMain(portMap, tokenRoot, rewriteMappedLocalUrls) {
|
|
|
1382
1485
|
function mapUrl(v, prefix) {
|
|
1383
1486
|
if (typeof v !== "string" || !v) return v;
|
|
1384
1487
|
if (v.indexOf("/__mp/") !== -1) return v;
|
|
1488
|
+
if (v.indexOf("/__cors") !== -1) return v;
|
|
1385
1489
|
return prefixWith(rewriteText(v), prefix);
|
|
1386
1490
|
}
|
|
1387
1491
|
self.addEventListener("fetch", function (event) {
|
|
1388
1492
|
var req = event.request;
|
|
1389
1493
|
if (req.url.indexOf("/__mp/") !== -1) return;
|
|
1494
|
+
if (req.url.indexOf("/__cors") !== -1) return;
|
|
1390
1495
|
event.respondWith(
|
|
1391
1496
|
(async function () {
|
|
1392
1497
|
var client = null;
|
|
@@ -1417,6 +1522,7 @@ function shareServiceWorkerMain(portMap, tokenRoot, rewriteMappedLocalUrls) {
|
|
|
1417
1522
|
credentials: req.credentials,
|
|
1418
1523
|
redirect: req.redirect,
|
|
1419
1524
|
referrer: req.referrer,
|
|
1525
|
+
cache: "no-store",
|
|
1420
1526
|
};
|
|
1421
1527
|
if (req.mode && req.mode !== "navigate") init.mode = req.mode;
|
|
1422
1528
|
if (body !== undefined) init.body = body;
|