fix(flathub): scope rewritten descriptor cache by origin

This commit is contained in:
xixu-me committed 2026-03-16 01:14:33 +08:00
1 parent a0312c1ad9
commit c76dcca460
2 files changed
+46 -5

No files matched your search

+10 -5
View File
@@ -175,6 +175,11 @@ async function handleRequest(request, env, ctx) {
// Check if this is a Hugging Face API request
const isHF = isHuggingFaceAPIRequest(request, url);
const shouldVaryCacheByOrigin =
platform === 'flathub' && isFlatpakReferenceFilePath(effectivePath);
const cacheTargetUrl = shouldVaryCacheByOrigin
? `${targetUrl}${targetUrl.includes('?') ? '&' : '?'}__xget_origin=${encodeURIComponent(url.origin)}`
: targetUrl;
const canUseCache = request.method === 'GET' || request.method === 'HEAD';
const shouldPassthroughRequest =
isGit || isGitLFS || isDocker || isAI || isHF || !canUseCache;
@@ -199,7 +204,7 @@ async function handleRequest(request, env, ctx) {
) {
try {
// For Range requests, try cache match first
const cacheKey = new Request(targetUrl, {
const cacheKey = new Request(cacheTargetUrl, {
method: 'GET',
headers: request.headers
});
@@ -211,7 +216,7 @@ async function handleRequest(request, env, ctx) {
// If Range request missed cache, try with original request to see if we have full content cached
const rangeHeader = request.headers.get('Range');
if (rangeHeader) {
const fullContentKey = new Request(targetUrl, {
const fullContentKey = new Request(cacheTargetUrl, {
method: 'GET', // Always use GET method for cache key consistency
headers: new Headers(
[...request.headers.entries()].filter(
@@ -631,7 +636,7 @@ async function handleRequest(request, env, ctx) {
) {
const rangeHeader = request.headers.get('Range');
const cacheKey = rangeHeader
? new Request(targetUrl, {
? new Request(cacheTargetUrl, {
method: 'GET',
headers: new Headers(
[...request.headers.entries()].filter(
@@ -639,7 +644,7 @@ async function handleRequest(request, env, ctx) {
)
)
})
: new Request(targetUrl, { method: 'GET' });
: new Request(cacheTargetUrl, { method: 'GET' });
try {
if (ctx && typeof ctx.waitUntil === 'function') {
@@ -652,7 +657,7 @@ async function handleRequest(request, env, ctx) {
if (rangeHeader && response.status === 200) {
const rangedResponse = await cache.match(
new Request(targetUrl, {
new Request(cacheTargetUrl, {
method: 'GET',
headers: request.headers
})
+36
View File
@@ -94,6 +94,42 @@ describe('Flathub Response Rewriting', () => {
expect(body).toContain('RuntimeRepo=https://example.com/flathub/repo/flathub.flatpakrepo');
});
it('uses host-scoped cache keys for rewritten Flathub descriptors', async () => {
const cacheEntries = new Map();
vi.stubGlobal('caches', {
default: {
match: vi.fn(async request => cacheEntries.get(request.url) || null),
put: vi.fn(async (request, response) => {
cacheEntries.set(request.url, response.clone());
})
}
});
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockImplementation(
async () =>
new Response(`[Flatpak Repo]\nUrl=https://dl.flathub.org/repo/`, {
status: 200,
headers: { 'Content-Type': 'application/octet-stream' }
})
);
const responseA = await worker.fetch(
new Request('https://mirror-a.example/flathub/repo/flathub.flatpakrepo'),
{},
executionContext
);
const responseB = await worker.fetch(
new Request('https://mirror-b.example/flathub/repo/flathub.flatpakrepo'),
{},
executionContext
);
expect(fetchSpy).toHaveBeenCalledTimes(2);
expect(await readUtf8Text(responseA)).toContain('Url=https://mirror-a.example/flathub/repo/');
expect(await readUtf8Text(responseB)).toContain('Url=https://mirror-b.example/flathub/repo/');
});
it('does not rewrite binary repository metadata like summary files', async () => {
vi.spyOn(globalThis, 'fetch').mockResolvedValue(
new Response('summary-binary-payload', {