File size: 2,122 Bytes
88c4c60 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | /**
* 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;
}
|