Skip to content

Commit 5a5abdd

Browse files
committed
Set the correct content type for gzipped files with the .gz ext
Using the gzip plugin it's possible to specify a `keep` option which will maintain both the original uncompressed file and save the gzipped version with a `.gz` suffix. Amazon S3 does not detect content type or encoding so this is all managed in this plugin via the mime package. The default mime type is `application/octet-stream` which is exactly what is detected for a `.gz` files. Uploading `.js.gz` and `.css.gz` files without their correct content types blows up some browsers with syntax errors (e.g. Safari) This PR makes the uploader a little smarter. If we detect a file is gzipped and has a `.gz` extension we strip the extension and look for the non-gzipped file in the file path list. If it's found, we'll do a mime lookup for the non-gzipped file and use _that_ content type and encoding instead. If a non-gzipped counterpart isn't found we will still upload the gzipped file as an `application/octet-stream` so this shouldn't break any valid gzip assets that aren't compressed as part of the gzip plugin in the pipeline.
1 parent 17c922f commit 5a5abdd

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

lib/s3.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ module.exports = CoreObject.extend({
9191
var key = prefix === '' ? filePath : [prefix, filePath].join('/');
9292
var isGzipped = gzippedFilePaths.indexOf(filePath) !== -1;
9393

94+
if (isGzipped && path.extname(basePath) === '.gz') {
95+
var basePathUncompressed = path.basename(basePath, '.gz');
96+
if (filePaths.indexOf(basePathUncompressed) !== -1) {
97+
contentType = mime.lookup(basePathUncompressed);
98+
encoding = mime.charsets.lookup(contentType);
99+
}
100+
}
101+
94102
if (encoding) {
95103
contentType += '; charset=';
96104
contentType += encoding.toLowerCase();

tests/fixtures/dist/app.css.gz

37 Bytes
Binary file not shown.

tests/unit/lib/s3-nodetest.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,35 @@ describe('s3', function() {
110110
assert.equal(s3Params.ContentType, 'text/css; charset=utf-8');
111111
assert.equal(s3Params.Key, 'js-app/app.css');
112112
assert.equal(s3Params.CacheControl, 'max-age=63072000, public');
113+
assert.isUndefined(s3Params.ContentEncoding);
114+
assert.deepEqual(s3Params.Expires, new Date('2030'));
115+
});
116+
});
117+
118+
it('sends the correct content type params for gzipped files with .gz extension', function() {
119+
var s3Params;
120+
s3Client.putObject = function(params, cb) {
121+
s3Params = params;
122+
cb();
123+
};
124+
125+
var options = {
126+
filePaths: ['app.css', 'app.css.gz'],
127+
gzippedFilePaths: ['app.css.gz'],
128+
cwd: process.cwd() + '/tests/fixtures/dist',
129+
prefix: 'js-app',
130+
acl: 'public-read',
131+
bucket: 'some-bucket'
132+
};
133+
134+
var promises = subject.upload(options);
135+
136+
return assert.isFulfilled(promises)
137+
.then(function() {
138+
assert.equal(s3Params.ContentType, 'text/css; charset=utf-8');
139+
assert.equal(s3Params.Key, 'js-app/app.css.gz');
140+
assert.equal(s3Params.CacheControl, 'max-age=63072000, public');
141+
assert.equal(s3Params.ContentEncoding, 'gzip');
113142
assert.deepEqual(s3Params.Expires, new Date('2030'));
114143
});
115144
});

0 commit comments

Comments
 (0)