HTTP Redirects with Cloudfront & S3

Posted on Tue 18 August 2015 in aws

Redirects can account for a significant share of direct traffic so taking a few minutes to optimize them is worthwhile.

Using Cloudfront & S3 for redirects will improve responsiveness, reduce server load and improve management (since they are managed via aws-cli or the console).

Let's say you have a typical .htaccess redirect like this.

RewriteEngine On
### re-direct to www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Or worse, it could look like this in your index.php

$protocol = (@$_SERVER["HTTPS"] == "on") ? "https://" : "http://";

if (substr($_SERVER['HTTP_HOST'], 0, 4) !== 'www.') {
    header('Location: '.$protocol.'www.'.$_SERVER['HTTP_HOST'].'/'.$_SERVER['REQUEST_URI']);

Instead, let's use Cloudfront to host these redirects as close to the user as possible.

First you'll need an S3 bucket with the website configuration activated like this:

$ aws s3api get-bucket-website --bucket
    "RedirectAllRequestsTo": {
        "HostName": "",
        "Protocol": "http"

Second, you'll need a cloudfront distribution using this site as the origin:

$ aws cloudfront get-distribution --id=E32XXXXXXXXX |jq .Distribution.DistributionConfig.Origins
 "Items": [
         "OriginPath": "",
         "CustomOriginConfig": {
             "OriginProtocolPolicy": "http-only",
             "HTTPPort": 80,
             "HTTPSPort": 443
         "Id": "",
         "DomainName": ""
 "Quantity": 1

Finally, re-assign the DNS to point to the cloudfront Distribution .

$ aws route53 list-resource-record-sets --hosted-zone-id=XXXXXXXXX |jq '.ResourceRecordSets[0]'
  "AliasTarget": {
    "HostedZoneId": "XXXXXXXXX",
    "EvaluateTargetHealth": false,
    "DNSName": ""
  "Type": "A",
  "Name": ""

Now you can test the performance

curl -w @curl-timing.txt -Is|egrep 'Location|time'
            time_namelookup:  0.005
               time_connect:  0.046
            time_appconnect:  0.000
           time_pretransfer:  0.046
              time_redirect:  0.000
         time_starttransfer:  0.092
                 time_total:  0.092