Skip to content

Commit 64be0b1

Browse files
committed
Fix res.end patch to call correct upstream res.write
fixes #72
1 parent c5c1ac8 commit 64be0b1

File tree

3 files changed

+88
-21
lines changed

3 files changed

+88
-21
lines changed

History.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
unreleased
2+
==========
3+
4+
* Fix `res.end` patch to call correct upstream `res.write`
5+
16
1.7.2 / 2014-07-27
27
==================
38

index.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,10 @@ function session(options){
179179
});
180180

181181
// proxy end() to commit the session
182-
var end = res.end;
182+
var _end = res.end;
183+
var _write = res.write;
183184
var ended = false;
184-
res.end = function(chunk, encoding){
185+
res.end = function end(chunk, encoding) {
185186
if (ended) {
186187
return false;
187188
}
@@ -206,16 +207,16 @@ function session(options){
206207
debug('destroyed');
207208

208209
if (sync) {
209-
ret = end.call(res, chunk, encoding);
210+
ret = _end.call(res, chunk, encoding);
210211
sync = false;
211212
return;
212213
}
213214

214-
end.call(res);
215+
_end.call(res);
215216
});
216217

217218
if (sync) {
218-
ret = res.write(chunk, encoding);
219+
ret = _write.call(res, chunk, encoding);
219220
sync = false;
220221
}
221222

@@ -225,7 +226,7 @@ function session(options){
225226
// no session to save
226227
if (!req.session) {
227228
debug('no session');
228-
return end.call(res, chunk, encoding);
229+
return _end.call(res, chunk, encoding);
229230
}
230231

231232
req.session.resetMaxAge();
@@ -240,23 +241,23 @@ function session(options){
240241
debug('saved');
241242

242243
if (sync) {
243-
ret = end.call(res, chunk, encoding);
244+
ret = _end.call(res, chunk, encoding);
244245
sync = false;
245246
return;
246247
}
247248

248-
end.call(res);
249+
_end.call(res);
249250
});
250251

251252
if (sync) {
252-
ret = res.write(chunk, encoding);
253+
ret = _write.call(res, chunk, encoding);
253254
sync = false;
254255
}
255256

256257
return ret;
257258
}
258259

259-
return end.call(res, chunk, encoding);
260+
return _end.call(res, chunk, encoding);
260261
};
261262

262263
// generate the session

test/session.js

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,40 @@ describe('session()', function(){
937937
})
938938
});
939939

940+
describe('res.end patch', function () {
941+
it('should correctly handle res.end/res.write patched prior', function (done) {
942+
var app = express()
943+
944+
app.use(writePatch())
945+
app.use(createSession())
946+
app.use(function (req, res) {
947+
req.session.hit = true
948+
res.write('hello, ')
949+
res.end('world')
950+
})
951+
952+
request(app)
953+
.get('/')
954+
.expect(200, 'hello, world', done)
955+
})
956+
957+
it('should correctly handle res.end/res.write patched after', function (done) {
958+
var app = express()
959+
960+
app.use(createSession())
961+
app.use(writePatch())
962+
app.use(function (req, res) {
963+
req.session.hit = true
964+
res.write('hello, ')
965+
res.end('world')
966+
})
967+
968+
request(app)
969+
.get('/')
970+
.expect(200, 'hello, world', done)
971+
})
972+
})
973+
940974
describe('req.session', function(){
941975
it('should persist', function(done){
942976
var store = new session.MemoryStore()
@@ -1584,19 +1618,9 @@ function cookie(res) {
15841618
}
15851619

15861620
function createServer(opts, fn) {
1587-
var options = opts || {}
1621+
var _session = createSession(opts)
15881622
var respond = fn || end
15891623

1590-
if (!('cookie' in options)) {
1591-
options.cookie = { maxAge: 60 * 1000 }
1592-
}
1593-
1594-
if (!('secret' in options)) {
1595-
options.secret = 'keyboard cat'
1596-
}
1597-
1598-
var _session = session(options)
1599-
16001624
var server = http.createServer(function (req, res) {
16011625
_session(req, res, function (err) {
16021626
if (err && !res._header) {
@@ -1617,6 +1641,20 @@ function createServer(opts, fn) {
16171641
return server
16181642
}
16191643

1644+
function createSession(opts) {
1645+
var options = opts || {}
1646+
1647+
if (!('cookie' in options)) {
1648+
options.cookie = { maxAge: 60 * 1000 }
1649+
}
1650+
1651+
if (!('secret' in options)) {
1652+
options.secret = 'keyboard cat'
1653+
}
1654+
1655+
return session(options)
1656+
}
1657+
16201658
function end(req, res) {
16211659
res.end()
16221660
}
@@ -1632,6 +1670,29 @@ function sid(res) {
16321670
return val
16331671
}
16341672

1673+
function writePatch() {
1674+
var ended = false
1675+
return function addWritePatch(req, res, next) {
1676+
var _end = res.end
1677+
var _write = res.write
1678+
1679+
res.end = function end() {
1680+
ended = true
1681+
return _end.apply(this, arguments)
1682+
}
1683+
1684+
res.write = function write() {
1685+
if (ended) {
1686+
throw new Error('write after end')
1687+
}
1688+
1689+
return _write.apply(this, arguments)
1690+
}
1691+
1692+
next()
1693+
}
1694+
}
1695+
16351696
function SyncStore() {
16361697
this.sessions = Object.create(null);
16371698
}

0 commit comments

Comments
 (0)