Skip to content

Commit

Permalink
res: use http.ServerResponse._header when accessors exist (#930)
Browse files Browse the repository at this point in the history
* Don't use http.ServerResponse._header when accessors exist

Structure of http.ServerResponse._header will change in future
Node versions. Avoid reading and setting it directly when
helpers exist.

* Add new header test case

* make things a little more strict
  • Loading branch information
jonathanong authored Mar 8, 2017
1 parent 188c096 commit e9d7aba
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 3 deletions.
12 changes: 10 additions & 2 deletions lib/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,16 @@ const proto = module.exports = {
return;
}

// unset all headers, and set those specified
this.res._headers = {};
const { res } = this;

// first unset all headers
if (typeof res.getHeaderNames === 'function') {
res.getHeaderNames().forEach(name => res.removeHeader(name));
} else {
res._headers = {}; // Node < 7.7
}

// then set those specified
this.set(err.headers);

// force text/plain
Expand Down
5 changes: 4 additions & 1 deletion lib/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ module.exports = {
*/

get header() {
return this.res._headers || {};
const { res } = this;
return typeof res.getHeaders === 'function'
? res.getHeaders()
: res._headers || {}; // Node < 7.7
},

/**
Expand Down
20 changes: 20 additions & 0 deletions test/context/onerror.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@

'use strict';

const assert = require('assert');
const request = require('supertest');
const Koa = require('../..');
const context = require('../helpers/context');

describe('ctx.onerror(err)', () => {
it('should respond', done => {
Expand Down Expand Up @@ -169,5 +171,23 @@ describe('ctx.onerror(err)', () => {
.expect('Content-Type', 'text/plain; charset=utf-8')
.expect('Internal Server Error', done);
});

it('should use res.getHeaderNames() accessor when available', () => {
let removed = 0;
const ctx = context();

ctx.app.emit = () => {};
ctx.res = {
getHeaderNames: () => ['content-type', 'content-length'],
removeHeader: () => removed++,
end: () => {},
emit: () => {}
};

ctx.onerror(new Error('error'));

assert.equal(removed, 2);
});
});
});

24 changes: 24 additions & 0 deletions test/response/header.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

'use strict';

const request = require('supertest');
const response = require('../helpers/context').response;
const Koa = require('../..');

describe('res.header', () => {
it('should return the response header object', () => {
Expand All @@ -10,6 +12,28 @@ describe('res.header', () => {
res.header.should.eql({ 'x-foo': 'bar' });
});

it('should use res.getHeaders() accessor when available', () => {
const res = response();
res.res._headers = null;
res.res.getHeaders = () => ({ 'x-foo': 'baz' });
res.header.should.eql({ 'x-foo': 'baz' });
});

it('should return the response header object when no mocks are in use', async () => {
const app = new Koa();
let header;

app.use(ctx => {
ctx.set('x-foo', '42');
header = Object.assign({}, ctx.response.header);
});

await request(app.listen())
.get('/');

header.should.eql({ 'x-foo': '42' });
});

describe('when res._headers not present', () => {
it('should return empty object', () => {
const res = response();
Expand Down

2 comments on commit e9d7aba

@yufan-zhao
Copy link

@yufan-zhao yufan-zhao commented on e9d7aba May 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`......\node_modules\koa\lib\response.js:47
 const { res } = this;
       ^

 SyntaxError: Unexpected token {
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:373:25)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (......\node_modules\koa\lib\application.js:11:18)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)`

node version: v4.4.7

@PlasmaPower
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yufan-zhao only Node versions 6 and above are supported with Koa 2.0.

Please sign in to comment.