Created
June 9, 2022 02:40
-
-
Save firxworx/423f536f5487486a894f3fa0ccb21748 to your computer and use it in GitHub Desktop.
AWS Lambda@Edge for rewriting request URI - reverse proxy for static sites and apps hosted with S3 + CloudFront CDN
This file contains hidden or 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
'use strict' | |
/** | |
* Minimal implementation of an AWS 'Lambda@Edge' solution for rewriting a request URI. | |
* | |
* This Edge Lambda can support static sites + front-end apps hosted on AWS via S3 + CloudFront CDN, | |
* including those built by popular frameworks such as NextJS (e.g. via NextJS' `next export` static HTML export feature). | |
* | |
* An Edge Lambda provides control and can help meet real-world requirements that arise in the development of non-trivial | |
* front-end web applications, e.g. involving headers, with query strings, etc. that may not be supported (or at least | |
* elegantly supported) by "shortcut" AWS services such as AWS Amplify or app hosting services such as Netlify. | |
* | |
* Edge Lambdas like this example improve the behaviour of S3's static website hosting feature, which has potentially | |
* undesirable behaviours by design, e.g. issuing an HTTP 302 response to requests that omit a trailing slash. | |
* | |
* @see {@link https://aws.amazon.com/blogs/compute/implementing-default-directory-indexes-in-amazon-s3-backed-amazon-cloudfront-origins-using-lambdaedge/} | |
* @see {@link https://github.com/aws-samples/aws-lambda-edge-workshops/blob/master/Workshop1/Lab4_PrettyUrls/README.md} | |
* @see {@link https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html#lambda-event-structure-request} | |
*/ | |
exports.handler = (event, _context, callback) => { | |
const hasEndingSlashRegex = /\/$/ | |
const hasFileExtensionRegex = /(.+)\.[a-zA-Z0-9]{2,5}$/ | |
// extract request from the CloudFront event | |
const request = event.Records[0].cf.request | |
const requestUri = request.uri || '' | |
// if logic involving http headers is required... | |
// const headers = request.headers // array of request headers | |
// if logic involving the query string is required... | |
// const params = querystring.parse(request.querystring) // requires import `const querystring = require('querystring')` | |
// if the request uri ends in '/' then replace the trailing slash with /index.html | |
if (requestUri.match(hasEndingSlashRegex)) { | |
request.uri = requestUri.replace(/\/$/, '/index.html') | |
} | |
// if the request uri is not for a file (i.e. no file extension) then append /index.html | |
if (!requestUri.match(hasFileExtensionRegex)) { | |
request.uri = requestUri + '/index.html' | |
} | |
if (requestUri !== request.uri) { | |
console.log(`Rewrite request uri '${requestUri}' to '${request.uri}'`) | |
} | |
return callback(null, request) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment