Using Lambda at Edge and Python to Redirect WWW and other Requests

Perspect makes extensive use of Lambda at Edge for a variety of uses, but one of them is to redirect URLs that start with “www” if a site owner chooses to configure such redirects.  There isn’t much documentation anywhere as to how to accomplish this with Python, so here’s an example that uses the Chalice framework, but this could easily be used outside of Chalice with a slight modification.

 


from chalice import Chalice

from chalicelib.responses import generate_response

 

app = Chalice(app_name='redirect')

 

 

@app.lambda_function(name="redirect")

def redirect(event, context):

 

    request = event['Records'][0]['cf']['request']

    headers = request['headers']

 

    # Get the host name

    host_in_request = headers['host'][0]['value']

 

    # Get the path/uri in the request

    uri_in_request = event['Records'][0]['cf']['request']['uri']

 

 

    if host_in_request.startswith("www"):

        parts = host_in_request.split("www.")

        host_in_request = parts[1]

 

        try:

 

            new_host = "https://{}".format(host_in_request)

            if uri_in_request is not "/":

                new_host = new_host + uri_in_request

 

            print("Redirecting to: {}".format(new_host))

 

            response = {

            'status': '302',

            'statusDescription': 'Found',

            'headers': {

                'location': [{

                    'key': 'Location',

                    'value': new_host

                }]

            }

        }

 

        except Exception as e:

            return generate_response(500, "text/html", "Internal Server Error")

 

        else:

            return response

 

    # If the host does not start with www then just return the request which will cause the request to carry on without a redirect

    else:

        return request


 

This simple Lambda function makes use of a helper function called generate_response() to actually, well, generate the HTTP responses sent to the client:
 
 

def generate_response(code, value, data):

 

    response = {

            'status': code,

            'statusDescription': 'OK',

            'headers': {

                'cache-control': [

                    {

                        'key': 'Cache-Control',

                        'value': 'max-age=100'

                    }

                ],

                "content-type": [

                    {

                        'key': 'Content-Type',

                        'value': value

                    }

                ]

            },

            'body': data

        }

 

    return response