Device based redirection on CloudFront serving from S3 origin

cloudfront add cache-control header
aws lambda redirect
lambda@edge s3
lambda edge a/b testing
lambda-edge add header
lambda@edge geolocation
aws lambda read cookie
lambda edge query string

Is there a way to redirect the user to the mobile version of a web app say m.foobar.com based on the User Agent header using CloudFront?

I did read up on header caching using the user's device type using CloudFront-Is-Mobile-Viewer header. But, I can only whitelist it if I'm using a custom origin to serve my assets (ELB or an EC2 instance). In such a scenario, I could edit my server configuration to handle the redirection.

However, I'm using S3 to serve my application now and would prefer a solution within the CloudFront/S3 ecosystem.

Edit: For S3 distributions, I DONOT have access to the CloudFront-Is-Mobile-Viewer and other CF headers.

Any help, pointers would be greatly appreciated!

Background Material: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html https://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/

Request and Response Behavior for Custom Origins, HTTP Request Headers and CloudFront Behavior (Custom and S3 Origins) CloudFront does not add the header before forwarding the request to your origin. For more information, see Configuring Caching Based on the Device Type. separately performs the validation step and the CloudFront server serves the object. In this article, I’m going to walk you through setting up a redirect rule in S3 and have it work with CloudFront. If you’ve never set up redirect rules in S3, not to worry. This article is for you! Setting up a bucket. First we need to jump into S3 and create a bucket. By clicking the Create Bucket button, a modal will appear.

Here is how I would solve it.

You don't need to perform a redirect for mobile apps. (Avoid redirect when possible) You can use the same url to serve desktop or mobile contents.

In your cloudfront whitelist, just whitelist CloudFront-Is-Mobile-Viewer header. That will cache the contents based on your device.

Implement Viewer Request Lambda Edge and add it to CloudFront. Lambda Edge is to program pop or CloudFront before the request gets to server.

In the LambdaEdge, verify the User-Agent header and classify whether you want to serve mobile or desktop contents. If mobile, then you can change the origin url to serve from mobile contents, else you can change it to desktop contents or default content.

You get your http headers in the User Request LambdaEdge.

Lambda Edge Documentation:

http://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html

Sample node implementation is available on the reference page.

If you really want to perform a redirect, you can do that with viewer response and make decision-based on the device header received.

A sample implementation of viewer response is covered in this blog,

https://aws.amazon.com/blogs/aws/lambdaedge-intelligent-processing-of-http-requests-at-the-edge/

The above implementation just spits back all the headers that it received, instead of sending 200 OK, the code need to be modified for 3xx status with the redirect location.

Hope it helps.

Dynamically Route Viewer Requests to Any Origin Using Lambda , This enables you to route requests to different origins based on request The object is returned to CloudFront from Amazon S3, served to the viewer and If you're still being redirected after the distribution state is Deployed, then you'll Game Tech Infrastructure & Automation Internet of Things Machine  Short Description. To serve a static website hosted on Amazon S3, you can deploy a CloudFront distribution using one of these configurations: Using a REST API endpoint as the origin with access restricted by an origin access identity (OAI) Using a website endpoint as the origin with anonymous (public) access allowed.

Currently at viewer response we don't have access to CloudFront-Is-X-Viewer headers even after setting them as whitelisted and moreover status header is read-only. I've solved it by triggering at origin request:

exports.handler = (event, context, callback) => {
const name = 'cloudfront-is-mobile-viewer';
const request = event.Records[0].cf.request;
const headers = request.headers;

if (headers[name] && headers[name][0].value == "true") {
    callback(null, {
        status:'302',
        statusDescription: 'Found',
        headers: {
            location: [{
                key: 'Location',
                value: `http://m.example.com${request.uri}`,
            }]
        }
    })
}

callback(null, request);

};

Multi-Origin CloudFront Setup to Route Requests to Services Based , AWS CloudFront allows to have multiple origins for the distribution and, to S3 bucket and then served via CloudFront (the origin is S3 bucket, with For example, we need to redirect requests to index.html for www.myapp.com/app need to copy them back to local machine, commit to git and redeploy). How to redirect S3 hosted static site from Domain A to Domain B in AWS Cloudfront setup?-1. My problem.

How to add decoder with this code for nodejs, i use this code but its give me a string of character(How to decode it URi string) Sorry for i add it to answer because i have low reputation

exports.handler = (event, context, callback) => {
const name = 'cloudfront-is-mobile-viewer';
const request = event.Records[0].cf.request;
const headers = request.headers;

if (headers[name] && headers[name][0].value == "true") {
     callback(null, {
        status:'302',
        statusDescription: 'Found',
           headers: {
        location: [{
            key: 'Location',
            value: `http://m.example.com${request.uri}`,
        }]
    }
})

}

callback(null, request); };

Redirection on CloudFront with Lambda@Edge, This was not an issue until we decided to use S3 private buckets and serve it through CloudFront with S3 origin. S3 has the functionality to  The headers that you can forward to the origin and that CloudFront bases caching on depend on whether your origin is an Amazon S3 bucket or a custom origin. Amazon S3 – You can configure CloudFront to forward and to cache your objects based on a number of specific headers (see the following list of exceptions).

Using AWS Lambda@Edge with CloudFront, Lambda@Edge is an addition to the AWS Lambda compute service which is Redirect the URL to another site, based on the header details. the page and change the response when detected as desktop and devices. Login to AWS console and create a bucket in S3 and add the . html file which you want to display. Example: Using an Origin-Request Trigger to Change From an Amazon S3 Origin to a Custom Origin This function demonstrates how an origin-request trigger can be used to change the custom origin from which the content is fetched, based on request properties.

Host a Static Site on AWS, using S3 and CloudFront, A simple tutorial demonstrating how to host a static website on AWS using S3, Register a Domain; Make an S3 Bucket; Upload to S3; Make a CloudFront Distribution Note that you'll need to verify your AWS account with a phone number as part of In the static website hosting form, select the "Redirect requests" option. This allows anyone to access your files either through CloudFront or using the Amazon S3 URL. CloudFront doesn't expose Amazon S3 URLs, but your users might have those URLs if your application serves any files directly from Amazon S3 or if anyone gives out direct links to specific files in Amazon S3.

[PDF] Hosting Static Websites on AWS, Speeding Up Your Amazon S3 Based Website Using Amazon CloudFront 14 devices. They usually consist of a mix of HTML documents, images, videos, CSS style System (DNS) service, to point your domain to your Amazon S3 bucket. value of the Viewer Protocol Policy to Redirect HTTP to HTTPS or HTTPS Only. When you create a distribution, you specify where CloudFront sends requests for the files. CloudFront supports using several AWS resources as origins. For example, you can specify an Amazon S3 bucket or a MediaStore container, a MediaPackage channel, or a custom origin, such as an Amazon EC2 instance or your own HTTP web server.

Comments
  • The solution is a perfect fit if I'm to use an ELB origin to forward my content. But seemingly, the Whitelist headers CloudFront-Is-Mobile-Viewer is not applicable for S3 distribution. For S3 distributions, only 3 headers are 'whitelistable': Access-Control-Request-Method, Access-Control-Request-Headers and Origin.
  • What if you use the static website endpoint like [bucket].s3-website-[region].amazonaws.com. this value can also be found on the Static Website Hosting settings page of your s3 bucket.
  • My origin is the fully qualified domain name of the S3 bucket whose format is kinda like this xxxx.s3.amazonaws.com. All of the website redirection docs on the AWS docs (docs.aws.amazon.com/AmazonS3/latest/dev/…) addresses static redirection based on keys, errors etc.; but none based on dynamic properties like user location/device.
  • Updated my answer to account for this by changing from an S3 origin to a Custom origin
  • I saw headers['cloudfront-is-mobile-viewer'] && headers['cloudfront-is-mobile-viewer'][0].value === 'true' from aws docs(docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/…). Maybe aws updated their headers?