Skip to content

Instantly share code, notes, and snippets.

@nbolton
Created April 17, 2025 08:31
Show Gist options
  • Save nbolton/82d71943207d10a5f4b07d031e2b0fa0 to your computer and use it in GitHub Desktop.
Save nbolton/82d71943207d10a5f4b07d031e2b0fa0 to your computer and use it in GitHub Desktop.
// Lazy multipurpose mirror handler for AWS Lambda@Edge or API Gateway
import { S3Client, HeadObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3';
import fetch from 'node-fetch';
const s3 = new S3Client({ region: 'your-region' });
const BUCKET = 'qt-mirror-cache';
// Prefix -> upstream URL
const routeTable: Record<string, string> = {
'/qt': 'https://download.qt.io',
'/npm': 'https://registry.npmjs.org',
'/foo': 'https://example.com/foo',
};
export async function handler(event: any) {
const path = decodeURIComponent(event.path);
const prefix = Object.keys(routeTable).find(p => path.startsWith(p));
if (!prefix) {
console.warn(`[404] Unknown prefix for path: ${path}`);
return { statusCode: 404, body: 'Unknown mirror path' };
}
const upstream = routeTable[prefix];
const upstreamPath = path.slice(prefix.length);
const upstreamUrl = `${upstream}${upstreamPath}`;
const s3Key = path.startsWith('/') ? path.slice(1) : path;
try {
await s3.send(new HeadObjectCommand({ Bucket: BUCKET, Key: s3Key }));
console.info(`[HIT] Cache hit: s3://${BUCKET}/${s3Key}`);
return redirectToS3(s3Key);
} catch {
console.info(`[MISS] Cache miss: s3://${BUCKET}/${s3Key}`);
}
try {
const res = await fetch(upstreamUrl);
if (!res.ok) {
console.error(`[UPSTREAM FAIL] ${res.status} ${res.statusText} - ${upstreamUrl}`);
return { statusCode: res.status, body: 'Upstream error' };
}
const body = await res.buffer();
await s3.send(new PutObjectCommand({
Bucket: BUCKET,
Key: s3Key,
Body: body,
ContentType: res.headers.get('content-type') || 'application/octet-stream',
}));
console.info(`[FETCHED] ${upstreamUrl} → s3://${BUCKET}/${s3Key}`);
return redirectToS3(s3Key);
} catch (err) {
console.error(`[ERROR] Failed to fetch and store ${upstreamUrl}:`, err);
return { statusCode: 500, body: 'Mirror error' };
}
}
function redirectToS3(key: string) {
return {
statusCode: 302,
headers: {
Location: `https://${BUCKET}.s3.amazonaws.com/${key}`,
},
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment