curl / Mailing Lists / curl-users / Single Mail
Buy commercial curl support from WolfSSL. We help you work out your issues, debug your libcurl applications, use the API, port to new platforms, add new features and more. With a team lead by the curl founder himself.

Re: How does early error response detection work?

From: Osipov, Michael via curl-users <>
Date: Mon, 25 May 2020 11:33:01 +0200

Daniel, thanks for the response!

Am 2020-05-23 um 22:57 schrieb Daniel Stenberg:
> On Sat, 23 May 2020, Osipov, Michael via curl-users wrote:
>> I am currently trying to understand how curl via libcurl detects an
>> early error respone (401) on a POST request with a large request body:
> I knows this because it gets the response back with that error *before*
> it has sent the entire request body. Can you do this any other way?

I am actually not questioning the behavior implemented in curl, it seems
correct to me according to RFC 7230. My primary problem was to analyze a
shortcoming in mod_proxy_http which does not handle these early
responses and fails with 502. See

When I use curl I use the Expect feature. The speciic about the issue I
am experiencing is a CI job in Python with py-requests which does not
support Expect, but that's offtopic here.

>> I read the source code (rewind and auth) and ran curl through truss.
>> As far as I understand curl works with non-blocking I/O. It sends the
>> headers, reads from socket and then sends the first block of data (64
>> KiB), waits with a poll for the socket, send the next chuck, receives
>> a EAGAIN (ERR#35 on BSD), polls again and tries to read from the
>> socket and notices that an error response has been transmitted, all
>> FDs are closed and the application terminated.
>> Hopefully this is properly understood from my side.
> Your description depends on your specific circumstances. curl will send
> as much as possible of the headers and body until it gets EAGAIN back
> (or they were all sent off) and then continue sending more when it can.
>> Since all runs in the same thread, I did not fully understand the
>> synchronization between read() and write(). Does the EAGAIN on write()
>> cause the read() on the socket or rather after a write() happens a
>> read(), sets some flags and the write() picks them up and notices that
>> any further write()s won't be fruitful?
> Reading and writing are handled separately and independently. EAGAIN on
> send()
> will make it wait until it can write again until it retries and the same
> thing for recv().

This explains what I see in truss. But how do you notify from recv()
that send() shall stop sending if both operate separately and independently?

Received on 2020-05-25