When gzip is used as middleware in a parent -> gzip -> inner setup, sometimes the parent handler wants to call ResponseWriter.WriteHeader knowing the inner handler hasn't called it yet.
However, gziphandler currently calls WriteHeader(200) when wrapping up, and because the go stdlib only uses the first call, this breaks things (parent's call becomes void). The same reasoning goes for calling .Write(): gziphandler should not call .Write() when no .Write() was ever called on itself.
I've updated the logic to never call WriteHeader() when .code is still 0 (and removed the one-liner writeHeader indirection while I was at it), and to make the distinction between Write() being called or not by keeping .buf to nil. This way even a .Write([]byte{}) will result in the same call to the parent.
I've added a test TestDontWriteWhenNotWrittenTo that confirms the new behavior for .WriteHeader() at least.
When gzip is used as middleware in a
parent -> gzip -> inner
setup, sometimes the parent handler wants to callResponseWriter.WriteHeader
knowing the inner handler hasn't called it yet.However,
gziphandler
currently callsWriteHeader(200)
when wrapping up, and because the go stdlib only uses the first call, this breaks things (parent's call becomes void). The same reasoning goes for calling.Write()
:gziphandler
should not call .Write() when no .Write() was ever called on itself.I've updated the logic to never call
WriteHeader()
when.code
is still 0 (and removed the one-linerwriteHeader
indirection while I was at it), and to make the distinction betweenWrite()
being called or not by keeping.buf
tonil
. This way even a.Write([]byte{})
will result in the same call to the parent.I've added a test
TestDontWriteWhenNotWrittenTo
that confirms the new behavior for.WriteHeader()
at least.