Reputation: 407
I started learning NodeJS + Lambda@Edge a few days ago and one of the things that I was trying to do is the HTTP redirect/rewrite.
My current problem is when I try to use regex on the destination
. For example, I want to redirect https://example.com/pt-BR/blog-posts/....
to https://example.com/pt/blog/....
, just rewriting the beginning of the pathname
.
Is it possible to do this redirection? I know that I could do it via NGINX, but I was wondering if I could do the same via Lambda@Edge and more "dynamic", like getting these URLs via DynamoDB.
const redirects = require('./redirects.json').map(
({ source, destination }) => ({
source: new RegExp(source),
destination
})
);
exports.handler = async event => {
const request = event.Records[0].cf.request;
for (const { source, destination } of redirects) {
if (source.test(request.uri)) {
return {
status: '301',
statusDescription: 'Moved Permanently',
headers: {
location: [{ value: destination }]
}
};
}
}
return request;
};
This is the redirects.json
. The first two examples work perfectly, just the last one that is redirection to https://example.com/pt/blog/$1
instead of https://example.com/pt/blog/my-post-test001
.
[
{
"source": "^/pt/pt",
"destination": "/pt/"
},
{
"source": "^/en/en",
"destination": "/en/"
},
{
"source": "^/pt-BR/blog-posts/(.*)",
"destination": "/pt/blog/$1"
}
]
These are the examples/docs that I checked: https://nodejs.org/docs/latest/api/url.html#url_url https://aws.amazon.com/blogs/networking-and-content-delivery/leveraging-external-data-in-lambdaedge/ https://www.npmjs.com/package/express-urlrewrite
Upvotes: 0
Views: 6507
Reputation: 5508
Here's one for Node 12 that I use on Svedig to route /session/My-Workout
to /session/index.html
.
async function handler({ Records: [{ cf: { request } }] }) {
const { uri } = request;
if (uri.startsWith('/session/')) {
return {
...request,
uri: '/session/index.html',
};
}
return request;
}
exports.handler = handler;
I would also recommend a Path Pattern of session/*
.
Upvotes: 2
Reputation: 544
Yes, it's possible to rewrite a Cloudfront view request uri. The right approach depends on whether the target of the rewrite is also a Cloudfront object in the distribution origin. If it is, simply change the uri to the intended target.
Here is an example function that alters the uri of the cfrequest. The callback returns the same cfrequest to a different uri.
Example with NodeJS: rewrite the uri '/posts/' to '/posts/index.html'
const DEFAULT_OBJECT = 'index.html';
exports.handler = (event, context, callback) => {
const cfrequest = event.Records[0].cf.request;
if (cfrequest.uri.length > 0 && cfrequest.uri.charAt(cfrequest.uri.length - 1) === '/') {
// e.g. /posts/ to /posts/index.html
cfrequest.uri += DEFAULT_OBJECT;
}
callback(null, cfrequest);
return true;
};
Make sure to configure the Cloudfront behavior's viewer request with the rewrite Lambda@Edge function. That's different than an origin request lambda function.
Link: Hugo Quick Start, hosted on Cloudfront with lambda@edge
That'll be one happy lambda function!
Upvotes: 3