0

This is probablly related to Serving gzipped CSS and JavaScript from Amazon CloudFront via S3, but although I followed the doc I still can get this situation to work :

An S3 bucket contains files that I have gzipped (with grunt-contrib-compress, if that's of any relevance.)

My bucket has a CORS configuration :

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*.myorigin.net</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

The bucket is served via Cloudfront.

My Cloudfront has CORS configured to :

  • Allow GET,HEAD,OPTIONS,PUT,etc...
  • on HTTPS
  • to cache OPTIONS requests
  • to whitelist Access-Control-Request-Headers, Access-Control-Request-Method and Origin

Using curl, I'm able to get my resources, with the right header to request gzip, and I get a gzipped version

curl --insecure https:/whatever.cloudfront.net/.../foo.js --silent -H "Accept-Encoding:gzip,deflate,sdch" -I

HTTP/1.1 200 OK
Content-Type: application/javascript
Content-Length: 33990
Connection: keep-alive
Date: Wed, 06 May 2015 17:12:53 GMT
Content-Encoding: gzip
Last-Modified: Wed, 06 May 2015 16:36:40 GMT
ETag: "7a92919df6117827de9474851afe06c0"
Accept-Ranges: bytes
Server: AmazonS3
Age: 70
X-Cache: Hit from cloudfront
Via: 1.1 (redacted).cloudfront.net (CloudFront)
X-Amz-Cf-Id: iaghGGDg3f3l4njz7mpXeOzqIS5OCR5kaehk4Td4-Bxiv2KtljHVlQ==

I'am able to get the content decoded by adding the --compressed flag, so the files seem to be correct.

If I now do a CORS request, with curl, again, I get the proper encoding :

curl --insecure https://.../foo.js --silent -H "Accept-Encoding: gzip,deflate,sdch" -I -H "Origin: myorigin.net"
HTTP/1.1 200 OK
Content-Type: application/javascript
Content-Length: 33990
Connection: keep-alive
Date: Wed, 06 May 2015 17:16:06 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD
Access-Control-Max-Age: 3000
Content-Encoding: gzip
Last-Modified: Wed, 06 May 2015 16:36:40 GMT
ETag: "7a92919df6117827de9474851afe06c0"
Accept-Ranges: bytes
Server: AmazonS3
Vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method
X-Cache: Miss from cloudfront
Via: 1.1 redacted.cloudfront.net (CloudFront)
X-Amz-Cf-Id: kaUV4S9wiCGzXp8N_Gg2LhGK8uYw1-qRtSw6w_Ry4V8oHZiLRvWULA==

Still, for some reason, when my browser does the request... there is no "Content-Encoding", and so the content is not uncompressed, and since I'm loading it with requirejs, I get a bad error.

Request :
GET /resources-gz/foo.js HTTP/1.1
Host: d28p9e2ugw1o8w.cloudfront.net
Connection: keep-alive
Cache-Control: no-cache
Accept: */*
Pragma: no-cache
User-Agent: Mozilla/5.0 (X11; Linux i686 (x86_64)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Referer: http://localhost:3000/start
Accept-Encoding: gzip,deflate,sdch
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,de;q=0.2

Response:
HTTP/1.1 200 OK
Content-Type: application/javascript
Content-Length: 33990
Connection: keep-alive
Date: Wed, 06 May 2015 16:31:27 GMT
Last-Modified: Wed, 06 May 2015 14:36:32 GMT
ETag: "7a92919df6117827de9474851afe06c0"
Accept-Ranges: bytes
Server: AmazonS3
Age: 1261
X-Cache: Hit from cloudfront
Via: 1.1 eazeaze.cloudfront.net (CloudFront)
X-Amz-Cf-Id: IjpNd37e-c38Moz3HQJ940KNTXfp1NN7O4enQJUYPd6Aet5Egw8XPg==

I'm obviously missing something...

Community
  • 1
  • 1
phtrivier
  • 13,047
  • 6
  • 48
  • 79

1 Answers1

0

Yes, you're missing something.

Read the response headers of the last response.

Last-Modified: Wed, 06 May 2015 14:36:32 GMT
ETag: "7a92919df6117827de9474851afe06c0"
Age: 1261
X-Cache: Hit from cloudfront

This is a CloudFront cache hit, and CloudFront fetched this object from S3 20+ minutes before you requested it ... and this version of the object had last been modified in S3 over two hours earlier... so, you're getting a copy that probably dates from before you "fixed" whatever you recently fixed.

When the etag of an object doesn't change, that means the body has not changed... but it doesn't imply anything about the response headers.

The easiest way to test this is to put a new file in S3 with a name you haven't used before... gzipped, of course, then try downloading it again.

Michael - sqlbot
  • 169,571
  • 25
  • 353
  • 427
  • Why is it then, that the request done by `curl` gets a cache miss, and receives the right headers, while the request done by the browser gets the "old" version ? Also, I launched a cloudfront invalidation of the cache, and it does not seem to help... Thanks ! – phtrivier May 07 '15 at 09:14
  • Is the `Age:` value incrementing when you load it from the browser? If not, the browser is pretending to fetch it from CloudFront but actually loading it from its own local browser cache. – Michael - sqlbot May 07 '15 at 09:35
  • Ok, actually, I think I boltched my cache invalidation (and did not wait long enough.) After going back from a clean slate, things seems to be okay. So that's what I was missing : PATIENCE ;) !! – phtrivier May 07 '15 at 09:36