Skip to content

Instantly share code, notes, and snippets.

@croesus
Created April 29, 2018 15:06
Show Gist options
  • Save croesus/c1692dfc6bac5d4d84c063c1a894e099 to your computer and use it in GitHub Desktop.
Save croesus/c1692dfc6bac5d4d84c063c1a894e099 to your computer and use it in GitHub Desktop.
CloudFront Edge Lambda redirect non-www to www
'use strict';
exports.handler = (event, context, callback) => {
// Extract the request from the CloudFront event that is sent to Lambda@Edge
var request = event.Records[0].cf.request;
var params = '';
if(('querystring' in request) && (request.querystring.length>0)) {
params = '?'+request.querystring;
}
var miduri = request.uri.replace(/(\/[\w\-_]+)$/, '$1/');
var newuri = "https://www.example.com" + miduri + params;
const response = {
status: '301',
statusDescription: 'Permanently moved',
headers: {
location: [{
key: 'Location',
value: newuri
}]
}
};
return callback(null, response);
};
@ahmadkhalaf1
Copy link

Thank you for this function :)

can you please explain what does these 2 lines do?

 var miduri = request.uri.replace(/(\/[\w\-_]+)$/, '$1/');
 var newuri = "https://www.example.com" + miduri + params;
because i ended up with https://www.mysite.de/http://mysite.de
as a result of using this function , i think something is not right .

thanks

@croesus
Copy link
Author

croesus commented Jan 13, 2021

The first line is intended to add a trailing slash to the uri if it doesn't end in a file extension or a slash, so /blah becomes /blah/ but /blah.txt would be left intact. Looking again at it I think it might be broken for deeper paths - /foo/bar would become /bar/. I think this line would work better (although I don't have an AWS setup available to test the function):

var miduri = request.uri.replace(/((?:\/[\w\-_]+)*)(\/[\w\-_]+)$/, '$1$2/');

That doesn't explain your problem though. request.uri should just be the path on the server, without the domain information, so I'm not sure how you're ending up with your full http domain on the path. Is there an http-to-https rewrite in play as well, either on another edge function or the origin server? Perhaps that is what is going wrong.

@ahmadkhalaf1
Copy link

The first line is intended to add a trailing slash to the uri if it doesn't end in a file extension or a slash, so /blah becomes /blah/ but /blah.txt would be left intact. Looking again at it I think it might be broken for deeper paths - /foo/bar would become /bar/. I think this line would work better (although I don't have an AWS setup available to test the function):

var miduri = request.uri.replace(/((?:\/[\w\-_]+)*)(\/[\w\-_]+)$/, '$1$2/');

That doesn't explain your problem though. request.uri should just be the path on the server, without the domain information, so I'm not sure how you're ending up with your full http domain on the path. Is there an http-to-https rewrite in play as well, either on another edge function or the origin server? Perhaps that is what is going wrong.

Thank you so much the new regex work perfect and helped me specially for media paths like www.mysite.de/robots.txt .

i have no idea why my domain shows up like this , but at the end i decided not to use this lambda edge function for my gatsby redirect from non-www to www , and its working as expected only by using cloudfront with http to https redirect and s3 bucket with static hosting and redirect to my www.site.de.

thanks again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment