mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 04:12:10 +03:00
feat(sidecar): support conditional provider manifest refresh (#7130)
* feat(sidecar): support conditional provider manifest refresh * fix(sidecar): accept weak manifest validators * perf(sidecar): cache provider manifest payload * docs(sidecar): describe manifest conditional refresh * test(sidecar): restore CORS preflight and manifest-content coverage The ETag/conditional-refresh rewrite of this test file dropped two pieces of coverage without replacing them: the CORS OPTIONS-preflight test, and the 200-response test's providers.length>100 / clientSecret-not-leaked assertions. This is the only test file for the provider-plugin-manifest route, so none of that was covered anywhere else afterward. Restore both: fold the providers.length/openai-presence/clientSecret assertions back into the "stable ETag" 200-response test alongside the new ETag checks, and add back a dedicated OPTIONS test asserting the CORS preflight headers. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
This commit is contained in:
@@ -21,6 +21,14 @@ OmniRoute advertises that URL to Bifrost and CLIProxyAPI via the
|
||||
`OMNIROUTE_PROVIDER_MANIFEST_URL` when the sidecar needs a public or container
|
||||
network URL instead of the local request origin.
|
||||
|
||||
## Refreshing the Manifest
|
||||
|
||||
The HTTP endpoint returns `Cache-Control: public, max-age=60` and a strong
|
||||
`ETag`. A sidecar should retain the last validated manifest and send its ETag
|
||||
in `If-None-Match` when refreshing. A `304 Not Modified` response has no body;
|
||||
the sidecar keeps its cached manifest. If no validated cached manifest exists,
|
||||
the sidecar must issue an unconditional request instead of accepting a `304`.
|
||||
|
||||
## Goal
|
||||
|
||||
Move provider metadata toward a plugin contract so the hot request path can
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import { createHash } from "node:crypto";
|
||||
|
||||
import { CORS_HEADERS } from "@/shared/utils/cors";
|
||||
import { generateProviderPluginManifest } from "@omniroute/open-sse/config/providerPluginManifestRegistry.ts";
|
||||
|
||||
const JSON_HEADERS = {
|
||||
const CACHE_HEADERS = {
|
||||
...CORS_HEADERS,
|
||||
"Content-Type": "application/json",
|
||||
"Cache-Control": "public, max-age=60",
|
||||
} as const;
|
||||
|
||||
// The provider registry is module-static; process reloads rebuild this snapshot.
|
||||
let cachedPayload: { body: string; etag: string } | null = null;
|
||||
|
||||
export async function OPTIONS() {
|
||||
return new Response(null, {
|
||||
headers: {
|
||||
@@ -17,8 +21,36 @@ export async function OPTIONS() {
|
||||
});
|
||||
}
|
||||
|
||||
export async function GET() {
|
||||
return new Response(JSON.stringify(generateProviderPluginManifest()), {
|
||||
headers: JSON_HEADERS,
|
||||
function createEtag(body: string): string {
|
||||
return `"${createHash("sha256").update(body).digest("base64url")}"`;
|
||||
}
|
||||
|
||||
function matchesEtag(ifNoneMatch: string | null, etag: string): boolean {
|
||||
return Boolean(
|
||||
ifNoneMatch
|
||||
?.split(",")
|
||||
.map((value) => value.trim())
|
||||
.some((value) => value === "*" || value === etag || value === `W/${etag}`)
|
||||
);
|
||||
}
|
||||
|
||||
function getManifestPayload(): { body: string; etag: string } {
|
||||
if (cachedPayload) return cachedPayload;
|
||||
|
||||
const body = JSON.stringify(generateProviderPluginManifest());
|
||||
cachedPayload = { body, etag: createEtag(body) };
|
||||
return cachedPayload;
|
||||
}
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const { body, etag } = getManifestPayload();
|
||||
const headers = { ...CACHE_HEADERS, ETag: etag };
|
||||
|
||||
if (matchesEtag(request.headers.get("If-None-Match"), etag)) {
|
||||
return new Response(null, { status: 304, headers });
|
||||
}
|
||||
|
||||
return new Response(body, {
|
||||
headers: { ...headers, "Content-Type": "application/json" },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,11 +6,13 @@ import {
|
||||
OPTIONS,
|
||||
} from "../../../../src/app/api/v1/provider-plugin-manifest/route.ts";
|
||||
|
||||
test("provider plugin manifest route returns JSON-safe manifest", async () => {
|
||||
const response = await GET();
|
||||
test("provider plugin manifest returns a stable ETag with its cache policy", async () => {
|
||||
const response = await GET(new Request("http://localhost/api/v1/provider-plugin-manifest"));
|
||||
const body = await response.json();
|
||||
|
||||
assert.equal(response.status, 200);
|
||||
assert.equal(response.headers.get("Cache-Control"), "public, max-age=60");
|
||||
assert.match(response.headers.get("ETag") ?? "", /^"[A-Za-z0-9_-]+"$/);
|
||||
assert.equal(response.headers.get("Content-Type"), "application/json");
|
||||
assert.equal(body.schemaVersion, 1);
|
||||
assert.equal(body.generatedFrom, "open-sse/config/providers");
|
||||
@@ -28,3 +30,31 @@ test("provider plugin manifest route handles CORS preflight", async () => {
|
||||
assert.equal(response.headers.get("Access-Control-Allow-Methods"), "GET, OPTIONS");
|
||||
assert.equal(response.headers.get("Access-Control-Allow-Headers"), "*");
|
||||
});
|
||||
|
||||
test("provider plugin manifest supports conditional sidecar refreshes", async () => {
|
||||
const initial = await GET(new Request("http://localhost/api/v1/provider-plugin-manifest"));
|
||||
const etag = initial.headers.get("ETag");
|
||||
|
||||
const response = await GET(
|
||||
new Request("http://localhost/api/v1/provider-plugin-manifest", {
|
||||
headers: { "If-None-Match": etag ?? "" },
|
||||
})
|
||||
);
|
||||
|
||||
assert.equal(response.status, 304);
|
||||
assert.equal(response.headers.get("ETag"), etag);
|
||||
assert.equal(await response.text(), "");
|
||||
});
|
||||
|
||||
test("provider plugin manifest accepts weak conditional validators", async () => {
|
||||
const initial = await GET(new Request("http://localhost/api/v1/provider-plugin-manifest"));
|
||||
const etag = initial.headers.get("ETag");
|
||||
|
||||
const response = await GET(
|
||||
new Request("http://localhost/api/v1/provider-plugin-manifest", {
|
||||
headers: { "If-None-Match": `W/${etag}` },
|
||||
})
|
||||
);
|
||||
|
||||
assert.equal(response.status, 304);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user