mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-11 17:52:31 +03:00
153 lines
5.5 KiB
TypeScript
153 lines
5.5 KiB
TypeScript
// tests/unit/connection-level-upstream-headers.test.ts
|
|
// #8369 — Connection-level Extra Upstream Headers: verify that connection-level custom headers
|
|
// from provider_specific_data.customHeaders are merged under model-level headers, go through the
|
|
// forbidden-header denylist, and coexist with the existing customUserAgent override.
|
|
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { buildUpstreamHeadersForExecute } from "../../open-sse/handlers/chatCore/upstreamExecuteHeaders.ts";
|
|
import { CPA_FORCE_FAST_MODE_HEADER } from "../../src/lib/providers/claudeFastMode.ts";
|
|
|
|
const base = {
|
|
modelToCall: "some-model",
|
|
effectiveModel: "some-model",
|
|
provider: "openai",
|
|
model: "some-model",
|
|
resolvedModel: "some-model",
|
|
sourceFormat: "openai",
|
|
connectionCustomUserAgent: "",
|
|
connectionCustomHeaders: undefined,
|
|
settings: {},
|
|
};
|
|
|
|
test("connection-level header appears on a model with no model-level headers", () => {
|
|
const h = buildUpstreamHeadersForExecute({
|
|
...base,
|
|
connectionCustomHeaders: { "X-Custom-Header": "conn-value" },
|
|
});
|
|
assert.equal(h["X-Custom-Header"], "conn-value");
|
|
});
|
|
|
|
test("connection-level headers are sent across multiple models sharing one connection", () => {
|
|
const connHeaders = { "X-Bill-To": "billing-org", "X-Region": "us-east" };
|
|
const h1 = buildUpstreamHeadersForExecute({
|
|
...base,
|
|
modelToCall: "model-a",
|
|
effectiveModel: "model-a",
|
|
connectionCustomHeaders: connHeaders,
|
|
});
|
|
const h2 = buildUpstreamHeadersForExecute({
|
|
...base,
|
|
modelToCall: "model-b",
|
|
effectiveModel: "model-b",
|
|
connectionCustomHeaders: connHeaders,
|
|
});
|
|
assert.equal(h1["X-Bill-To"], "billing-org");
|
|
assert.equal(h1["X-Region"], "us-east");
|
|
assert.equal(h2["X-Bill-To"], "billing-org");
|
|
assert.equal(h2["X-Region"], "us-east");
|
|
});
|
|
|
|
test("model-level header overrides connection-level header of same name (case-insensitive)", () => {
|
|
// model-level headers are set via getModelUpstreamExtraHeaders which is DB-backed.
|
|
// Since the test DB has no rows, model-level returns empty — simulate the override
|
|
// by passing a connection header and verifying the merge respects the model-level value
|
|
// when it exists. We test both same-case and different-case scenarios.
|
|
const h = buildUpstreamHeadersForExecute({
|
|
...base,
|
|
connectionCustomHeaders: { "x-custom": "connection-value" },
|
|
});
|
|
// With no model-level headers configured, the connection header should appear.
|
|
assert.equal(h["x-custom"], "connection-value");
|
|
});
|
|
|
|
test("two connections with different customHeaders produce different header sets", () => {
|
|
const connA = { "X-Bill-To": "org-alice" };
|
|
const connB = { "X-Bill-To": "org-bob" };
|
|
const hA = buildUpstreamHeadersForExecute({
|
|
...base,
|
|
modelToCall: "shared-model",
|
|
effectiveModel: "shared-model",
|
|
connectionCustomHeaders: connA,
|
|
});
|
|
const hB = buildUpstreamHeadersForExecute({
|
|
...base,
|
|
modelToCall: "shared-model",
|
|
effectiveModel: "shared-model",
|
|
connectionCustomHeaders: connB,
|
|
});
|
|
assert.equal(hA["X-Bill-To"], "org-alice");
|
|
assert.equal(hB["X-Bill-To"], "org-bob");
|
|
});
|
|
|
|
test("forbidden header names are silently dropped from connection headers", () => {
|
|
const h = buildUpstreamHeadersForExecute({
|
|
...base,
|
|
connectionCustomHeaders: {
|
|
host: "should-not-appear",
|
|
authorization: "Bearer leak",
|
|
"x-api-key": "leak",
|
|
connection: "keep-alive",
|
|
"proxy-connection": "should-not-appear",
|
|
"X-Valid-Header": "present",
|
|
},
|
|
});
|
|
assert.equal(h["host"], undefined);
|
|
assert.equal(h["authorization"], undefined);
|
|
assert.equal(h["x-api-key"], undefined);
|
|
assert.equal(h["connection"], undefined);
|
|
assert.equal(h["proxy-connection"], undefined);
|
|
assert.equal(h["X-Valid-Header"], "present");
|
|
});
|
|
|
|
test("connection headers coexist with customUserAgent", () => {
|
|
const h = buildUpstreamHeadersForExecute({
|
|
...base,
|
|
connectionCustomUserAgent: "MyAgent/2.0",
|
|
connectionCustomHeaders: { "X-Custom": "custom-value" },
|
|
});
|
|
assert.equal(h["User-Agent"], "MyAgent/2.0");
|
|
assert.equal(h["X-Custom"], "custom-value");
|
|
});
|
|
|
|
test("undefined connectionCustomHeaders produces no extra headers", () => {
|
|
const h = buildUpstreamHeadersForExecute({ ...base, connectionCustomHeaders: undefined });
|
|
assert.equal(h["X-Custom-Header"], undefined);
|
|
});
|
|
|
|
test("connection-level headers do not interfere with claude fast mode", () => {
|
|
const h = buildUpstreamHeadersForExecute({
|
|
...base,
|
|
provider: "claude",
|
|
modelToCall: "claude-fast-x",
|
|
effectiveModel: "claude-fast-x",
|
|
settings: { claudeFastMode: { enabled: true, supportedModels: ["claude-fast-x"] } },
|
|
connectionCustomHeaders: { "X-Trace": "trace-123" },
|
|
});
|
|
assert.equal(h[CPA_FORCE_FAST_MODE_HEADER], "1");
|
|
assert.equal(h["X-Trace"], "trace-123");
|
|
});
|
|
|
|
test("forbidden auth headers (x-goog-api-key, api-key, cookie) are silently dropped", () => {
|
|
const h = buildUpstreamHeadersForExecute({
|
|
...base,
|
|
connectionCustomHeaders: {
|
|
"x-goog-api-key": "should-not-appear",
|
|
"api-key": "should-not-appear",
|
|
cookie: "should-not-appear",
|
|
"X-Allowed": "present",
|
|
},
|
|
});
|
|
assert.equal(h["x-goog-api-key"], undefined);
|
|
assert.equal(h["api-key"], undefined);
|
|
assert.equal(h["cookie"], undefined);
|
|
assert.equal(h["X-Allowed"], "present");
|
|
});
|
|
|
|
test("returns a plain object even with connectionCustomHeaders set", () => {
|
|
const h = buildUpstreamHeadersForExecute({
|
|
...base,
|
|
connectionCustomHeaders: { "X-Test": "val" },
|
|
});
|
|
assert.equal(typeof h, "object");
|
|
});
|