Skip to content

Commit

Permalink
Expose compressor to response streams. Closes #3599
Browse files Browse the repository at this point in the history
  • Loading branch information
hueniverse committed Oct 18, 2017
1 parent 5031700 commit c49b9c8
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 11 deletions.
8 changes: 7 additions & 1 deletion API.md
Original file line number Diff line number Diff line change
Expand Up @@ -3323,7 +3323,13 @@ The return value must be one of:
- `Stream` object
- must be compatible with the "streams2" API and not be in `objectMode`.
- if the stream object has a `statusCode` property, that status code will be used as
the default response code.
the default response code based on the [`passThrough`](#response.settings.passThrough)
option.
- if the stream object has a `headers` property, the headers will be included in the response
based on the [`passThrough`](#response.settings.passThrough) option.
- if the stream object has a function property `setCompressor(compressor)` and the response
passes through a compressor, a reference to the compressor stream will be passed to the
response stream via this method.
- any object or array
- must not include circular references.
- a toolkit signal:
Expand Down
9 changes: 8 additions & 1 deletion lib/transmit.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,14 @@ internals.encoding = function (response, encoding) {

delete response.headers['content-length'];
response._header('content-encoding', encoding);
return request._core.compression.encoder(request, encoding);
const compressor = request._core.compression.encoder(request, encoding);
if (response.variety === 'stream' &&
typeof response._payload.setCompressor === 'function') {

response._payload.setCompressor(compressor);
}

return compressor;
};


Expand Down
60 changes: 51 additions & 9 deletions test/transmit.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,15 +371,8 @@ describe('transmission', () => {
expect(res.headers['content-encoding']).to.equal('gzip');
expect(res.headers.vary).to.equal('accept-encoding');

await new Promise((resolve) => {

Zlib.unzip(res.rawPayload, (err, result) => {

expect(err).to.not.exist();
expect(result.toString()).to.equal('/**/docall({"first":"1","last":"2"});');
resolve();
});
});
const uncompressed = await internals.uncompress('unzip', res.rawPayload);
expect(uncompressed.toString()).to.equal('/**/docall({"first":"1","last":"2"});');
});

it('returns an JSONP response when response is a buffer', async () => {
Expand Down Expand Up @@ -1772,6 +1765,49 @@ describe('transmission', () => {
});
});

describe('encoding()', () => {

it('passes compressor to stream', async () => {

const handler = (request, h) => {

const TestStream = class extends Stream.Readable {

_read(size) {

if (this.isDone) {
return;
}
this.isDone = true;

this.push('some payload');
this._compressor.flush();

setTimeout(() => {

this.push(' and some other payload');
this.push(null);
}, 10);
}

setCompressor(compressor) {

this._compressor = compressor;
}
};

return h.response(new TestStream()).type('text/html');
};

const server = Hapi.server({ compression: { minBytes: 1 } });
server.route({ method: 'GET', path: '/', handler });

const res = await server.inject({ url: '/', headers: { 'accept-encoding': 'gzip' } });
const uncompressed = await internals.uncompress('unzip', res.rawPayload);
expect(uncompressed.toString()).to.equal('some payload and some other payload');
});
});

describe('writeHead()', () => {

it('set custom statusMessage', async () => {
Expand Down Expand Up @@ -1841,3 +1877,9 @@ internals.compress = function (encoder, value) {

return new Promise((resolve) => Zlib[encoder](value, (ignoreErr, compressed) => resolve(compressed)));
};


internals.uncompress = function (decoder, value) {

return new Promise((resolve) => Zlib[decoder](value, (ignoreErr, uncompressed) => resolve(uncompressed)));
};

0 comments on commit c49b9c8

Please sign in to comment.