Skip to content

curl cannot decode non-simple Transfer-Encoding #16956

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

Closed
jonathan-rosa opened this issue Apr 4, 2025 · 8 comments
Closed

curl cannot decode non-simple Transfer-Encoding #16956

jonathan-rosa opened this issue Apr 4, 2025 · 8 comments
Assignees
Labels

Comments

@jonathan-rosa
Copy link

I did this

This is a bug report where cURL does not understand Transfer-Encoding other than solely chunked.

Firefox and Chrome behavior reference
Neither browser cares where is chunked, they both show "Hello world" unless it is encoded, neither browser supports encodings in Transfer-Encoding other than chunked.

cURL
Response:

HTTP/1.1 200 OK
Transfer-Encoding: identity, chunked

Expected output:

Hello world

Actual output:

* no chunk, no close, no size. Assume close to signal end
b
Hello world
0

Response:

HTTP/1.1 200 OK
Transfer-Encoding: chunked, identity

Expected output:
Error, because chunked must be last according to spec (6.1 of RFC 9112).
Actual output:

Hello world

Response:

HTTP/1.1 200 OK
Transfer-Encoding: gzip, chunked

Expected output:

Hello world

Actual output:

* no chunk, no close, no size. Assume close to signal end
13
[binary not decoded]
0

Response:

HTTP/1.1 200 OK
Transfer-Encoding: chunked, gzip

Expected output:
Error, because chunked must be last according to spec (6.1 of RFC 9112).
Actual output:

[binary not decoded]

I expected the following

No response

curl/libcurl version

curl 8.13.0 (aarch64-apple-darwin24.2.0) libcurl/8.13.0 OpenSSL/3.4.1 (SecureTransport) zlib/1.2.12 brotli/1.1.0 zstd/1.5.7 AppleIDN libssh2/1.11.1 nghttp2/1.65.0 librtmp/2.3
Release-Date: 2025-04-02
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd

operating system

macOS 15.3.1 (24D70)

@bagder bagder added the HTTP label Apr 4, 2025
@bagder bagder self-assigned this Apr 4, 2025
@bagder
Copy link
Member

bagder commented Apr 4, 2025

When you tested the Transfer-Encoding: gzip, chunked case, how did you invoke curl? With out without --tr-encoding ?

Edit:

  1. because with the option, we have test case 1124 that seems to indicate that it works.
  2. because without the option, shouldn't the presence of gzip in the response header instead cause an error?

@bagder
Copy link
Member

bagder commented Apr 4, 2025

If the choice had been bluergh, chunked it seems natural we need to fail because we have no clue how to decode.

@bagder
Copy link
Member

bagder commented Apr 4, 2025

A guess is that browsers handle unsolicited gzip ?

bagder added a commit that referenced this issue Apr 4, 2025
- allow and ignore "identity" as an encoding

- fail if any other encoder than chunked follows after chunked

- fail on unsolicited encodings - when the server encodes but curl did
  not ask for it

Add test 1493 to 1496 to verify.

Reported-by: Jonathan Rosa
Fixes #16956
@jonathan-rosa
Copy link
Author

jonathan-rosa commented Apr 4, 2025

When you tested the Transfer-Encoding: gzip, chunked case, how did you invoke curl? With out without --tr-encoding ?

Edit:

1. because **with** the option, we have test case 1124 that seems to indicate that it works.

2. because **without** the option, shouldn't the presence of `gzip`  in the response header instead cause an error?

I was testing without the option the whole time.

With the option, everything works surprisingly as expected and even decodes the binary unsolicited.

  • Transfer-Encoding: chunked, gzip: (correct) curl: (61) Error while processing content unencoding: incorrect header check
  • Transfer-Encoding: chunked, ssss: (correct) the same 61 error.
  • Transfer-Encoding: gzip, chunked: (correct) the chunk gets decompressed as Hello world
  • Transfer-Encoding: ssss, chunked: (correct) curl: (61) Unrecognized content encoding type. libcurl understands deflate, gzip content encodings.
  • Transfer-Encoding: identity, chunked: (correct) Hello world

@jonathan-rosa
Copy link
Author

A guess is that browsers handle unsolicited gzip ?

Yeah, a browser sends Accept-Encoding: gzip, deflate, br, zstd for every request, there is never a point where it is unsolicited for them.

@bagder
Copy link
Member

bagder commented Apr 4, 2025

even decodes the binary unsolicited.

What do you mean? When you use the option the client asks for Transfer-Encoding, how is that "unsolicited" ?

a browser sends Accept-Encoding

That's Accept-Encoding (encoding content), let's not confuse this with the Transfer-Encoding this issue is about!

@jonathan-rosa
Copy link
Author

even decodes the binary unsolicited.

What do you mean? When you use the option the client asks for Transfer-Encoding, how is that "unsolicited" ?

Oh, I see, I did not see the TE: gzip in the server log until just now.

Host: 127.0.0.1:8080
User-Agent: curl/8.7.1
Accept: */*
Connection: TE
TE: gzip

@jonathan-rosa
Copy link
Author

I believe that there is confusion in what I thought what the bug was and what the bug actually is.
I thought that the bug is cURL not being able to handle non-simple Transfer-Encoding at all, but it can with tr flag.
The real bug is cURL not being able to dechunk it without the tr flag. That is the miscommunication between us.

@bagder bagder closed this as completed in b8bd019 Apr 5, 2025
nbaws pushed a commit to nbaws/curl that referenced this issue Apr 26, 2025
- allow and ignore "identity" as an encoding

- fail if any other encoder than chunked follows after chunked

- fail on unsolicited encodings - when the server encodes but curl did
  not ask for it

Add test 1493 to 1496 to verify.

Disable test 319 as that is now broken: issue curl#16974

Reported-by: Jonathan Rosa
Fixes curl#16956
Closes curl#16959
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging a pull request may close this issue.

2 participants