Skip to content

Commit 183decd

Browse files
author
a.habannakeh
committed
Merge branch 'master' of https://github.com/peterbartels/send
2 parents acefad9 + f8fd84f commit 183decd

File tree

3 files changed

+116
-19
lines changed

3 files changed

+116
-19
lines changed

README.md

+26-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ the 4th byte in the stream.
7676

7777
##### etag
7878

79-
Enable or disable etag generation, defaults to true.
79+
Enable or disable etag generation, defaults to `true` unless the transform options is set.
8080

8181
##### extensions
8282

@@ -101,9 +101,11 @@ in preferred order.
101101

102102
##### lastModified
103103

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

107+
If the `transform` option is set then the default is `false`.
108+
107109
##### maxAge
108110

109111
Provide a max-age in milliseconds for http caching, defaults to 0.
@@ -120,6 +122,28 @@ Byte offset at which the stream starts, defaults to 0. The start is inclusive,
120122
meaning `start: 2` will include the 3rd byte in the stream.
121123

122124
#### Events
125+
=======
126+
##### Transform
127+
128+
A function that consumes the file stream and produces a new (transformed) stream:
129+
```javascript
130+
function(stream) {return stream.pipe(replaceStream('tobi', 'peter'))}
131+
```
132+
133+
Multiple transformations are possible:
134+
```javascript
135+
function(stream) {
136+
return stream
137+
.pipe(replaceStream('tobi', 'peter'))
138+
.pipe(replaceStream('peter', 'hans'))
139+
.pipe(...)
140+
}
141+
```
142+
143+
With transform the last-modified and etag defaults to `false` but can be overridden when
144+
a transform on the file's stream is expected to always generate the same result.
145+
146+
### Events
123147

124148
The `SendStream` is an event emitter and will emit the following events:
125149

index.js

+34-11
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,14 @@ function send (req, path, options) {
9696
function SendStream (req, path, options) {
9797
Stream.call(this)
9898

99-
var opts = options || {}
10099

101-
this.options = opts
102-
this.path = path
103-
this.req = req
100+
this._transform = typeof options.transform === 'function'
101+
? options.transform
102+
: undefined
104103

105-
this._acceptRanges = opts.acceptRanges !== undefined
106-
? Boolean(opts.acceptRanges)
107-
: true
108-
109-
this._cacheControl = opts.cacheControl !== undefined
110-
? Boolean(opts.cacheControl)
111-
: true
104+
this._etag = options.etag !== undefined
105+
? Boolean(options.etag)
106+
: (this._transform !== undefined ? false : true)
112107

113108
this._etag = opts.etag !== undefined
114109
? Boolean(opts.etag)
@@ -145,9 +140,15 @@ function SendStream (req, path, options) {
145140
? normalizeList(opts.index, 'index option')
146141
: ['index.html']
147142

143+
<<<<<<< HEAD
148144
this._lastModified = opts.lastModified !== undefined
149145
? Boolean(opts.lastModified)
150146
: true
147+
=======
148+
this._lastModified = options.lastModified !== undefined
149+
? Boolean(options.lastModified)
150+
: (this._transform !== undefined ? false : true)
151+
>>>>>>> f8fd84f270e1e1afb969e75d63e57a63f9d17141
151152

152153
this._maxage = opts.maxAge || opts.maxage
153154
this._maxage = typeof this._maxage === 'string'
@@ -696,7 +697,16 @@ SendStream.prototype.send = function send (path, stat) {
696697
opts.end = Math.max(offset, offset + len - 1)
697698

698699
// content-length
700+
<<<<<<< HEAD
699701
res.setHeader('Content-Length', len)
702+
=======
703+
if(this._transform === undefined){
704+
res.setHeader('Content-Length', len);
705+
}else{
706+
//we don't know the content-length of the transformed data beforehand
707+
res.setHeader('Transfer-Encoding', 'chunked');
708+
}
709+
>>>>>>> f8fd84f270e1e1afb969e75d63e57a63f9d17141
700710

701711
// HEAD support
702712
if (req.method === 'HEAD') {
@@ -793,10 +803,23 @@ SendStream.prototype.stream = function stream (path, options) {
793803
var res = this.res
794804

795805
// pipe
806+
<<<<<<< HEAD
796807
var stream = fs.createReadStream(path, options)
797808
this.emit('stream', stream)
798809
stream.pipe(res)
799810

811+
=======
812+
var stream = fs.createReadStream(path, options);
813+
814+
this.emit('stream', stream);
815+
816+
if(this._transform !== undefined){
817+
stream = this._transform(stream);
818+
}
819+
820+
stream.pipe(res);
821+
822+
>>>>>>> f8fd84f270e1e1afb969e75d63e57a63f9d17141
800823
// response finished, done with the fd
801824
onFinished(res, function onfinished () {
802825
finished = true

test/send.js

+56-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ var http = require('http')
88
var path = require('path')
99
var request = require('supertest')
1010
var send = require('..')
11+
var replaceStream = require('replacestream')
1112

1213
// test server
1314

@@ -1317,12 +1318,61 @@ describe('send(file, options)', function () {
13171318
})
13181319
})
13191320

1320-
describe('root', function () {
1321-
describe('when given', function () {
1322-
it('should join root', function (done) {
1323-
request(createServer({ root: fixtures }))
1324-
.get('/pets/../name.txt')
1325-
.expect(200, 'tobi', done)
1321+
describe('transform', function(){
1322+
it('should transform the file contents', function(done){
1323+
var app = http.createServer(function(req, res){
1324+
send(req, 'test/fixtures/name.txt', {transform: function(stream) {return stream.pipe(replaceStream('tobi', 'peter'))}})
1325+
.pipe(res)
1326+
});
1327+
1328+
request(app)
1329+
.get('/name.txt')
1330+
.expect(shouldNotHaveHeader('Last-Modified'))
1331+
.expect(shouldNotHaveHeader('ETag'))
1332+
.expect(200, "peter", done)
1333+
})
1334+
1335+
it('should be possible to do mulitple transformations', function(done){
1336+
var transformFunc = function(stream) {
1337+
return stream
1338+
.pipe(replaceStream('tobi', 'peter'))
1339+
.pipe(replaceStream('peter', 'hans'))
1340+
}
1341+
1342+
var app = http.createServer(function(req, res){
1343+
send(req, 'test/fixtures/name.txt', {transform: transformFunc})
1344+
.pipe(res)
1345+
});
1346+
1347+
request(app)
1348+
.get('/name.txt')
1349+
.expect(200, "hans", done)
1350+
})
1351+
1352+
it('should be able to override last modified', function(done){
1353+
var app = http.createServer(function(req, res){
1354+
send(req, 'test/fixtures/name.txt', {lastModified: true, transform: function(stream) {return stream.pipe(replaceStream('tobi', 'peter'))}})
1355+
.pipe(res)
1356+
});
1357+
1358+
request(app)
1359+
.get('/name.txt')
1360+
.expect('last-modified', dateRegExp)
1361+
.expect(200, "peter", done)
1362+
})
1363+
})
1364+
1365+
describe('root', function(){
1366+
describe('when given', function(){
1367+
it('should join root', function(done){
1368+
var app = http.createServer(function(req, res){
1369+
send(req, req.url, {root: __dirname + '/fixtures'})
1370+
.pipe(res);
1371+
});
1372+
1373+
request(app)
1374+
.get('/pets/../name.txt')
1375+
.expect(200, 'tobi', done)
13261376
})
13271377

13281378
it('should work with trailing slash', function (done) {

0 commit comments

Comments
 (0)