I am trying to build a very light weight static website with a form using a serverless architecture:
I've tried to do this using a 302 redirect in API Gateway both with and without lambda proxy integration so that I could redirect the user to a different webpage that pulls their data from s3.
Using proxy integration I get an Internal Server Error every time.
Without it I just get the json response back to the user instead of an actual redirect.
Here is the python code for the response in my lambda function (this json is what comes back to the user currently instead of taking them to the url https://example.com):
return {
"isBase64Encoded": False,
"statusCode": 302,
"headers": {
"Location": "https://example.com"
},
"multiValueHeaders": {},
"body": "Success!!!"
}
I added the "Location" header to the Method Response in API Gateway and mapped it to integration.response.headers.location in the Integration Response (when I tried without lambda proxy).
No success with any of this though.
With proxy its an internal server error that only happens from the html form (doesn't happen when testing in api gateway console or lambda console), and without proxy it doesn't redirect to the value in the Location header, just prints the json to the url of the api.
Any help, guidance or suggestions is much appreciated!
Thanks for your time.
Sharing how I figured this out in case someone else ever runs into a similar issue.
I was getting an Internal Server error when using Lambda Proxy Integration because of the way I was parsing my event variable from API Gateway.
Assuming your API Gateway is configured to Lambda Proxy Integration and that your Lambda function is written in python, the below code should result in a successful 302 Redirect when triggered from a static s3 http form:
import urllib.parse
from furl import furl
def lambda_handler(event, context):
body = urllib.parse.unquote(event["body"])
furledBody = furl("/abc?" + body)
parameter1 = furledBody.args["parameter1"]
parameter2 = furledBody.args["parameter2"]
parameter3 = furledBody.args["parameter3"]
#Do stuff with body parameters
return {
"isBase64Encoded": False,
"statusCode": 302,
"headers": {
"Location": "https://example.com"
}
"multiValueHeaders": {},
"body": ""
}
This however is not the design I went with for my use case of providing the data my lambda function downloaded back to the client for the user to download.
Instead I configured my lambda response to contain html that automatically rendered at the client as a response to the http form request. Within the html I include S3 pre-signed URLs that were generated earlier in the lambda:
import boto3
s3 = boto3.client('s3')
presignedURL = s3.generate_presigned_url('get_object',{'Bucket': '[insert bucket name]', 'Key': '[insert key aka file name including the full path]'}, 500, 'GET'}
responseBody = (
"<html>"
"<head></head>"
"<body>"
"<a href=\"" + presignedURL + "\"download><button>Download</button></a>"
"</body>"
"</html>")
return {
"isBase64Encoded": False,
"statusCode": 200,
"headers": {
"Content-Type": "text/html"
}
"multiValueHeaders": {},
"body": responseBody
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With