Follow-up on #286
#286 fixes GotenbergFileResult::stream() forwarding stale content-encoding/content-length (and drops transfer-encoding/connection) when an external reverse proxy sits in front of the Gotenberg server and gzip-compresses the response. Symfony HttpClient decompresses the body transparently but intentionally leaves the original headers untouched — this is confirmed as expected behavior by a core maintainer on symfony/symfony#64869, so the responsibility to sanitize headers before re-emitting a response sits with the consumer (us), not with HttpClient.
That raises a few open questions:
-
RFC 7230 §6.1 lists eight hop-by-hop headers (Connection, Keep-Alive, Proxy-Authenticate, Proxy-Authorization, TE, Trailer, Transfer-Encoding, Upgrade). #286 only strips two of them (Connection, Transfer-Encoding). Should the remaining ones (Keep-Alive, Trailer, TE, Upgrade, Proxy-Authenticate, Proxy-Authorization) also be stripped, given that any reverse proxy sitting in front of Gotenberg (the exact setup that triggered #286) could inject them too?
-
Is it worth distinguishing, in code or in a comment, between headers stripped because they're hop-by-hop by spec (Connection, Transfer-Encoding, etc.) versus headers stripped because this bundle mutates the body before re-emitting it (Content-Encoding, Content-Length)? The two categories have different justifications and conflating them may confuse future readers.
-
Should this header-sanitizing logic be extracted into a shared private/protected method (e.g. on AbstractGotenbergResult) now, even though GotenbergFileResult::stream() is currently the only place in the bundle that builds an outgoing Response? Would that guard against the same bug resurfacing if another response-building path is added later (e.g. on GotenbergAsyncResult)?
-
Are there other representation headers worth checking for staleness in this same "body gets transformed before re-emission" scenario (e.g. Content-MD5, Digest), or should we hold off until one is actually observed in a real Gotenberg or intermediary-proxy response, per YAGNI?
#286 fixes GotenbergFileResult::stream() forwarding stale content-encoding/content-length (and drops transfer-encoding/connection) when an external reverse proxy sits in front of the Gotenberg server and gzip-compresses the response. Symfony HttpClient decompresses the body transparently but intentionally leaves the original headers untouched — this is confirmed as expected behavior by a core maintainer on symfony/symfony#64869, so the responsibility to sanitize headers before re-emitting a response sits with the consumer (us), not with HttpClient.
That raises a few open questions:
RFC 7230 §6.1 lists eight hop-by-hop headers (Connection, Keep-Alive, Proxy-Authenticate, Proxy-Authorization, TE, Trailer, Transfer-Encoding, Upgrade). #286 only strips two of them (Connection, Transfer-Encoding). Should the remaining ones (Keep-Alive, Trailer, TE, Upgrade, Proxy-Authenticate, Proxy-Authorization) also be stripped, given that any reverse proxy sitting in front of Gotenberg (the exact setup that triggered #286) could inject them too?
Is it worth distinguishing, in code or in a comment, between headers stripped because they're hop-by-hop by spec (Connection, Transfer-Encoding, etc.) versus headers stripped because this bundle mutates the body before re-emitting it (Content-Encoding, Content-Length)? The two categories have different justifications and conflating them may confuse future readers.
Should this header-sanitizing logic be extracted into a shared private/protected method (e.g. on AbstractGotenbergResult) now, even though GotenbergFileResult::stream() is currently the only place in the bundle that builds an outgoing Response? Would that guard against the same bug resurfacing if another response-building path is added later (e.g. on GotenbergAsyncResult)?
Are there other representation headers worth checking for staleness in this same "body gets transformed before re-emission" scenario (e.g. Content-MD5, Digest), or should we hold off until one is actually observed in a real Gotenberg or intermediary-proxy response, per YAGNI?