I have configured the following redirect rule to my AWS Application Load Balancer to redirect all HTTP traffic to HTTPS:
The issue is that when I now curl
(or visit the domain in the browser), I will get this ugly and redundant Location
response (domain changed to example.com):
~ $ curl -I http://www.example.com
HTTP/1.1 301 Moved Permanently
Server: awselb/2.0
Date: Mon, 14 Sep 2020 18:28:48 GMT
Content-Type: text/html
Content-Length: 150
Connection: keep-alive
Location: https://www.example.com:443/
I know that https://www.example.com:443/
is in practice just fine, and I know that it will not be shown in the end user's browser's URL field. But still, it will be shown in the browser's network tab's 'Response headers', and to me it just looks unprofessional compared to a redirect without the port, e.g.:
~ $ curl -I http://www.apple.com
HTTP/1.1 301 Moved Permanently
Server: AkamaiGHost
Content-Length: 0
Location: https://www.apple.com/
Cache-Control: max-age=0
Expires: Mon, 14 Sep 2020 18:33:23 GMT
Date: Mon, 14 Sep 2020 18:33:23 GMT
Connection: keep-alive
strict-transport-security: max-age=31536000
Set-Cookie: geo=FI; path=/; domain=.apple.com
Set-Cookie: ccl=izHQtSPVGso4jrdTGqyAkA==; path=/; domain=.apple.com
It would seem like a logical thing to just drop the port from the URL, but unfortunately it's a required field:
Also the 'Switch to full URL' option doesn't seem to really help, even though the port can be cleared there:
it still appears back after saving:
Is there any way to make this work?
Edit:
My domain is managed through AWS Route 53.
UPDATE: maybe it's worth mentioning this is nice as an exercise and show capabilities. However between a Lambda redirection and just a pure Load Balancer redirection, I'd still suggest you go with the ALB-native. It's more performatic (no cold-start, no extra hop), less error-prone (no coding required), for the cost of just aesthetics on a network trace or developer tools. End users would never notice that (you probably browse in lot of these sites everyday and you don't even know). So if you ask me, I'd suggest against going to production with something like this.
If you want something very simple as a redirect, you could just create a Target Group pointing to a Lambda function that returns a redirect. It doesn't require the overhead of managing a CloudFront distribution or trying to make it work behind a load balancer, as that would require changes in your DNS as well, since you cannot just place CloudFront behind a load balancer (not that I know of, at least).
For your case, I created a Lambda function (Python 3.8) with the following code:
def lambda_handler(event, context):
response = {}
if event.get('headers', {}).get('x-forwarded-proto', '') == 'http':
print(event)
response["statusCode"]=302
response["headers"] = {"Location": f"https://{event['headers']['host']}{event['path']}"}
response["body"]=""
return response
Then I created a new Target Group with that Lambda function as backend:
Finally, I configured my Listener on port 80 to the redirect Target Group:
With this implementation, your 302 redirect will show up as you expected: