Skip to content

Commit

Permalink
Support node v14
Browse files Browse the repository at this point in the history
  • Loading branch information
hueniverse committed Apr 25, 2020
1 parent fa76016 commit 6f3e08d
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 131 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -2,6 +2,7 @@ language: node_js

node_js:
- "12"
- "14"
- "node"

sudo: false
Expand Down
17 changes: 2 additions & 15 deletions lib/response.js
Expand Up @@ -574,14 +574,6 @@ exports = module.exports = internals.Response = class {
// Stream source

if (Streams.isStream(source)) {
if (typeof source._read !== 'function') {
throw Boom.badImplementation('Stream must have a readable interface');
}

if (source._readableState.objectMode) {
throw Boom.badImplementation('Cannot reply with stream in object mode');
}

this._payload = source;
return;
}
Expand Down Expand Up @@ -669,18 +661,13 @@ exports = module.exports = internals.Response = class {

static drain(stream) {

if (stream.unpipe) {
stream.unpipe();
}
stream.unpipe();

if (stream.close) {
stream.close();
}
else if (stream.destroy) {
stream.destroy();
}
else {
Streams.drain(stream);
stream.destroy();
}
}
};
Expand Down
20 changes: 17 additions & 3 deletions lib/streams.js
@@ -1,5 +1,6 @@
'use strict';

const Boom = require('@hapi/boom');
const Teamwork = require('@hapi/teamwork');


Expand All @@ -10,9 +11,22 @@ const internals = {

exports.isStream = function (stream) {

return stream &&
typeof stream === 'object' &&
typeof stream.pipe === 'function';
if (!stream ||
typeof stream !== 'object' ||
typeof stream.pipe !== 'function') {

return false;
}

if (typeof stream._read !== 'function') {
throw Boom.badImplementation('Stream must have a readable interface');
}

if (stream._readableState.objectMode) {
throw Boom.badImplementation('Cannot reply with stream in object mode');
}

return true;
};


Expand Down
6 changes: 4 additions & 2 deletions test/response.js
Expand Up @@ -1196,13 +1196,15 @@ describe('Response', () => {
});

await server.initialize();
const res1 = await server.inject('/stream');

const res1 = await server.inject('/stream');
expect(res1.statusCode).to.equal(500);
const res2 = await server.inject('/writable');

const res2 = await server.inject('/writable');
expect(res2.statusCode).to.equal(500);

await Hoek.wait(10);

expect(updates).to.equal(2);
});

Expand Down
112 changes: 1 addition & 111 deletions test/transmit.js
Expand Up @@ -2,7 +2,6 @@

const ChildProcess = require('child_process');
const Fs = require('fs');
const Http = require('http');
const Path = require('path');
const Stream = require('stream');
const Zlib = require('zlib');
Expand Down Expand Up @@ -1274,56 +1273,6 @@ describe('transmission', () => {
await server.stop();
});

it('does not leak stream data when request aborts before stream drains', async () => {

const server = Hapi.server();

let destroyed = false;
const team = new Teamwork.Team();
const handler = (request) => {

const stream = new Stream.Readable();

stream.destroy = undefined; // Node 8 streams comes with a destroy method – disable for this test

stream._read = function (size) {

const chunk = new Array(size).join('x');

if (destroyed) {
this.push(chunk);
this.push(null);
}
else {

setTimeout(() => {

this.push(chunk);
}, 10);
}
};

stream.once('end', () => team.attend());
return stream;
};

server.route({ method: 'GET', path: '/', handler });

await server.start();

const res = await Wreck.request('GET', 'http://localhost:' + server.info.port);
res.on('data', (chunk) => {

if (!destroyed) {
destroyed = true;
res.destroy();
}
});

await team.work;
await server.stop();
});

it('does not leak classic stream data when passed to request and aborted', async () => {

const server = Hapi.server({ debug: false });
Expand Down Expand Up @@ -1417,8 +1366,7 @@ describe('transmission', () => {
}, timeout);
};

stream.once('error', () => team.attend()); // Node 8
stream.once('close', () => team.attend()); // Node 10
stream.once('close', () => team.attend());
return stream;
};

Expand All @@ -1433,64 +1381,6 @@ describe('transmission', () => {
await server.stop();
});

it('does not leak stream data when request aborts before stream is returned', async () => {

const server = Hapi.server();
const team = new Teamwork.Team();

const handler = async (request) => {

clientRequest.abort();

const stream = new Stream.Readable();
let responded = false;

stream.destroy = undefined; // Node 8 streams comes with a destroy method – disable for this test

stream._read = function (size) {

const chunk = new Array(size).join('x');

if (responded) {
this.push(chunk);
this.push(null);
}
else {
setTimeout(() => {

responded = true;
this.push(chunk);
}, 10);
}
};

stream.once('end', () => {

expect(responded).to.be.true();
team.attend();
});

await Hoek.wait(100);
return stream;
};

server.route({ method: 'GET', path: '/', handler });

await server.start();

const clientRequest = Http.request({
hostname: 'localhost',
port: server.info.port,
method: 'GET'
});

clientRequest.on('error', () => { /* NOP */ });
clientRequest.end();

await team.work;
await server.stop();
});

it('changes etag when content-encoding set manually', async () => {

const payload = new Array(1000).fill('x').join();
Expand Down

0 comments on commit 6f3e08d

Please sign in to comment.