-
Notifications
You must be signed in to change notification settings - Fork 18k
compress/flate: can't reuse inflate state for split data packets #48877
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
Comments
cc @dsnet |
Have you tried using |
How could you extract said dictionary so you can feed it to
I am by no means a specialist in compression algorithms. |
Correct. The dictionary is literally the last 32KiB of the most recently compressed input or decompressed output. At the very least, you could use a We could add methods to directly retrieve the buffer with something like: // ExportDictionary dictionary copies the internal dictionary into b
// and reports the number of bytes copied.
// A buffer of at least 32KiB should be provided.
func (*Writer) ExportDictionary(b []byte) int It's highly unfortunate that |
OK, dictionary itself isn't an issue then, thanks. Adding new method to stdlib isn't necessary in that case. At least not right now. But there is still an issue with reader (writer is probably fine) because it's impossible to know whether it finished to read all decompressed data from provided chunk or not. I don't think that's a good idea to rely on Edit: I tried using fixed buffer for incoming stream and then passing that to How about some kind of |
@dsnet can you please take another look and give some feedback? |
In addition to relying on |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
WebSocket
permessage-deflate
compression extension (RFC7692) can reuse LZ77 sliding window for future messages which requires maintaining inflate state so you could feed incoming messages to it.Also Discord uses zlib streaming compression in a similar manner.
In both cases sender uses single context for all consecutive messages that end with
Z_SYNC_FLUSH = 0x0000FFFF
.If you decompress these messages without resetting inflate state it wouldn't be possible but quite expected.
If you try to maintain inflate state, it's still doesn't seem possible to decompress separate messages within same context.
io.Reader
object returned fromflate.NewReader
doesn't provide information about stream state.Read
calls do not indicate when flate encountersZ_SYNC_FLUSH
.Neither inflate nor WebSocket protocol have information about size of decompressed payload (and doesn't need to correctly work) so you can't allocate correctly-sized buffer for reading without going out of message boundaries.
If you try to call
Read
onio.Reader
fromflate.NewReader
, you'll getio.UnexpectedEOF
as soon as first compressed message ends. You can't also feed data to that reader anymore even if you ignoreio.UnexpectedEOF
(which is good). It can be easily reproduced by usingio.ReadAll
.It is understandable why it works like that and not an issue by itself.
The text was updated successfully, but these errors were encountered: