Skip to content

Instantly share code, notes, and snippets.

@mauritsl
Created January 18, 2023 07:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mauritsl/18b1333b3891236f53644c1909b3b735 to your computer and use it in GitHub Desktop.
Save mauritsl/18b1333b3891236f53644c1909b3b735 to your computer and use it in GitHub Desktop.
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
import { resolve } from 'path';
const s3 = new S3Client({ region: 'S3_REGION' });
const s3Params = {
Bucket: 'S3_BUCKET_NAME',
Key: 'router-paths.txt'
};
const TTL = 10000;
const pullStream = (body) => {
return new Promise((resolve, reject) => {
const buffers = [];
body.on('data', buf => {
buffers.push(Buffer.from(buf));
});
body.on('end', () => {
resolve(Buffer.concat(buffers));
});
body.on('error', reject);
});
};
let paths;
const getPaths = async () => {
if (paths) {
return paths;
}
const response = await s3.send(new GetObjectCommand(s3Params));
paths = (await pullStream(response.Body)).toString();
setTimeout(() => {
paths = undefined;
}, TTL);
return paths;
};
const getOriginPath = async clientPath => {
const clientParts = clientPath.substring(1).split('/');
const paths = (await getPaths())
.split('\n')
.map(s => s.trim())
.filter(s => s);
for (let i = 0; i < paths.length; ++i) {
const parts = paths[i].split('.html')[0].split('/');
const match =
parts.length === clientParts.length &&
parts.reduce(
(match, part, index) =>
match &&
clientParts[index].length &&
(part === clientParts[index] || part.startsWith('@') || part.startsWith('[')),
true
);
if (match) {
return '/' + paths[i];
}
}
return '/404.html';
};
export const handler = (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
const request = event.Records[0].cf.request;
const headers = request.headers;
const origin = request.origin;
// Ignore static files.
if (request.uri.indexOf('.') >= 0) {
callback(null, request);
return;
}
// Return 404 page for the paths config file.
if (request.uri === '/router-paths.txt') {
request.uri = '/404.html';
callback(null, request);
return;
}
// Homepage.
if (request.uri === '/') {
request.uri = '/index.html';
callback(null, request);
return;
}
// Remove trailing slashes by redirect.
if (request.uri.endsWith('/')) {
const response = {
status: '302',
statusDescription: 'Found',
headers: {
location: [
{
key: 'Location',
value: request.uri.substring(0, request.uri.length - 1)
}
]
}
};
callback(null, response);
return;
}
// Lookup path in paths text file.
getOriginPath(request.uri)
.then(path => {
request.uri = path;
callback(null, request);
return;
})
.catch(err => {
console.log(err);
callback(null, request);
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment