2016-03-04 03:57:52 +00:00
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const request = require('supertest');
|
|
|
|
const assert = require('assert');
|
|
|
|
const Koa = require('../..');
|
2016-08-10 19:15:48 +00:00
|
|
|
const http = require('http');
|
2016-03-04 03:57:52 +00:00
|
|
|
|
|
|
|
describe('ctx.flushHeaders()', () => {
|
2017-05-11 03:30:32 +00:00
|
|
|
it('should set headersSent', () => {
|
2016-03-04 03:57:52 +00:00
|
|
|
const app = new Koa();
|
|
|
|
|
|
|
|
app.use((ctx, next) => {
|
|
|
|
ctx.body = 'Body';
|
|
|
|
ctx.status = 200;
|
|
|
|
ctx.flushHeaders();
|
2017-05-11 03:30:32 +00:00
|
|
|
assert.equal(ctx.res.headersSent, true);
|
2016-03-04 03:57:52 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
const server = app.listen();
|
|
|
|
|
2017-05-11 03:30:32 +00:00
|
|
|
return request(server)
|
2016-03-04 03:57:52 +00:00
|
|
|
.get('/')
|
|
|
|
.expect(200)
|
2017-05-11 03:30:32 +00:00
|
|
|
.expect('Body');
|
2016-03-04 03:57:52 +00:00
|
|
|
});
|
|
|
|
|
2017-05-11 03:30:32 +00:00
|
|
|
it('should allow a response afterwards', () => {
|
2016-03-04 03:57:52 +00:00
|
|
|
const app = new Koa();
|
|
|
|
|
|
|
|
app.use((ctx, next) => {
|
|
|
|
ctx.status = 200;
|
|
|
|
ctx.res.setHeader('Content-Type', 'text/plain');
|
|
|
|
ctx.flushHeaders();
|
|
|
|
ctx.body = 'Body';
|
|
|
|
});
|
|
|
|
|
|
|
|
const server = app.listen();
|
2017-05-11 03:30:32 +00:00
|
|
|
return request(server)
|
2016-03-04 03:57:52 +00:00
|
|
|
.get('/')
|
|
|
|
.expect(200)
|
|
|
|
.expect('Content-Type', 'text/plain')
|
2017-05-11 03:30:32 +00:00
|
|
|
.expect('Body');
|
2016-03-04 03:57:52 +00:00
|
|
|
});
|
|
|
|
|
2017-05-11 03:30:32 +00:00
|
|
|
it('should send the correct status code', () => {
|
2016-03-04 03:57:52 +00:00
|
|
|
const app = new Koa();
|
|
|
|
|
|
|
|
app.use((ctx, next) => {
|
|
|
|
ctx.status = 401;
|
|
|
|
ctx.res.setHeader('Content-Type', 'text/plain');
|
|
|
|
ctx.flushHeaders();
|
|
|
|
ctx.body = 'Body';
|
|
|
|
});
|
|
|
|
|
|
|
|
const server = app.listen();
|
2017-05-11 03:30:32 +00:00
|
|
|
return request(server)
|
2016-03-04 03:57:52 +00:00
|
|
|
.get('/')
|
|
|
|
.expect(401)
|
|
|
|
.expect('Content-Type', 'text/plain')
|
2017-05-11 03:30:32 +00:00
|
|
|
.expect('Body');
|
2016-03-04 03:57:52 +00:00
|
|
|
});
|
|
|
|
|
2018-02-11 08:25:24 +00:00
|
|
|
it('should ignore set header after flushHeaders', async () => {
|
2016-03-04 03:57:52 +00:00
|
|
|
const app = new Koa();
|
|
|
|
|
|
|
|
app.use((ctx, next) => {
|
|
|
|
ctx.status = 401;
|
|
|
|
ctx.res.setHeader('Content-Type', 'text/plain');
|
|
|
|
ctx.flushHeaders();
|
2018-02-11 08:25:24 +00:00
|
|
|
ctx.body = 'foo';
|
|
|
|
ctx.set('X-Shouldnt-Work', 'Value');
|
|
|
|
ctx.remove('Content-Type');
|
|
|
|
ctx.vary('Content-Type');
|
2016-03-04 03:57:52 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
const server = app.listen();
|
2017-05-11 03:30:32 +00:00
|
|
|
const res = await request(server)
|
2016-03-04 03:57:52 +00:00
|
|
|
.get('/')
|
|
|
|
.expect(401)
|
2018-02-11 08:25:24 +00:00
|
|
|
.expect('Content-Type', 'text/plain');
|
2017-05-11 03:30:32 +00:00
|
|
|
|
|
|
|
assert.equal(res.headers['x-shouldnt-work'], undefined, 'header set after flushHeaders');
|
2018-02-11 08:25:24 +00:00
|
|
|
assert.equal(res.headers.vary, undefined, 'header set after flushHeaders');
|
2016-03-04 03:57:52 +00:00
|
|
|
});
|
2016-08-10 19:15:48 +00:00
|
|
|
|
|
|
|
it('should flush headers first and delay to send data', done => {
|
|
|
|
const PassThrough = require('stream').PassThrough;
|
|
|
|
const app = new Koa();
|
|
|
|
|
|
|
|
app.use(ctx => {
|
|
|
|
ctx.type = 'json';
|
|
|
|
ctx.status = 200;
|
|
|
|
ctx.headers['Link'] = '</css/mycss.css>; as=style; rel=preload, <https://img.craftflair.com>; rel=preconnect; crossorigin';
|
|
|
|
const stream = ctx.body = new PassThrough();
|
|
|
|
ctx.flushHeaders();
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
stream.end(JSON.stringify({ message: 'hello!' }));
|
|
|
|
}, 10000);
|
|
|
|
});
|
|
|
|
|
|
|
|
app.listen(function(err){
|
|
|
|
if (err) return done(err);
|
|
|
|
|
|
|
|
const port = this.address().port;
|
|
|
|
|
|
|
|
http.request({
|
|
|
|
port
|
|
|
|
})
|
|
|
|
.on('response', res => {
|
|
|
|
const onData = () => done(new Error('boom'));
|
|
|
|
res.on('data', onData);
|
|
|
|
|
|
|
|
// shouldn't receive any data for a while
|
|
|
|
setTimeout(() => {
|
|
|
|
res.removeListener('data', onData);
|
|
|
|
done();
|
|
|
|
}, 1000);
|
|
|
|
})
|
|
|
|
.on('error', done)
|
|
|
|
.end();
|
|
|
|
});
|
|
|
|
});
|
2018-02-11 08:25:24 +00:00
|
|
|
|
|
|
|
it('should catch stream error', done => {
|
|
|
|
const PassThrough = require('stream').PassThrough;
|
|
|
|
const app = new Koa();
|
|
|
|
app.once('error', err => {
|
|
|
|
assert(err.message === 'mock error');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
|
|
|
|
app.use(ctx => {
|
|
|
|
ctx.type = 'json';
|
|
|
|
ctx.status = 200;
|
|
|
|
ctx.headers['Link'] = '</css/mycss.css>; as=style; rel=preload, <https://img.craftflair.com>; rel=preconnect; crossorigin';
|
|
|
|
ctx.length = 20;
|
|
|
|
ctx.flushHeaders();
|
|
|
|
const stream = ctx.body = new PassThrough();
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
stream.emit('error', new Error('mock error'));
|
|
|
|
}, 100);
|
|
|
|
});
|
|
|
|
|
|
|
|
const server = app.listen();
|
|
|
|
|
|
|
|
request(server).get('/').end();
|
|
|
|
});
|
2016-03-04 03:57:52 +00:00
|
|
|
});
|