Skip to content

Commit

Permalink
Add support for transform option.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Barham committed Sep 29, 2015
1 parent 80cfa7f commit 67fd622
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 7 deletions.
34 changes: 31 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ with a dot, for backward-compatibility.

##### etag

Enable or disable etag generation, defaults to true.
Enable or disable etag generation.

Defaults to `true`, unless the `transform` option is set.

##### extensions

Expand All @@ -70,8 +72,10 @@ in preferred order.

##### lastModified

Enable or disable `Last-Modified` header, defaults to true. Uses the file
system's last modified value.
Enable or disable `Last-Modified` header. Uses the file system's last modified
value.

Defaults to `true`, unless the `transform` option is set.

##### maxAge

Expand All @@ -83,6 +87,30 @@ This can also be a string accepted by the

Serve files relative to `path`.

##### transform

A function that consumes the file stream and produces a new (transformed)
stream:

```javascript
function(stream) {return stream.pipe(replaceStream('tobi', 'peter'))}
```

Multiple transformations are possible:

```javascript
function(stream) {
return stream
.pipe(replaceStream('tobi', 'peter'))
.pipe(replaceStream('peter', 'hans'))
.pipe(...)
}
```

When a transform is specified, the `lastModified` and `etag` options default to
`false`, but can be overridden when a transform on the file's stream is expected
to always generate the same result.

### Events

The `SendStream` is an event emitter and will emit the following events:
Expand Down
18 changes: 15 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,13 @@ function SendStream(req, path, options) {
this.path = path
this.req = req

this._transform = typeof opts.transform === 'function'
? options.transform
: undefined

this._etag = opts.etag !== undefined
? Boolean(opts.etag)
: true
: (this._transform !== undefined ? false : true)

this._dotfiles = opts.dotfiles !== undefined
? opts.dotfiles
Expand Down Expand Up @@ -120,7 +124,7 @@ function SendStream(req, path, options) {

this._lastModified = opts.lastModified !== undefined
? Boolean(opts.lastModified)
: true
: (this._transform !== undefined ? false : true)

this._maxage = opts.maxAge || opts.maxage
this._maxage = typeof this._maxage === 'string'
Expand Down Expand Up @@ -592,7 +596,12 @@ SendStream.prototype.send = function(path, stat){
opts.end = Math.max(offset, offset + len - 1)

// content-length
res.setHeader('Content-Length', len);
if(this._transform === undefined){
res.setHeader('Content-Length', len);
} else {
//we don't know the content-length of the transformed data beforehand
res.setHeader('Transfer-Encoding', 'chunked');
}

// HEAD support
if ('HEAD' == req.method) return res.end();
Expand Down Expand Up @@ -691,6 +700,9 @@ SendStream.prototype.stream = function(path, options){
// pipe
var stream = fs.createReadStream(path, options);
this.emit('stream', stream);
if(this._transform !== undefined) {
stream = this._transform(stream);
}
stream.pipe(res);

// response finished, done with the fd
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"after": "0.8.1",
"istanbul": "0.3.9",
"mocha": "2.2.5",
"replacestream": "0.1.3",
"supertest": "1.0.1"
},
"files": [
Expand Down
47 changes: 46 additions & 1 deletion test/send.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ var assert = require('assert');
var fs = require('fs');
var http = require('http');
var path = require('path');
var replaceStream = require('replacestream');
var request = require('supertest');
var send = require('..')
var send = require('..');

// test server

Expand Down Expand Up @@ -1172,6 +1173,50 @@ describe('send(file, options)', function(){
})
})

describe('transform', function(){
it('should transform the file contents', function(done){
var app = http.createServer(function(req, res){
send(req, 'test/fixtures/name.txt', {transform: function(stream) {return stream.pipe(replaceStream('tobi', 'peter'))}})
.pipe(res)
});

request(app)
.get('/name.txt')
.expect(shouldNotHaveHeader('Last-Modified'))
.expect(shouldNotHaveHeader('ETag'))
.expect(200, "peter", done)
})

it('should be possible to do mulitple transformations', function(done){
var transformFunc = function(stream) {
return stream
.pipe(replaceStream('tobi', 'peter'))
.pipe(replaceStream('peter', 'hans'))
}

var app = http.createServer(function(req, res){
send(req, 'test/fixtures/name.txt', {transform: transformFunc})
.pipe(res)
});

request(app)
.get('/name.txt')
.expect(200, "hans", done)
})

it('should be able to override last modified', function(done){
var app = http.createServer(function(req, res){
send(req, 'test/fixtures/name.txt', {lastModified: true, transform: function(stream) {return stream.pipe(replaceStream('tobi', 'peter'))}})
.pipe(res)
});

request(app)
.get('/name.txt')
.expect('last-modified', dateRegExp)
.expect(200, "peter", done)
})
})

describe('root', function(){
describe('when given', function(){
it('should join root', function(done){
Expand Down

0 comments on commit 67fd622

Please sign in to comment.