Skip to content

fix: decompress gzip/deflate/br responses in parseURL() - #306

Open
pratik-desgn wants to merge 1 commit into
rbren:masterfrom
pratik-desgn:fix-gzip-content-encoding
Open

fix: decompress gzip/deflate/br responses in parseURL()#306
pratik-desgn wants to merge 1 commit into
rbren:masterfrom
pratik-desgn:fix-gzip-content-encoding

Conversation

@pratik-desgn

Copy link
Copy Markdown

Summary

Fixes #280. parseURL() never sends an Accept-Encoding header, and reads the raw HTTP response body directly as text (res.on('data')). Per RFC 7231 §5.3.4, a server is allowed to compress a response even without an Accept-Encoding request header - and as the issue reports, some servers do this unconditionally regardless of what's requested. When that happens, rss-parser feeds raw gzip bytes to the XML parser and fails with Non-whitespace before first tag.

Browsers and fetch() handle this by transparently decompressing based on the response's Content-Encoding, independent of what was requested. This PR does the same.

Changes

  • parseURL() now sends Accept-Encoding: gzip, deflate, br by default (in DEFAULT_HEADERS), for better compliance and so compliant servers can save bandwidth.
  • Regardless of what's requested, if the response actually comes back with a Content-Encoding: gzip/deflate/br header, the body is piped through the matching zlib decompression stream before being read as text - covering the case in the issue where the server ignores Accept-Encoding entirely.

Test plan

  • Added a test that spins up a real HTTP server returning a gzip-compressed RSS body with a Content-Encoding: gzip header and no request for it, and asserts it parses correctly. Confirmed it fails with the exact Non-whitespace before first tag error from the issue when run against the old code, and passes with the fix.
  • Full existing test suite passes (36/36).

parseURL() reads the raw HTTP response body as text via res.on('data'),
so a server that returns a compressed body (with or without an
Accept-Encoding request header - which rss-parser never sent) produces
garbage bytes that the XML parser rejects with
"Non-whitespace before first tag" (rbren#280).

Now requests advertise Accept-Encoding: gzip, deflate, br, and any
response actually returned with a Content-Encoding header gets piped
through the matching zlib decompression stream before being read as
text, regardless of what was requested - matching how fetch()/browsers
already handle this.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

parseURL doesn't send Accept-Encoding and fails to handle alternate Content-Encoding (e.g. gzip)

1 participant