chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
// The edge cache in the Worker entry: site-hostname GETs are served from
// caches.default so repeat traffic never crosses to the Durable Object,
// while the PDS's own hostname bypasses the cache entirely.
import { afterEach, describe, expect, it, vi } from 'vitest';
import worker, {
responseStorable,
siteCacheable,
siteHost,
} from '../src/index.js';
const ENV_BASE = {
HOSTNAME: 'pds.example.com',
PDS_EXPERIMENTAL_SITE_DOMAIN: 'example.com',
};
/** @param {Request} request @param {Record<string, string>} [env] */
function cacheableFor(request, env = {}) {
return siteCacheable(request, /** @type {any} */ ({ ...ENV_BASE, ...env }));
}
describe('siteHost', () => {
/** @param {string} url @param {Record<string, string>} [env] */
const hostFor = (url, env = {}) =>
siteHost(new Request(url), /** @type {any} */ ({ ...ENV_BASE, ...env }));
it('accepts only hostnames under the site domain, never the PDS', () => {
expect(hostFor('https://blog.example.com/')).toBe(true);
expect(hostFor('https://example.com/')).toBe(true);
expect(hostFor('https://pds.example.com/')).toBe(false);
expect(hostFor('https://other.test/')).toBe(false);
expect(hostFor('http://localhost:8787/')).toBe(false);
expect(
hostFor('https://blog.example.com/', {
PDS_EXPERIMENTAL_SITE_DOMAIN: '',
}),
).toBe(false);
});
it('compares the PDS hostname without its port', () => {
expect(
hostFor('https://pds.example.com/', { HOSTNAME: 'pds.example.com:8443' }),
).toBe(false);
});
});
describe('siteCacheable', () => {
it('accepts site-hostname GETs and nothing else', () => {
expect(cacheableFor(new Request('https://blog.example.com/'))).toBe(true);
expect(cacheableFor(new Request('https://pds.example.com/'))).toBe(false);
expect(
cacheableFor(
new Request('https://blog.example.com/', { method: 'POST' }),
),
).toBe(false);
expect(
cacheableFor(new Request('https://blog.example.com/'), {
PDS_EXPERIMENTAL_SITE_DOMAIN: '',
}),
).toBe(false);
});
it('keeps registry reads out of the cache', () => {
expect(
cacheableFor(new Request('https://example.com/v2/app/manifests/latest')),
).toBe(false);
expect(
cacheableFor(new Request('https://example.com/npm/@pdsjs%2fcore')),
).toBe(false);
expect(cacheableFor(new Request('https://example.com/v2x'))).toBe(true);
});
});
describe('responseStorable', () => {
it('stores only shareable 200s', () => {
const ok = new Response('x', {
status: 200,
headers: { 'Cache-Control': 'public, max-age=60' },
});
expect(responseStorable(ok)).toBe(true);
expect(responseStorable(new Response('x', { status: 404 }))).toBe(false);
expect(
responseStorable(
new Response('x', { headers: { 'Cache-Control': 'no-store' } }),
),
).toBe(false);
expect(
responseStorable(
new Response('x', { headers: { 'Set-Cookie': 'sid=1' } }),
),
).toBe(false);
});
});
describe('worker entry cache flow', () => {
/** @type {Map<string, Response>} */
const store = new Map();
const fakeCaches = {
default: {
/** @param {Request} request */
match: async (request) => store.get(request.url)?.clone(),
/** @param {Request} request @param {Response} response */
put: async (request, response) => {
store.set(request.url, response);
},
},
};
/** @param {Response} doResponse */
function makeEnv(doResponse) {
let doCalls = 0;
const env = /** @type {any} */ ({
...ENV_BASE,
PDS: {
idFromName: () => 'default',
get: () => ({
fetch: async () => {
doCalls += 1;
return doResponse.clone();
},
}),
},
});
return { env, doCalls: () => doCalls };
}
const ctx = /** @type {any} */ ({
/** @param {Promise<unknown>} p */
waitUntil: (p) => p,
});
afterEach(() => {
store.clear();
vi.unstubAllGlobals();
});
it('serves the second request from cache and answers conditionals with 304', async () => {
vi.stubGlobal('caches', fakeCaches);
const { env, doCalls } = makeEnv(
new Response('<h1>hi</h1>', {
status: 200,
headers: {
'Cache-Control': 'public, max-age=60',
ETag: '"bafycid"',
},
}),
);
const url = 'https://blog.example.com/';
const first = await worker.fetch(new Request(url), env, ctx);
expect(first.status).toBe(200);
expect(doCalls()).toBe(1);
const second = await worker.fetch(new Request(url), env, ctx);
expect(second.status).toBe(200);
expect(second.headers.get('X-Sites-Cache')).toBe('hit');
expect(await second.text()).toBe('<h1>hi</h1>');
expect(doCalls()).toBe(1);
const conditional = await worker.fetch(
new Request(url, { headers: { 'If-None-Match': '"bafycid"' } }),
env,
ctx,
);
expect(conditional.status).toBe(304);
expect(conditional.headers.get('Content-Length')).toBeNull();
expect(doCalls()).toBe(1);
});
it('never caches the 404 for an unknown site', async () => {
vi.stubGlobal('caches', fakeCaches);
const { env, doCalls } = makeEnv(
new Response('not found', {
status: 404,
headers: { 'Cache-Control': 'no-store' },
}),
);
const url = 'https://nosuch.example.com/';
await worker.fetch(new Request(url), env, ctx);
await worker.fetch(new Request(url), env, ctx);
expect(doCalls()).toBe(2);
expect(store.size).toBe(0);
});
it('redirects plain-HTTP site requests to HTTPS before anything else', async () => {
// No caches stub: the redirect must not touch the cache or the DO
const { env, doCalls } = makeEnv(new Response('x', { status: 200 }));
const response = await worker.fetch(
new Request('http://blog.example.com/sub/page?q=1'),
env,
ctx,
);
expect(response.status).toBe(301);
expect(response.headers.get('Location')).toBe(
'https://blog.example.com/sub/page?q=1',
);
expect(doCalls()).toBe(0);
});
it('trusts X-Forwarded-Proto over the URL scheme, both ways', async () => {
const { env, doCalls } = makeEnv(new Response('x', { status: 200 }));
// The edge hands the worker an https URL for a plain-HTTP visitor
const disguised = await worker.fetch(
new Request('https://blog.example.com/', {
headers: { 'X-Forwarded-Proto': 'http' },
}),
env,
ctx,
);
expect(disguised.status).toBe(301);
expect(disguised.headers.get('Location')).toBe('https://blog.example.com/');
expect(doCalls()).toBe(0);
vi.stubGlobal('caches', fakeCaches);
const secure = await worker.fetch(
new Request('https://blog.example.com/', {
headers: { 'X-Forwarded-Proto': 'https' },
}),
env,
ctx,
);
expect(secure.status).toBe(200);
expect(doCalls()).toBe(1);
});
it('sends PDS-hostname requests straight through, never touching caches', async () => {
// No caches stub at all: touching it would throw
const { env, doCalls } = makeEnv(new Response('{}', { status: 200 }));
const response = await worker.fetch(
new Request('https://pds.example.com/xrpc/_health'),
env,
ctx,
);
expect(response.status).toBe(200);
expect(doCalls()).toBe(1);
expect(store.size).toBe(0);
});
});