I am trying to get CloudFront to serve a gzipped text file along with Content-Length: <bytes> and Access-Control-Expose-Headers: Content-Length headers so I can display the download progress when using fetch().
The setup I have is:
- Pre-compress the files with gzip before uploading to S3 and set
Content-Encoding: gzip. (Using CloudFront's automatic compression will mean that it is compressed on-the-fly and theContent-Lengthheader will not be set.) - CORS settings for S3 setting
Allow-Control-Expose-Headers: Content-Lengthas follows:
<?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedMethod>HEAD</AllowedMethod> <AllowedHeader>*</AllowedHeader> <ExposeHeader>Content-Length</ExposeHeader> </CORSRule> </CORSConfiguration> - CloudFront setup with the corresponding S3 Origin and:
- GET, HEAD, OPTIONS allowed
- Origin header whitelisted
- "Compress Objects Automatically" disabled
Using this configuration I get:
Requesting from S3:
curl <s3 URL> -H "Accept-Encoding: gzip" -H "Origin: example.com" -I
HTTP/1.1 200 OK x-amz-id-2: ... x-amz-request-id: ... Date: Sat, 03 Aug 2019 06:28:41 GMT Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, HEAD Access-Control-Expose-Headers: Content-Length Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method Last-Modified: Sat, 03 Aug 2019 05:32:02 GMT ETag: "6483b10f491dc607412899efad695a04" Content-Encoding: gzip x-amz-version-id: ... Accept-Ranges: bytes Content-Type: text/plain; charset=utf-8 Content-Length: 559354 Server: AmazonS3 Requesting from CloudFront without specifying
Accept-Encoding: gzip(or simply deliberately mis-spelling it asgzp):curl <cloudfront URL> -H "Origin: example.com" -I
HTTP/2 200 content-type: text/plain; charset=utf-8 content-length: 559354 date: Sat, 03 Aug 2019 06:05:26 GMT access-control-allow-origin: * access-control-allow-methods: GET, HEAD access-control-expose-headers: Content-Length last-modified: Sat, 03 Aug 2019 05:32:02 GMT etag: "6483b10f491dc607412899efad695a04" content-encoding: gzip x-amz-version-id: ... accept-ranges: bytes server: AmazonS3 vary: Origin age: 1572 x-cache: Hit from cloudfront via: 1.1 xxxxx.cloudfront.net (CloudFront) x-amz-cf-pop: ... x-amz-cf-id: ... Requesting from CloudFront specifying
Accept-Encoding: gzip:curl <cloudfront URL> -H "Accept-Encoding: gzip" -H "Origin: example.com" -I
HTTP/2 200 content-type: text/plain; charset=utf-8 content-length: 559354 date: Sat, 03 Aug 2019 05:39:50 GMT access-control-allow-origin: * access-control-allow-methods: GET, HEAD last-modified: Sat, 03 Aug 2019 05:32:02 GMT etag: "6483b10f491dc607412899efad695a04" content-encoding: gzip x-amz-version-id: ... accept-ranges: bytes server: AmazonS3 vary: Origin age: 3239 x-cache: Hit from cloudfront via: 1.1 xxxx.cloudfront.net (CloudFront) x-amz-cf-pop: ... x-amz-cf-id: ... Notice that the access-control-expose-headers: Content-Length header gets dropped from the CloudFront response headers simply because we set Accept-Encoding: gzip.
(Also note that S3 is happy to return it even when Accept-Encoding: gzip is set.)
Is there any way to get CloudFront to keep the Access-Control-Expose-Headers header when the request has Accept-Encoding: gzip?
Access-Control-Expose-Headersheader.