Proxy server to inject shim (#178)
things to test: - [x] allow real URL to open in new window - [x] packaging in electron? - [ ] does it work on windows? - [x] make sure it works with older apps - [x] what about cache / reuse? - maybe use a bigger range of ports??
This commit is contained in:
48
src/ipc/utils/port_utils.ts
Normal file
48
src/ipc/utils/port_utils.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import net from "net";
|
||||
|
||||
export function findAvailablePort(
|
||||
minPort: number,
|
||||
maxPort: number,
|
||||
): Promise<number> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let attempts = 0;
|
||||
const maxAttempts = 3;
|
||||
|
||||
function tryPort() {
|
||||
if (attempts >= maxAttempts) {
|
||||
reject(
|
||||
new Error(
|
||||
`Failed to find an available port after ${maxAttempts} attempts.`,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
attempts++;
|
||||
const port =
|
||||
Math.floor(Math.random() * (maxPort - minPort + 1)) + minPort;
|
||||
const server = net.createServer();
|
||||
|
||||
server.once("error", (err: any) => {
|
||||
if (err.code === "EADDRINUSE") {
|
||||
// Port is in use, try another one
|
||||
console.log(`Port ${port} is in use, trying another...`);
|
||||
server.close(() => tryPort());
|
||||
} else {
|
||||
// Other error
|
||||
server.close(() => reject(err));
|
||||
}
|
||||
});
|
||||
|
||||
server.once("listening", () => {
|
||||
server.close(() => {
|
||||
resolve(port);
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(port, "localhost");
|
||||
}
|
||||
|
||||
tryPort();
|
||||
});
|
||||
}
|
||||
55
src/ipc/utils/start_proxy_server.ts
Normal file
55
src/ipc/utils/start_proxy_server.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
// startProxy.js – helper to launch proxy.js as a worker
|
||||
|
||||
import { Worker } from "worker_threads";
|
||||
import path from "path";
|
||||
import { findAvailablePort } from "./port_utils";
|
||||
import log from "electron-log";
|
||||
|
||||
const logger = log.scope("start_proxy_server");
|
||||
|
||||
export async function startProxy(
|
||||
targetOrigin: string,
|
||||
opts: {
|
||||
// host?: string;
|
||||
// port?: number;
|
||||
// env?: Record<string, string>;
|
||||
onStarted?: (proxyUrl: string) => void;
|
||||
} = {},
|
||||
) {
|
||||
if (!/^https?:\/\//.test(targetOrigin))
|
||||
throw new Error("startProxy: targetOrigin must be absolute http/https URL");
|
||||
const port = await findAvailablePort(50_000, 60_000);
|
||||
logger.info("Found available port", port);
|
||||
const {
|
||||
// host = "localhost",
|
||||
// env = {}, // additional env vars to pass to the worker
|
||||
onStarted,
|
||||
} = opts;
|
||||
|
||||
const worker = new Worker(
|
||||
path.resolve(__dirname, "..", "..", "worker", "proxy_server.js"),
|
||||
{
|
||||
env: {
|
||||
...process.env, // inherit parent env
|
||||
|
||||
TARGET_URL: targetOrigin,
|
||||
},
|
||||
workerData: {
|
||||
targetOrigin,
|
||||
port,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
worker.on("message", (m) => {
|
||||
logger.info("[proxy]", m);
|
||||
if (typeof m === "string" && m.startsWith("proxy-server-start url=")) {
|
||||
const url = m.substring("proxy-server-start url=".length);
|
||||
onStarted?.(url);
|
||||
}
|
||||
});
|
||||
worker.on("error", (e) => logger.error("[proxy] error:", e));
|
||||
worker.on("exit", (c) => logger.info("[proxy] exit", c));
|
||||
|
||||
return worker; // let the caller keep a handle if desired
|
||||
}
|
||||
Reference in New Issue
Block a user