Created
October 30, 2023 05:45
-
-
Save javanigus/46d9bad88a9244d2789dc00c41912a8f to your computer and use it in GitHub Desktop.
AWS Lambda Function to Redirect HTTP Requests by Reading JSON Data in S3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const REDIRECTS_DATA_REGION = 'us-east-1'; | |
const REDIRECTS_DATA_BUCKET = 'pdfs'; | |
const REDIRECTS_DATA_OBJECT = 'docs/pdf-redirects.json'; | |
// https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/command/GetObjectCommand/ | |
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3"; | |
const client = new S3Client({ | |
region: REDIRECTS_DATA_REGION | |
}); | |
async function readFile(bucketName, filename) { | |
const input = { Bucket: bucketName, Key: filename }; | |
const command = new GetObjectCommand(input); | |
const response = await client.send(command); | |
return response.Body.transformToString(); | |
} | |
async function getRedirectsData() { | |
const txt = await readFile(REDIRECTS_DATA_BUCKET, REDIRECTS_DATA_OBJECT); | |
let data; | |
try { | |
data = JSON.parse(txt); | |
} catch (e) { | |
console.error('getRedirectsData parse failed', txt, e); | |
data = {}; | |
} | |
return data; | |
} | |
const supportedStatusCodes = { | |
301: 'Moved Permanently', | |
302: 'Found', | |
307: 'Temporary Redirect', | |
}; | |
export const handler = async (event, context) => { | |
// Get the incoming request and the initial response from S3 | |
// https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html | |
const { request, response } = event.Records[0].cf; | |
// request.uri is just the URL path without hostname or querystring | |
let path = request.uri; | |
// Cut off trailing slash to normalize it | |
if (path.slice(-1) === '/') { | |
path = path.slice(0, -1); | |
} | |
const redirectsData = await getRedirectsData(); | |
const redirectData = redirectsData[path]; | |
// See if a redirect exists & sanity check that the redirect object is what we expect | |
const shouldRedirect = !!( | |
redirectData && | |
redirectData.to && | |
supportedStatusCodes[redirectData.statusCode] | |
); | |
if (shouldRedirect) { | |
// Note: We can't completely create a new set of headers even for a redirect | |
// because Cloudfront fails painfully if you set (or clear) a "read-only" header. | |
// For Origin Response triggers, that includes leaving "Transfer-Encoding" alone. | |
// https://github.com/awsdocs/amazon-cloudfront-developer-guide/blob/master/doc_source/lambda-requirements-limits.md#read-only-headers | |
response.headers['location'] = [ | |
{ | |
key: 'Location', | |
value: redirectData.to, | |
}, | |
]; | |
return { | |
status: redirectData.statusCode, | |
statusDescription: supportedStatusCodes[redirectData.statusCode], | |
headers: response.headers, | |
}; | |
} | |
return response; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment