-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Event on end of deflate stream #26603
Comments
Zlib docs do say
And lists Z_STREAM_END as a possible return value. But I find no tests that cover that case and I cannot figure out where, exactly, those values would be returned from. |
@kingces95 Did you take a look at #26363? I linked it from your previous issue, and it seems like it is what you want here? |
Oh! Woot! Although, are we sure that is the right fix? I'm not an expert, but are we sure that every input byte will result in output bytes? If not, then there could be a case where there is input to consume and space to publish the output yet Shouldn't we shuttle the Take this case: If I write bytes one at a time them I'm forced to write one byte past the end of the deflate stream before the What does |
No, not every input byte will result in output bytes. |
Given Mark Adler's comment, I don't think we can infer Z_STREAM_END given the conditions specified in the comment:
So there is a delta I think would work for me. I added a property Please lemme know if that makes sense and I'll move the test case I added as a comment into the test suite + some docs. (Or just lemme know if you wanna rock out with it!) I'm gonna see how hard it would be to add another field |
As an example, the Python zlib |
Ah, so if I follow, node could introduce a Could also deprecate Yeah. That'd be pretty. |
No, but it doesn’t have to, either; that’s not what the check is testing. It’s ending the stream when zlib has stopped accepting input and refuses to let
I’ve tried that in a first attempt to solve the previous issue that you posted, but it turned out to be a bit icky as a way to end the stream. I don’t exactly remember why.
Yeah, that is a bit unfortunate indeed.
It ends the readable side of the stream; after all data has been read from zlib, the |
Ah! I was looking for the So this fix rests on the fact that I think I found the ending the stream given And while an Was that more or less the thinking? |
And for those who find this later, here is my test case! var zlib = require('zlib');
var assert = require('assert');
const input = Buffer.from('0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789');
var log = console.log.bind(console);
zlib.deflateRaw(input, (err, deflatedBuffer) => {
assert(!err);
var bytesRead = 0;
var buffers = [];
var stream = zlib.createInflateRaw();
var position = 0;
stream.on('data', function(chunk) {
buffers.push(chunk);
bytesRead += chunk.length;
log('decompressed:', 'written', stream.bytesWritten, 'read', bytesRead);
})
stream.on('end', function done() {
var result = Buffer.concat(buffers, bytesRead);
this.close();
log('result:', result.toString());
log('chunks:', buffers.length);
log('bytesWritten:', stream.bytesWritten);
log('numberRead:', bytesRead);
log('discarded:', position - stream.bytesWritten);
});
log('download: started')
stream.write(deflatedBuffer.slice(0, 5)); position += 5;
stream.write(deflatedBuffer.slice(5, 10)); position += 5;
stream.write(deflatedBuffer.slice(10)); position += deflatedBuffer.length - 10;
stream.write(Buffer.from([1,2,3,4,5,6])); position += 6; // discarded
log('download: delayed')
setTimeout(() => {
log('download: resumed')
log(stream.write(Buffer.from([1,2,3,4,5,6]))); // rejected
log('download: finished')
stream.end();
}, 1000);
}); |
Wow. So excited to give this a spin. Will re-open if I get stuck but I think I've got what I need. Yea node! |
I expect the zlib
InflateRaw
stream to notify me somehow (maybe an'error'
event) that it has detected the end of the deflated stream and is now discarding any more bytes written to the stream. The zlib.net/zpipe.c annotated example code saysWhat zlib actually does is discard any bytes written to
InflateRaw
after then the end of the deflated stream has been identified; Zlib does not propagate the Z_STREAM_END notification to me.I believe zlib will encounter Z_STREAM_END here. And here is where zlib needs to raise the error (I think), but only if there are additional bytes written after the end of the stream as that would indicate the stream user doesn't know where the end of the stream is.
Either way, the stream should also return
false
after encountering Z_STREAM_END instead of "consuming" by tossing the bytes.I'm attempting to download and unzip a file in one pass. As the bytes are downloaded I detect the zip headers and start decompressing the stream. The stream is decompressed but as I'm not notified the decompression has reached the end of the deflated stream I'm forced to buffer the remainder of the file which defeats my goal of streaming decompression.
For example, see: #26624
See also my first issue (notes from when I was groping around trying to grock): #26332
The text was updated successfully, but these errors were encountered: