diff --git a/lib/response.js b/lib/response.js index 21a8b7f..a51d661 100644 --- a/lib/response.js +++ b/lib/response.js @@ -79,6 +79,8 @@ module.exports = { */ set status(code) { + if (this.headerSent) return; + assert('number' == typeof code, 'status code must be a number'); assert(statuses[code], 'invalid status code: ' + code); this._explicitStatus = true; @@ -229,6 +231,8 @@ module.exports = { */ vary: function(field){ + if (this.headerSent) return; + vary(this.res, field); }, @@ -430,6 +434,8 @@ module.exports = { */ set: function(field, val){ + if (this.headerSent) return; + if (2 == arguments.length) { if (Array.isArray(val)) val = val.map(String); else val = String(val); @@ -475,6 +481,8 @@ module.exports = { */ remove: function(field){ + if (this.headerSent) return; + this.res.removeHeader(field); }, diff --git a/test/response/remove.js b/test/response/remove.js index b74c46d..723ffdf 100644 --- a/test/response/remove.js +++ b/test/response/remove.js @@ -2,6 +2,7 @@ 'use strict'; var context = require('../context'); +var should = require('should'); describe('ctx.remove(name)', function(){ it('should remove a field', function(){ @@ -10,4 +11,14 @@ describe('ctx.remove(name)', function(){ ctx.remove('x-foo'); ctx.response.header.should.eql({}); }) + + describe('after header sent', function(){ + it('should ignore', function(){ + var ctx = context(); + ctx.set('foo', 'bar'); + ctx.res.headersSent = true; + ctx.remove('foo', 'bar'); + ctx.response.header.foo.should.equal('bar'); + }) + }) }) diff --git a/test/response/set.js b/test/response/set.js index 45a304a..a12ab8f 100644 --- a/test/response/set.js +++ b/test/response/set.js @@ -2,6 +2,7 @@ 'use strict'; var context = require('../context'); +var should = require('should'); describe('ctx.set(name, val)', function(){ it('should set a field value', function(){ @@ -21,6 +22,14 @@ describe('ctx.set(name, val)', function(){ ctx.set('x-foo', ['foo', 'bar']); ctx.response.header['x-foo'].should.eql([ 'foo', 'bar' ]); }) + + describe('after header sent', function(){ + it('should ignore', function(){ + var ctx = context(null, { headersSent: true }); + ctx.set('foo', 'bar'); + should.not.exist(ctx.response.header.foo); + }) + }) }) describe('ctx.set(object)', function(){ diff --git a/test/response/status.js b/test/response/status.js index 744a6d9..50abb58 100644 --- a/test/response/status.js +++ b/test/response/status.js @@ -5,6 +5,7 @@ var response = require('../context').response; var request = require('supertest'); var statuses = require('statuses'); var assert = require('assert'); +var should = require('should'); var koa = require('../..'); describe('res.status=', function(){ @@ -50,6 +51,14 @@ describe('res.status=', function(){ }) }) + describe('after header sent', function(){ + it('should ignore', function(){ + var res = response(null, { headersSent: true }); + res.status = 200; + should.not.exist(res.status); + }) + }) + describe('when a status string', function(){ it('should throw', function(){ assert.throws(function() { diff --git a/test/response/vary.js b/test/response/vary.js index 2dcb314..9520f49 100644 --- a/test/response/vary.js +++ b/test/response/vary.js @@ -2,6 +2,7 @@ 'use strict'; var context = require('../context'); +var should = require('should'); describe('ctx.vary(field)', function(){ describe('when Vary is not set', function(){ @@ -31,4 +32,12 @@ describe('ctx.vary(field)', function(){ ctx.response.header.vary.should.equal('Accept, Accept-Encoding'); }) }) + + describe('after header sent', function(){ + it('should ignore', function(){ + var ctx = context(null, { headersSent: true }); + ctx.vary('Accept'); + should.not.exist(ctx.response.header.vary); + }) + }) })