diff --git a/README.md b/README.md index ba9afb8..efd87d8 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ app.use(staticCache(path.join(__dirname, 'public'), { - `options.buffer` (bool) - store the files in memory instead of streaming from the filesystem on each request. - `options.gzip` (bool) - when request's accept-encoding include gzip, files will compressed by gzip. - `options.usePrecompiledGzip` (bool) - try use gzip files, loaded from disk, like nginx gzip_static +- `options.setHeaders` (function) - optional `function (ctx, file)` hook to set custom response headers for matched files. - `options.alias` (obj) - object map of aliases. See below. - `options.prefix` (str) - the url prefix you wish to add, default to `''`. - `options.dynamic` (bool) - dynamic load file which not cached on initialization. diff --git a/index.js b/index.js index 44cd7bb..5a84045 100644 --- a/index.js +++ b/index.js @@ -22,6 +22,9 @@ module.exports = function staticCache(dir, options, files) { dir = path.normalize(dir) var enableGzip = !!options.gzip var filePrefix = path.normalize(options.prefix.replace(/^\//, '')) + var setHeaders = typeof options.setHeaders === 'function' + ? options.setHeaders + : null // option.filter var fileFilter = function () { return true } @@ -99,6 +102,7 @@ module.exports = function staticCache(dir, options, files) { ctx.length = file.zipBuffer ? file.zipBuffer.length : file.length ctx.set('cache-control', file.cacheControl || 'public, max-age=' + file.maxAge) if (file.md5) ctx.set('content-md5', file.md5) + if (setHeaders) setHeaders(ctx, file) if (ctx.method === 'HEAD') return diff --git a/test/index.js b/test/index.js index ed74ace..e50388a 100644 --- a/test/index.js +++ b/test/index.js @@ -250,6 +250,59 @@ describe('Static Cache', function () { .expect(200, done) }) + it('should set custom headers for streamed files', function (done) { + var app = new Koa() + var seenFile + app.use(staticCache(path.join(__dirname, '..'), { + setHeaders: function (ctx, file) { + seenFile = file + ctx.set('X-Static-Cache', file.type) + }, + filter(file) { + return !file.includes('node_modules') + } + })) + + request(app.listen()) + .get('/index.js') + .expect('X-Static-Cache', /javascript/) + .expect(200, function (err) { + if (err) + return done(err) + + seenFile.type.should.match(/javascript/) + seenFile.path.should.endWith('index.js') + done() + }) + }) + + it('should set custom headers for buffered files', function (done) { + var app = new Koa() + var seenFile + app.use(staticCache(path.join(__dirname, '..'), { + buffer: true, + setHeaders: function (ctx, file) { + seenFile = file + ctx.set('X-Static-Length', String(file.length)) + }, + filter(file) { + return !file.includes('node_modules') + } + })) + + request(app.listen()) + .get('/index.js') + .expect('X-Static-Length', String(fs.statSync('index.js').size)) + .expect(200, function (err) { + if (err) + return done(err) + + should.exist(seenFile.buffer) + seenFile.path.should.endWith('index.js') + done() + }) + }) + it('should set Last-Modified if file modified and not buffered', function (done) { setTimeout(function () { var readme = fs.readFileSync('README.md', 'utf8')