-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
HTTP response during a stalled upload gets buffered when curl isn't expecting 100 Continue #16788
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
I am not sure I understand the problem you are stating. Curl does an upload from stdin, the server sends - before the upload is done - a 200 response. Curl continues the upload. What do you think is wrong with curl's behaviour here? |
I think the received parts of the response body should be written to the output as they're being received, i.e. while the upload is still ongoing. Especially so when |
@JustAnotherArchivist in my tests with uploading a file and a server that echoes that back right away, curl writes out the response while it is still uploading the file. The difference to your example is that the upload is from a file and not Does that explain what you are seeing? |
@icing Hmm, I see. It at least shows that there are more cases to consider. But I don't think it's the full explanation; curl does write out the response while waiting for the 100 response, even when stdin has no data available, like in scenario 2 above... Edit: Actually, I was probably half-asleep when I wrote this; as I mentioned in the original writeup, file uploads where data is available continuously do indeed not cause this issue. It might be interesting to test this with a setup where the reads can be delayed, perhaps with a networked file system. |
Only for
|
on the scenario 1 shows this:
Until I press return, as then it unsticks:
|
Something is weird here. |
I did this
It appears that whenever an upload is stalling (e.g. uploading from a pipe and waiting for more data) and curl isn't expecting a
100 Continue
response, any response (data) being sent by the server ahead of request completion gets buffered. I have observed the buffering in the following scenarios:100 Continue
, then starts sending a response: response data is buffered.Expect: 100-continue
header and starts sending a response: until the--expect100-timeout
is reached, data is written to the output immediately; after the timeout, it is buffered.Expect
behaviour on the client side using--header Expect:
(as documented here): response data is buffered.In all cases, whenever curl receives input data to send, it also writes the accumulated response data to the output. Once the upload is complete, e.g. EOF on the input pipe, buffering returns to normal as well. The behaviour is identical with a terminal on stdout (as below) and with
--output file --no-buffer
.To reproduce scenario 1, here's a simple HTTP/1.1 server that blindly sends a
100 Continue
and then a response:Then,
from a terminal will buffer until receiving an LF.
To reproduce scenarios 2 and 3, here's an even simpler HTTP/0.9 server:
For scenario 2,
will output the first 10 numbers immediately, then declare the end of the expect phase via
* Done waiting for 100-continue
on stderr, then buffer until LF on stdin.For scenario 3,
will buffer from the beginning. Also of note, it doesn't even output the request
> PUT / HTTP/1.1
+ headers either.I expected the following
Regular buffering behaviour, i.e. line buffering when stdout is a terminal, and no buffering with
--no-buffer
.curl/libcurl version
curl 8.12.1 (x86_64-pc-linux-gnu) libcurl/8.12.1 GnuTLS/3.8.9 zlib/1.3.1 brotli/1.1.0 zstd/1.5.7 libidn2/2.3.8 libpsl/0.21.2 libssh2/1.11.1 nghttp2/1.64.0 ngtcp2/1.11.0 nghttp3/1.8.0 librtmp/2.3 OpenLDAP/2.6.9
Release-Date: 2025-02-13, security patched: 8.12.1-3
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 HTTP3 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd
operating system
Debian sid,
Linux $hostname 6.12.17-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.17-1 (2025-03-01) x86_64 GNU/Linux
Why I found this
This was discovered in the process of trying to turn curl into an IRC client.
The text was updated successfully, but these errors were encountered: