fix content-length when body is re-assigned. Closes #267

This commit is contained in:
dead_horse 2014-04-28 20:34:26 -07:00 committed by TJ Holowaychuk
parent 5e3d7f0aa0
commit 48ac0669c5
3 changed files with 107 additions and 3 deletions

View file

@ -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;

View file

@ -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();

View file

@ -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);
})
})