Skip to content

Commit

Permalink
Merge pull request #71 from kanongil/lookupmap-option
Browse files Browse the repository at this point in the history
Add lookupMap option
  • Loading branch information
kanongil authored Dec 27, 2016
2 parents 8a037e1 + 11fb666 commit a164a8f
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 22 deletions.
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,11 @@ type based on filename extension.:
- `false` - header is not included. This is the default value.
- `'attachment'`
- `'inline'`
- `lookupCompressed` - if `true`, looks for the same filename with the '.gz' suffix for a
pre-compressed version of the file to serve if the request supports content encoding.
- `lookupCompressed` - if `true`, looks for for a pre-compressed version of the file with
the same filename with an extension, depending on the accepted encoding.
Defaults to `false`.
- `lookupMap` - an `object` which maps content encoding to expected file name extension.
Defaults to `{ gzip: '.gz' }.
- `etagMethod` - specifies the method used to calculate the `ETag` header response.
Available values:
- `'hash'` - SHA1 sum of the file contents, suitable for distributed deployments.
Expand Down Expand Up @@ -193,9 +195,11 @@ Generates a static file endpoint for serving a single file. `file` can be set to
- `false` - header is not included. This is the default value.
- `'attachment'`
- `'inline'`
- `lookupCompressed` - if `true`, looks for the same filename with the '.gz' suffix
for a pre-compressed version of the file to serve if the request supports content
encoding. Defaults to `false`.
- `lookupCompressed` - if `true`, looks for for a pre-compressed version of the file with
the same filename with an extension, depending on the accepted encoding.
Defaults to `false`.
- `lookupMap` - an `object` which maps content encoding to expected file name extension.
Defaults to `{ gzip: '.gz' }.
- `etagMethod` - specifies the method used to calculate the `ETag` header response.
Available values:
- `'hash'` - SHA1 sum of the file contents, suitable for distributed deployments.
Expand Down
2 changes: 2 additions & 0 deletions lib/directory.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ internals.schema = Joi.object({
showHidden: Joi.boolean(),
redirectToSlash: Joi.boolean(),
lookupCompressed: Joi.boolean(),
lookupMap: Joi.object().min(1).pattern(/.+/, Joi.string()),
etagMethod: Joi.string().valid('hash', 'simple').allow(false),
defaultExtension: Joi.string().alphanum()
});
Expand Down Expand Up @@ -94,6 +95,7 @@ exports.handler = function (route, options) {
const fileOptions = {
confine: null,
lookupCompressed: settings.lookupCompressed,
lookupMap: settings.lookupMap,
etagMethod: settings.etagMethod
};

Expand Down
44 changes: 27 additions & 17 deletions lib/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const Etag = require('./etag');
const internals = {};


internals.defaultMap = {
gzip: '.gz'
};


internals.schema = Joi.alternatives([
Joi.string(),
Joi.func(),
Expand All @@ -25,6 +30,7 @@ internals.schema = Joi.alternatives([
filename: Joi.string(),
mode: Joi.string().valid('attachment', 'inline').allow(false),
lookupCompressed: Joi.boolean(),
lookupMap: Joi.object().min(1).pattern(/.+/, Joi.string()),
etagMethod: Joi.string().valid('hash', 'simple').allow(false)
})
.with('filename', 'mode')
Expand Down Expand Up @@ -131,29 +137,33 @@ internals.prepare = function (response, callback) {

internals.marshal = function (response, next) {

if (!response.source.settings.lookupCompressed ||
!response.request.connection.settings.compression ||
response.request.info.acceptEncoding !== 'gzip') {
if (response.source.settings.lookupCompressed &&
response.request.connection.settings.compression) {

return internals.openStream(response, response.source.path, next);
}
const lookupMap = response.source.settings.lookupMap || internals.defaultMap;
const encoding = response.request.info.acceptEncoding;
const extension = lookupMap.hasOwnProperty(encoding) ? lookupMap[encoding] : null;
if (extension) {
const gzFile = `${response.source.path}${extension}`;
return internals.openStat(gzFile, 'r', (err, fd, stat) => {

const gzFile = response.source.path + '.gz';
internals.openStat(gzFile, 'r', (err, fd, stat) => {
if (err) {
return internals.openStream(response, response.source.path, next);
}

if (err) {
return internals.openStream(response, response.source.path, next);
}
internals.close(response);
response.source.fd = fd;

internals.close(response);
response.source.fd = fd;
response.bytes(stat.size);
response.header('content-encoding', encoding);
response.vary('accept-encoding');

response.bytes(stat.size);
response.header('content-encoding', 'gzip');
response.vary('accept-encoding');
return internals.openStream(response, gzFile, next);
});
}
}

return internals.openStream(response, gzFile, next);
});
return internals.openStream(response, response.source.path, next);
};


Expand Down
19 changes: 19 additions & 0 deletions test/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,25 @@ describe('file', () => {
});
});

it('returns a gzipped file using precompressed file using lookupMap', (done) => {

const content = Fs.readFileSync('./test/file/image.jpg#gz');
const lookupMap = { gzip: '#gz' };

const server = provisionServer();
server.route({ method: 'GET', path: '/file', handler: { file: { path: './test/file/image.jpg', lookupCompressed: true, lookupMap } } });

server.inject({ url: '/file', headers: { 'accept-encoding': 'gzip' } }, (res) => {

expect(res.statusCode).to.equal(200);
expect(res.headers['content-type']).to.equal('image/jpeg');
expect(res.headers['content-encoding']).to.equal('gzip');
expect(res.headers['content-length']).to.equal(content.length);
expect(res.rawPayload.length).to.equal(content.length);
done();
});
});

it('returns a gzipped file when precompressed file not found', (done) => {

const server = provisionServer();
Expand Down
Binary file added test/file/image.jpg#gz
Binary file not shown.

0 comments on commit a164a8f

Please sign in to comment.