I'm trying to get CORS to work properly with Amazon S3 + CloudFront.
After setting my CORS Configuration, it seems to work properly:
$ curl -H "Origin: https://app.close.io" -I "https://d4389n07pf8cq.cloudfront.net/built/app.9e1f9ee9.js" -s | grep Access
Access-Control-Allow-Origin: https://app.close.io
Access-Control-Allow-Methods: GET, HEAD
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
But when the resource is requested with Accept-Encoding: gzip
then the CORS headers aren't returned properly.
$ curl -H "Origin: https://app.close.io" -H "Accept-Encoding: gzip" -I "https://d4389n07pf8cq.cloudfront.net/built/app.9e1f9ee9.js" -s | grep Access
(nothing)
Why is that?
My CORS configuration looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>https://app.close.io</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
<AllowedHeader>Content-*</AllowedHeader>
<AllowedHeader>Host</AllowedHeader>
<AllowedHeader>Accept-Encoding</AllowedHeader>
</CORSRule>
</CORSConfiguration>
(I've also tried a CORS configuration with the Accent-Encoding
header removed.)
The S3 object itself is gzipped, and has "Metadata" of Content-Encoding: gzip
, Cache-Control: public, max-age=31536000
, and Content-Type: application/javascript
.
I don't understand why CloudFront+S3 CORS isn't working properly when requesting gzip.
By default, CloudFront doesn't consider headers when caching your objects in edge locations. If your origin returns two objects and they differ only by the values in the request headers, CloudFront caches only one version of the object.
CloudFront always caches responses to GET and HEAD requests. You can also configure CloudFront to cache responses to OPTIONS requests. CloudFront does not cache responses to requests that use the other methods.
A custom origin is an HTTP server, for example, a web server. The HTTP server can be an Amazon EC2 instance or an HTTP server that you host somewhere else. An Amazon S3 origin configured as a website endpoint is also considered a custom origin.
For enabling CORS we need to configure Cloudfront to allow forwarding of required headers. We can configure the behavior of Cloudfront by clicking on Cloudfront Distribution's "Distribution Settings". Then from the "Behaviour" tab click on "Edit". Here we need to whitelist the headers that need to be forwarded.
I think that the problem you are having is caused by CloudFront's lack of native support for CORS. At this time they do not support Vary on the Origin header so it's possible that CloudFront delivered an old cached response that did not have the correct CORS headers for your second request (with accept encoding: gzip).
Have a look at this thread on the AWS forum for a workaround to this missing CORS support:
https://forums.aws.amazon.com/message.jspa?messageID=422504#422532
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