70 lines
2.1 KiB
JavaScript
70 lines
2.1 KiB
JavaScript
/**
|
|
* Singleton cache for real Claude Code client headers.
|
|
* Captures headers from authentic Claude Code requests and makes them available
|
|
* for forwarding to api.anthropic.com, replacing static hardcoded values.
|
|
*/
|
|
|
|
const CLAUDE_IDENTITY_HEADERS = [
|
|
"user-agent",
|
|
"anthropic-beta",
|
|
"anthropic-version",
|
|
"anthropic-dangerous-direct-browser-access",
|
|
"x-app",
|
|
"x-stainless-helper-method",
|
|
"x-stainless-retry-count",
|
|
"x-stainless-runtime-version",
|
|
"x-stainless-package-version",
|
|
"x-stainless-runtime",
|
|
"x-stainless-lang",
|
|
"x-stainless-arch",
|
|
"x-stainless-os",
|
|
"x-stainless-timeout",
|
|
"x-claude-code-session-id",
|
|
"package-version",
|
|
"runtime-version",
|
|
"os",
|
|
"arch",
|
|
];
|
|
|
|
let cachedHeaders = null;
|
|
|
|
/**
|
|
* Detect if request headers look like a real Claude Code client.
|
|
* @param {object} headers - Lowercase header key/value object
|
|
*/
|
|
function isClaudeCodeClient(headers) {
|
|
const ua = (headers["user-agent"] || "").toLowerCase();
|
|
const xApp = (headers["x-app"] || "").toLowerCase();
|
|
return ua.includes("claude-cli") || ua.includes("claude-code") || xApp === "cli";
|
|
}
|
|
|
|
/**
|
|
* Store Claude Code identity headers if this looks like a real client request.
|
|
* Called at the entry point before any translation/forwarding.
|
|
* @param {object} headers - Lowercase header key/value object (from request.headers.entries())
|
|
*/
|
|
export function cacheClaudeHeaders(headers) {
|
|
if (!headers || typeof headers !== "object") return;
|
|
if (!isClaudeCodeClient(headers)) return;
|
|
|
|
const captured = {};
|
|
for (const key of CLAUDE_IDENTITY_HEADERS) {
|
|
if (headers[key] !== undefined && headers[key] !== null) {
|
|
captured[key] = headers[key];
|
|
}
|
|
}
|
|
|
|
if (Object.keys(captured).length > 0) {
|
|
cachedHeaders = captured;
|
|
console.log(`[ClaudeHeaders] Cached ${Object.keys(captured).length} identity headers from Claude Code client`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the most recently cached Claude Code identity headers.
|
|
* Returns null if no authentic client request has been seen yet (cold start).
|
|
* @returns {object|null}
|
|
*/
|
|
export function getCachedClaudeHeaders() {
|
|
return cachedHeaders;
|
|
}
|