res: use http.ServerResponse._header when accessors exist (#930)
* 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
This commit is contained in:
parent
188c0968e1
commit
e9d7abaf79
4 changed files with 58 additions and 3 deletions
|
@ -121,8 +121,16 @@ const proto = module.exports = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unset all headers, and set those specified
|
const { res } = this;
|
||||||
this.res._headers = {};
|
|
||||||
|
// 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);
|
this.set(err.headers);
|
||||||
|
|
||||||
// force text/plain
|
// force text/plain
|
||||||
|
|
|
@ -44,7 +44,10 @@ module.exports = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
get header() {
|
get header() {
|
||||||
return this.res._headers || {};
|
const { res } = this;
|
||||||
|
return typeof res.getHeaders === 'function'
|
||||||
|
? res.getHeaders()
|
||||||
|
: res._headers || {}; // Node < 7.7
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
const request = require('supertest');
|
const request = require('supertest');
|
||||||
const Koa = require('../..');
|
const Koa = require('../..');
|
||||||
|
const context = require('../helpers/context');
|
||||||
|
|
||||||
describe('ctx.onerror(err)', () => {
|
describe('ctx.onerror(err)', () => {
|
||||||
it('should respond', done => {
|
it('should respond', done => {
|
||||||
|
@ -169,5 +171,23 @@ describe('ctx.onerror(err)', () => {
|
||||||
.expect('Content-Type', 'text/plain; charset=utf-8')
|
.expect('Content-Type', 'text/plain; charset=utf-8')
|
||||||
.expect('Internal Server Error', done);
|
.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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const request = require('supertest');
|
||||||
const response = require('../helpers/context').response;
|
const response = require('../helpers/context').response;
|
||||||
|
const Koa = require('../..');
|
||||||
|
|
||||||
describe('res.header', () => {
|
describe('res.header', () => {
|
||||||
it('should return the response header object', () => {
|
it('should return the response header object', () => {
|
||||||
|
@ -10,6 +12,28 @@ describe('res.header', () => {
|
||||||
res.header.should.eql({ 'x-foo': 'bar' });
|
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', () => {
|
describe('when res._headers not present', () => {
|
||||||
it('should return empty object', () => {
|
it('should return empty object', () => {
|
||||||
const res = response();
|
const res = response();
|
||||||
|
|
Loading…
Reference in a new issue