fix(pypi): prevent caching origin-bound rewritten index pages

This commit is contained in:
xixu-me committed 2026-03-16 12:57:21 +08:00
1 parent 83c167aee1
commit a10413eddf
2 files changed
+26

No files matched your search

+5
View File
@@ -555,6 +555,7 @@ async function handleRequest(request, env, ctx) {
/** @type {string | ReadableStream<Uint8Array> | null} */
let responseBody = response.body;
let rewrittenContentLength = null;
let hasOriginBoundRewrite = false;
if (
shouldRewriteTextResponse(
@@ -575,6 +576,7 @@ async function handleRequest(request, env, ctx) {
);
responseBody = rewrittenText;
rewrittenContentLength = new TextEncoder().encode(rewrittenText).byteLength;
hasOriginBoundRewrite = platform === 'pypi';
}
const headers = new Headers(response.headers);
@@ -586,6 +588,8 @@ async function handleRequest(request, env, ctx) {
if (!isGit && !isGitLFS && !isDocker && !isAI && !isHF) {
if (!canUseCache) {
headers.set('Cache-Control', 'no-store');
} else if (hasOriginBoundRewrite) {
headers.set('Cache-Control', 'no-store');
} else if (hasSensitiveHeaders) {
headers.set('Cache-Control', 'private, no-store');
const existingVary = headers.get('Vary');
@@ -629,6 +633,7 @@ async function handleRequest(request, env, ctx) {
!isDocker &&
!isAI &&
!isHF &&
!hasOriginBoundRewrite &&
!hasSensitiveHeaders &&
request.method === 'GET' &&
response.ok &&
+21
View File
@@ -64,6 +64,27 @@ describe('Worker regression coverage', () => {
expect(clearTimeoutSpy).toHaveBeenCalledWith(timeoutToken);
});
it('does not cache host-bound PyPI rewritten HTML responses', async () => {
vi.spyOn(globalThis, 'fetch').mockResolvedValue(
new Response('<a href="https://files.pythonhosted.org/packages/demo.whl">demo</a>', {
status: 200,
headers: { 'Content-Type': 'text/html; charset=utf-8' }
})
);
const response = await worker.fetch(
new Request('https://mirror.example/pypi/simple/demo/'),
{},
executionContext
);
const body = await response.text();
expect(response.status).toBe(200);
expect(body).toContain('https://mirror.example/pypi/files/packages/demo.whl');
expect(response.headers.get('Cache-Control')).toBe('no-store');
expect(cacheDefault.put).not.toHaveBeenCalled();
});
it('forwards body and content type for configured non-protocol POST requests', async () => {
/** @type {{ url: string, method: string | undefined, body: string | null, contentType: string | null, cf: unknown }} */
let observed = {