Skip to content

Commit

Permalink
Merge f9ae8db into 0e2fe76
Browse files Browse the repository at this point in the history
  • Loading branch information
Sinewyk committed Mar 22, 2016
2 parents 0e2fe76 + f9ae8db commit 83eae74
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 4 deletions.
16 changes: 14 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ $ npm install koa-send

- `maxage` Browser cache max-age in milliseconds. defaults to 0
- `hidden` Allow transfer of hidden files. defaults to false
- `root` Root directory to restrict file access
- [`root`](#root-path) Root directory to restrict file access
- `gzip` Try to serve the gzipped version of a file automatically when `gzip` is supported by a client and if the requested file with `.gz` extension exists. defaults to true.
- `format` If not `false` (defaults to `true`), format the path to serve static file servers and not require a trailing slash for directories, so that you can do both `/directory` and `/directory/`
- [`setHeaders`](#setheaders) Function to set custom headers on response.

## Root path
### Root path

Note that `root` is required, defaults to `''` and will be resolved,
removing the leading `/` to make the path relative and this
Expand All @@ -48,6 +49,17 @@ app.use(function *(){
})
```

### setHeaders

The function is called as `fn(res, path, stats)`, where the arguments are:
* `res`: the response object
* `path`: the resolved file path that is being sent
* `stats`: the stats object of the file that is being sent.

You should only use the `setHeaders` option when you wish to edit the `Cache-Control` or `Last-Modified` headers, because doing it before is useless (it's overwritten by `send`), and doing it after is too late because the headers are already sent.

If you want to edit any other header, simply set them before calling `send`.

## Example (Koa@2) with async/await

```js
Expand Down
11 changes: 9 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ function send(ctx, path, opts) {
var hidden = opts.hidden || false;
var format = opts.format === false ? false : true;
var gzip = opts.gzip === false ? false : true;
var setHeaders = opts.setHeaders;

if (setHeaders && typeof setHeaders !== 'function') {
throw new TypeError('option setHeaders must be function')
}

var encoding = ctx.acceptsEncodings('gzip', 'deflate', 'identity');

Expand Down Expand Up @@ -94,10 +99,12 @@ function send(ctx, path, opts) {
throw err;
}

if (setHeaders) setHeaders(ctx.res, path, stats);

// stream
ctx.set('Last-Modified', stats.mtime.toUTCString());
ctx.set('Content-Length', stats.size);
ctx.set('Cache-Control', 'max-age=' + (maxage / 1000 | 0));
if (!ctx.response.get('Last-Modified')) ctx.set('Last-Modified', stats.mtime.toUTCString());
if (!ctx.response.get('Cache-Control')) ctx.set('Cache-Control', 'max-age=' + (maxage / 1000 | 0));
ctx.type = type(path);
ctx.body = fs.createReadStream(path);

Expand Down
79 changes: 79 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,85 @@ describe('send(ctx, file)', function(){
.end(done);
})

it('should set Last-Modified', function(done){
var app = koa();

app.use(function *(){
yield send(this, '/test/fixtures/user.json');
});

request(app.listen())
.get('/')
.expect('Last-Modified', /GMT/)
.end(done);
})

describe('with setHeaders', function() {
it('throws if setHeaders is not a function', function(done){
var app = koa();

app.use(function *(){
yield send(this, '/test/fixtures/user.json', {
setHeaders: 'foo'
});
});

request(app.listen())
.get('/')
.expect(500)
.end(done);
})

it('should not edit already set headers', function(done){
var app = koa();

var testFilePath = '/test/fixtures/user.json';
var normalizedTestFilePath = path.normalize(testFilePath);

app.use(function *(){
yield send(this, testFilePath, {
setHeaders: function(res, path, stats) {
assert.equal(path.substr(-normalizedTestFilePath.length), normalizedTestFilePath);
assert.equal(stats.size, 18);
assert(res);

// these can be set
res.setHeader('Cache-Control', 'max-age=0,must-revalidate');
res.setHeader('Last-Modified', 'foo')
// this one can not
res.setHeader('Content-Length', 9000)
}
});
});

request(app.listen())
.get('/')
.expect(200)
.expect('Cache-Control', 'max-age=0,must-revalidate')
.expect('Last-Modified', 'foo')
.expect('Content-Length', 18)
.end(done);
})

it('should correctly pass through regarding usual headers', function(done){
var app = koa();

app.use(function *(){
yield send(this, '/test/fixtures/user.json', {
setHeaders: function() {}
});
});

request(app.listen())
.get('/')
.expect(200)
.expect('Cache-Control', 'max-age=0')
.expect('Content-Length', 18)
.expect('Last-Modified', /GMT/)
.end(done);
})
})

it('should cleanup on socket error', function(done){
var app = koa();
var stream
Expand Down

0 comments on commit 83eae74

Please sign in to comment.