mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-22 20:00:47 +00:00
- Enhance passthrough function to support response inspection
- Add cursor tool configuration and update related components
This commit is contained in:
@@ -5,12 +5,14 @@ const TARGET_HOSTS = [
|
||||
"cloudcode-pa.googleapis.com",
|
||||
"api.individual.githubcopilot.com",
|
||||
"q.us-east-1.amazonaws.com",
|
||||
"api2.cursor.sh",
|
||||
];
|
||||
|
||||
const URL_PATTERNS = {
|
||||
antigravity: [":generateContent", ":streamGenerateContent"],
|
||||
copilot: ["/chat/completions", "/v1/messages", "/responses"],
|
||||
kiro: ["/generateAssistantResponse"],
|
||||
cursor: ["/BidiAppend", "/RunSSE", "/RunPoll", "/Run"],
|
||||
};
|
||||
|
||||
function getToolForHost(host) {
|
||||
@@ -18,6 +20,7 @@ function getToolForHost(host) {
|
||||
if (h === "api.individual.githubcopilot.com") return "copilot";
|
||||
if (h === "daily-cloudcode-pa.googleapis.com" || h === "cloudcode-pa.googleapis.com") return "antigravity";
|
||||
if (h === "q.us-east-1.amazonaws.com") return "kiro";
|
||||
if (h === "api2.cursor.sh") return "cursor";
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
Submodule src/mitm/dev updated: 39f5376ac1...ebfb215130
@@ -9,6 +9,7 @@ const TOOL_HOSTS = {
|
||||
antigravity: ["daily-cloudcode-pa.googleapis.com", "cloudcode-pa.googleapis.com"],
|
||||
copilot: ["api.individual.githubcopilot.com"],
|
||||
kiro: ["q.us-east-1.amazonaws.com", "codewhisperer.us-east-1.amazonaws.com"],
|
||||
cursor: ["api2.cursor.sh"],
|
||||
};
|
||||
|
||||
const IS_WIN = process.platform === "win32";
|
||||
|
||||
@@ -464,6 +464,11 @@ async function startServer(apiKey, sudoPassword) {
|
||||
err(msg);
|
||||
startError = msg;
|
||||
}
|
||||
// Detect wrong/missing password — clear cache and stop retry loop
|
||||
if (!IS_WIN && (msg.includes("incorrect password") || msg.includes("no password was provided"))) {
|
||||
setCachedPassword(null);
|
||||
mitmIsRestarting = true; // prevent scheduleMitmRestart from firing
|
||||
}
|
||||
});
|
||||
serverProcess.on("exit", (code) => {
|
||||
log(`Server exited (code: ${code})`);
|
||||
|
||||
+27
-2
@@ -26,6 +26,7 @@ const handlers = {
|
||||
antigravity: loadHandler("antigravity"),
|
||||
copilot: loadHandler("copilot"),
|
||||
kiro: loadHandler("kiro"),
|
||||
cursor: loadHandler("cursor"),
|
||||
};
|
||||
|
||||
// ── SSL / SNI ─────────────────────────────────────────────────
|
||||
@@ -118,7 +119,12 @@ function saveRequestLog(url, bodyBuffer) {
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
async function passthrough(req, res, bodyBuffer) {
|
||||
/**
|
||||
* Forward request to real upstream.
|
||||
* Optional onResponse(rawBuffer) callback — if provided, tees the response
|
||||
* so it's both forwarded to client AND passed to the callback for inspection.
|
||||
*/
|
||||
async function passthrough(req, res, bodyBuffer, onResponse) {
|
||||
const targetHost = (req.headers.host || TARGET_HOSTS[0]).split(":")[0];
|
||||
const targetIP = await resolveTargetIP(targetHost);
|
||||
|
||||
@@ -132,7 +138,19 @@ async function passthrough(req, res, bodyBuffer) {
|
||||
rejectUnauthorized: false
|
||||
}, (forwardRes) => {
|
||||
res.writeHead(forwardRes.statusCode, forwardRes.headers);
|
||||
forwardRes.pipe(res);
|
||||
|
||||
if (!onResponse) {
|
||||
forwardRes.pipe(res);
|
||||
return;
|
||||
}
|
||||
|
||||
// Tee: forward to client AND buffer for callback
|
||||
const chunks = [];
|
||||
forwardRes.on("data", chunk => { chunks.push(chunk); res.write(chunk); });
|
||||
forwardRes.on("end", () => {
|
||||
res.end();
|
||||
try { onResponse(Buffer.concat(chunks), forwardRes.headers); } catch { /* ignore */ }
|
||||
});
|
||||
});
|
||||
|
||||
forwardReq.on("error", (e) => {
|
||||
@@ -172,6 +190,13 @@ const server = https.createServer(sslOptions, async (req, res) => {
|
||||
|
||||
log(`🔍 [${tool}] url=${req.url} | bodyLen=${bodyBuffer.length}`);
|
||||
|
||||
// Cursor uses binary proto — model extraction not possible at this layer.
|
||||
// Delegate directly to handler which decodes proto internally.
|
||||
if (tool === "cursor") {
|
||||
log(`⚡ intercept | cursor | proto`);
|
||||
return handlers[tool].intercept(req, res, bodyBuffer, null, passthrough);
|
||||
}
|
||||
|
||||
const model = extractModel(req.url, bodyBuffer);
|
||||
log(`🔍 [${tool}] model="${model}"`);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user