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 ensureErrorHandler = require('error-inject');
|
||||||
|
var isJSON = require('koa-is-json');
|
||||||
var escape = require('escape-html');
|
var escape = require('escape-html');
|
||||||
var onfinish = require('finished');
|
var onfinish = require('finished');
|
||||||
var getType = require('set-type');
|
var getType = require('set-type');
|
||||||
|
@ -98,6 +99,7 @@ module.exports = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
set body(val) {
|
set body(val) {
|
||||||
|
var original = this._body;
|
||||||
this._body = val;
|
this._body = val;
|
||||||
|
|
||||||
// no content
|
// no content
|
||||||
|
@ -133,11 +135,16 @@ module.exports = {
|
||||||
if ('function' == typeof val.pipe) {
|
if ('function' == typeof val.pipe) {
|
||||||
onfinish(this, destroy.bind(null, val));
|
onfinish(this, destroy.bind(null, val));
|
||||||
ensureErrorHandler(val, this.ctx.onerror);
|
ensureErrorHandler(val, this.ctx.onerror);
|
||||||
|
|
||||||
|
// overwriting
|
||||||
|
if (null != original && original != val) this.remove('Content-Length');
|
||||||
|
|
||||||
if (setType) this.type = 'bin';
|
if (setType) this.type = 'bin';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// json
|
// json
|
||||||
|
this.remove('Content-Length');
|
||||||
this.type = 'json';
|
this.type = 'json';
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -166,7 +173,9 @@ module.exports = {
|
||||||
if (null == len) {
|
if (null == len) {
|
||||||
if (!body) return;
|
if (!body) return;
|
||||||
if ('string' == typeof body) return Buffer.byteLength(body);
|
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;
|
return ~~len;
|
||||||
|
|
|
@ -565,11 +565,83 @@ describe('app.respond', function(){
|
||||||
.end(function(err, res){
|
.end(function(err, res){
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
var pkg = require('../package');
|
var pkg = require('../package');
|
||||||
|
res.should.not.have.header('Content-Length');
|
||||||
res.body.should.eql(pkg);
|
res.body.should.eql(pkg);
|
||||||
done();
|
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){
|
it('should handle errors', function(done){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
|
||||||
|
var fs = require('fs');
|
||||||
|
var should = require('should');
|
||||||
var response = require('../context').response;
|
var response = require('../context').response;
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
|
|
||||||
|
@ -27,10 +29,31 @@ describe('res.length', function(){
|
||||||
var res = response();
|
var res = response();
|
||||||
|
|
||||||
res.body = 'foo';
|
res.body = 'foo';
|
||||||
|
res.remove('Content-Length');
|
||||||
res.length.should.equal(3);
|
res.length.should.equal(3);
|
||||||
|
|
||||||
res.body = new Buffer('foo');
|
res.body = 'foo';
|
||||||
res.length.should.equal(3);
|
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