fix content-length when body is re-assigned. Closes #267
This commit is contained in:
parent
5e3d7f0aa0
commit
48ac0669c5
3 changed files with 107 additions and 3 deletions
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
var ensureErrorHandler = require('error-inject');
|
||||
var isJSON = require('koa-is-json');
|
||||
var escape = require('escape-html');
|
||||
var onfinish = require('finished');
|
||||
var getType = require('set-type');
|
||||
|
@ -98,6 +99,7 @@ module.exports = {
|
|||
*/
|
||||
|
||||
set body(val) {
|
||||
var original = this._body;
|
||||
this._body = val;
|
||||
|
||||
// no content
|
||||
|
@ -133,11 +135,16 @@ module.exports = {
|
|||
if ('function' == typeof val.pipe) {
|
||||
onfinish(this, destroy.bind(null, val));
|
||||
ensureErrorHandler(val, this.ctx.onerror);
|
||||
|
||||
// overwriting
|
||||
if (null != original && original != val) this.remove('Content-Length');
|
||||
|
||||
if (setType) this.type = 'bin';
|
||||
return;
|
||||
}
|
||||
|
||||
// json
|
||||
this.remove('Content-Length');
|
||||
this.type = 'json';
|
||||
},
|
||||
|
||||
|
@ -166,7 +173,9 @@ module.exports = {
|
|||
if (null == len) {
|
||||
if (!body) return;
|
||||
if ('string' == typeof body) return Buffer.byteLength(body);
|
||||
return body.length;
|
||||
if (Buffer.isBuffer(body)) return body.length;
|
||||
if (isJSON(body)) return Buffer.byteLength(JSON.stringify(body));
|
||||
return;
|
||||
}
|
||||
|
||||
return ~~len;
|
||||
|
|
|
@ -565,11 +565,83 @@ describe('app.respond', function(){
|
|||
.end(function(err, res){
|
||||
if (err) return done(err);
|
||||
var pkg = require('../package');
|
||||
res.should.not.have.header('Content-Length');
|
||||
res.body.should.eql(pkg);
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
it('should strip content-length when overwriting', function(done){
|
||||
var app = koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = 'hello';
|
||||
this.body = fs.createReadStream('package.json');
|
||||
this.set('Content-Type', 'application/json');
|
||||
});
|
||||
|
||||
var server = app.listen();
|
||||
|
||||
request(server)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'application/json')
|
||||
.end(function(err, res){
|
||||
if (err) return done(err);
|
||||
var pkg = require('../package');
|
||||
res.should.not.have.header('Content-Length');
|
||||
res.body.should.eql(pkg);
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
it('should keep content-length if not overwritten', function(done){
|
||||
var app = koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.length = fs.readFileSync('package.json').length;
|
||||
this.body = fs.createReadStream('package.json');
|
||||
this.set('Content-Type', 'application/json');
|
||||
});
|
||||
|
||||
var server = app.listen();
|
||||
|
||||
request(server)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'application/json')
|
||||
.end(function(err, res){
|
||||
if (err) return done(err);
|
||||
var pkg = require('../package');
|
||||
res.should.have.header('Content-Length');
|
||||
res.body.should.eql(pkg);
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
it('should keep content-length if overwritten with the same stream', function(done){
|
||||
var app = koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.length = fs.readFileSync('package.json').length;
|
||||
var stream = fs.createReadStream('package.json');
|
||||
this.body = stream;
|
||||
this.body = stream;
|
||||
this.set('Content-Type', 'application/json');
|
||||
});
|
||||
|
||||
var server = app.listen();
|
||||
|
||||
request(server)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'application/json')
|
||||
.end(function(err, res){
|
||||
if (err) return done(err);
|
||||
var pkg = require('../package');
|
||||
res.should.have.header('Content-Length');
|
||||
res.body.should.eql(pkg);
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
it('should handle errors', function(done){
|
||||
var app = koa();
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
var fs = require('fs');
|
||||
var should = require('should');
|
||||
var response = require('../context').response;
|
||||
var assert = require('assert');
|
||||
|
||||
|
@ -27,10 +29,31 @@ describe('res.length', function(){
|
|||
var res = response();
|
||||
|
||||
res.body = 'foo';
|
||||
res.remove('Content-Length');
|
||||
res.length.should.equal(3);
|
||||
|
||||
res.body = new Buffer('foo');
|
||||
res.body = 'foo';
|
||||
res.length.should.equal(3);
|
||||
|
||||
res.body = new Buffer('foo bar');
|
||||
res.remove('Content-Length');
|
||||
res.length.should.equal(7);
|
||||
|
||||
res.body = new Buffer('foo bar');
|
||||
res.length.should.equal(7);
|
||||
|
||||
res.body = { hello: 'world' };
|
||||
res.remove('Content-Length');
|
||||
res.length.should.equal(17);
|
||||
|
||||
res.body = { hello: 'world' };
|
||||
res.length.should.equal(17);
|
||||
|
||||
res.body = fs.createReadStream('package.json');
|
||||
should.not.exist(res.length);
|
||||
|
||||
res.body = null;
|
||||
should.not.exist(res.length);
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -41,4 +64,4 @@ describe('res.length', function(){
|
|||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue