Skip to content

Instantly share code, notes, and snippets.

@DavidWells
Created June 28, 2018 20:48
Show Gist options
  • Select an option

  • Save DavidWells/99216c20cdb3df334d5b98ff19644fa2 to your computer and use it in GitHub Desktop.

Select an option

Save DavidWells/99216c20cdb3df334d5b98ff19644fa2 to your computer and use it in GitHub Desktop.
How to do a 301 redirect from an AWS lambda function
exports.handler = (event, context, callback) => {
const response = {
statusCode: 301,
headers: {
Location: 'https://google.com',
}
};
return callback(null, response);
}
@DavidWells
Copy link
Copy Markdown
Author

Great for:

  • Download URLS
  • Link shortening tools
  • Unauthorized calls
  • Rick rolls

@fwahlqvist
Copy link
Copy Markdown

Hey David, any insight on how to do it with async/await and not callback

@MrLuit
Copy link
Copy Markdown

MrLuit commented Nov 18, 2018

@fwahlqvist here's a simple way to do that:

exports.handler = async (event) => {
    const response = {
        statusCode: 301,
        headers: {
            Location: 'https://google.com'
        }
    };
    
    return response;
};

@pickleat
Copy link
Copy Markdown

pickleat commented May 8, 2019

Thanks for this!

@wdonray
Copy link
Copy Markdown

wdonray commented May 16, 2019

@DavidWells can I redirect to multiple locations?

@ramonuchoa386
Copy link
Copy Markdown

Any tips for specific URL rules?

@regnatarajan
Copy link
Copy Markdown

Useful! Thank you.

@gnarlz
Copy link
Copy Markdown

gnarlz commented Jan 8, 2020

Agreed, very useful.

Thanks so much!

@KraGiE
Copy link
Copy Markdown

KraGiE commented Feb 13, 2020

@DavidWells can I redirect to multiple locations?

That's now how HTTP redirects work.

@diegopamio
Copy link
Copy Markdown

I get the json as HTML in the response, that could be because of the method (GET vs. POST)? Is there any workaround for both methods (GET and POST)?

@diegopamio
Copy link
Copy Markdown

Right now, I'm just getting the JSON printed on the page instead of performing the redirect itself.

@niravvarma
Copy link
Copy Markdown

niravvarma commented Apr 15, 2020

I see there can be many ways. From the official website, I found this: https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html and https://github.com/aws-samples/aws-lambda-redirection-at-edge
For one of our client, I am using the solution mentioned here: https://aws.amazon.com/blogs/networking-and-content-delivery/handling-redirectsedge-part1/ which works pretty well for mass redirects.

@chumicat
Copy link
Copy Markdown

chumicat commented May 7, 2020

@diegopamio, and the following

WARNING:

You have to check the choice of "Use lambda proxy integration" while binding the method to lambda in API gateway, or you will get only JSON.

Following are the snapshot.

ๆˆชๅœ– 2020-05-07 ไธŠๅˆ9 34 24

@AllanOricil
Copy link
Copy Markdown

When I use this example everything woks locally (Im using SAM CLI), but when I deploy to AWS I keep getting status code 502. Would you know what is the problem? inside cloud watch there is no error

exports.handler = async (event) => {
    const response = {
        statusCode: 301,
        headers: {
            Location: 'https://google.com'
        }
    };
    
    return response;
};

image

@AllanOricil
Copy link
Copy Markdown

II found the reason, I was adding additional headers. It can't have other headers, only the Location.

@GokulDharumar
Copy link
Copy Markdown

How to fix the same issue for httpapi? i get the json printed on the page instead of redirect

@juantelez
Copy link
Copy Markdown

Thanks David!!
This helped me a lot!

@wxgeorge
Copy link
Copy Markdown

wxgeorge commented Mar 10, 2022

@diegopamio, and the following

WARNING:

You have to check the choice of "Use lambda proxy integration" while binding the method to lambda in API gateway, or you will get only JSON.

Following are the snapshot.

ๆˆชๅœ– 2020-05-07 ไธŠๅˆ9 34 24

Further to this -

if you're looking for the docs on why a lambda like this "works", see https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html. Lambdas are not "HTTP enabled" by default, but a key way they can be is through a proxy integration with an API Gateway.

This gist is an example how a lambda can conform to an API Gateway's expectations around proxy integrations.

Those docs describe how the output of a lambda is mapped to an HTTP response
(and also describes how HTTP requests are mapped into the event).

To check if you understand: is the use of callback in the gist necessary?

@samirm
Copy link
Copy Markdown

samirm commented Sep 6, 2022

thank you!

@Divuzki
Copy link
Copy Markdown

Divuzki commented Sep 12, 2022

Great for:

  • Download URLS
  • Link shortening tools
  • Unauthorized calls
  • Rick rolls

Rick Rolls ๐Ÿ˜‚

@lzhou0
Copy link
Copy Markdown

lzhou0 commented Sep 26, 2022

Tried out this piece of code, but receiving this error:

{
  "errorType": "Runtime.ImportModuleError",
  "errorMessage": "Error: Cannot find module 'index'\nRequire stack:\n- /var/runtime/index.mjs",
  "trace": [
    "Runtime.ImportModuleError: Error: Cannot find module 'index'",
    "Require stack:",
    "- /var/runtime/index.mjs",
    "    at _loadUserApp (file:///var/runtime/index.mjs:951:17)",
    "    at async Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:976:21)",
    "    at async start (file:///var/runtime/index.mjs:1137:23)",
    "    at async file:///var/runtime/index.mjs:1143:1"
  ]

Anyone else come across this Runtime.ImportModuleError error?

@Divuzki
Copy link
Copy Markdown

Divuzki commented Sep 27, 2022

Tried out this piece of code, but receiving this error:

{
  "errorType": "Runtime.ImportModuleError",
  "errorMessage": "Error: Cannot find module 'index'\nRequire stack:\n- /var/runtime/index.mjs",
  "trace": [
    "Runtime.ImportModuleError: Error: Cannot find module 'index'",
    "Require stack:",
    "- /var/runtime/index.mjs",
    "    at _loadUserApp (file:///var/runtime/index.mjs:951:17)",
    "    at async Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:976:21)",
    "    at async start (file:///var/runtime/index.mjs:1137:23)",
    "    at async file:///var/runtime/index.mjs:1143:1"
  ]

Anyone else come across this Runtime.ImportModuleError error?

Can you show the code causing the problem?

@BuffMcBigHuge
Copy link
Copy Markdown

Came across this recently. The proper Lambda Edge function should look like:

exports.handler = (event, context, callback) => {
   const response = {
    status: 301,
    headers: {
        location: [{
            key:   'Location', 
            value: 'https://google.com',
        }],
    },
  };
  return callback(null, response);
}

Furthermore, the Role Trust Relationship for your Lambda should include:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "lambda.amazonaws.com",
                    "edgelambda.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

@anandakumarpalanisamy
Copy link
Copy Markdown

Tried out this piece of code, but receiving this error:

{
  "errorType": "Runtime.ImportModuleError",
  "errorMessage": "Error: Cannot find module 'index'\nRequire stack:\n- /var/runtime/index.mjs",
  "trace": [
    "Runtime.ImportModuleError: Error: Cannot find module 'index'",
    "Require stack:",
    "- /var/runtime/index.mjs",
    "    at _loadUserApp (file:///var/runtime/index.mjs:951:17)",
    "    at async Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:976:21)",
    "    at async start (file:///var/runtime/index.mjs:1137:23)",
    "    at async file:///var/runtime/index.mjs:1143:1"
  ]

Anyone else come across this Runtime.ImportModuleError error?

Have you tried naming the js file as 'index.js'?

@renchris
Copy link
Copy Markdown

renchris commented Nov 21, 2022

For those using API Gateway + Lambda, I followed this: https://aws.amazon.com/premiumsupport/knowledge-center/malformed-502-api-gateway/

const response = {
    "statusCode": 200,
    "headers": {
        "my_header": "my_value"
    },
    "body": JSON.stringify(responseBody),
    "isBase64Encoded": false
};

The four fields of statusCode, headers, body, and isBase64Encoded were required

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