Skip to content
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

Curl doesn't send request body when the server responds with HTTP 101 #12022

Closed
djelinski opened this issue Oct 3, 2023 · 5 comments
Closed

Comments

@djelinski
Copy link
Contributor

I did this

Using a local Liberty server and curl 8.3.0 client, I sent a HTTP POST request over plain HTTP1 as follows:

curl --http2 -v -H"Expect:100-continue" http://localhost:9080/system/greeter/hello --data "foo"

The server sent the following 2 response headers in quick succession:

HTTP/1.1 100 Continue
Content-Length: 0
Date: Tue, 03 Oct 2023 19:06:00 GMT

HTTP/1.1 101 Switching Protocols
Date: Tue, 03 Oct 2023 19:06:00 GMT
Upgrade: h2c
Connection: Upgrade
Content-Length: 0

In response to that, Curl sent the HTTP2 connection preface without sending the data.
It doesn't fail every time; sometimes when the HTTP 101 header is late enough, curl manages to send the request body correctly.

I expected the following

I expected curl to send the request data before sending the HTTP2 preface

curl/libcurl version

curl 8.3.0 (x86_64-w64-mingw32) libcurl/8.3.0 OpenSSL/3.1.2 (Schannel) zlib/1.3 brotli/1.1.0 zstd/1.5.5 WinIDN libssh2/1.11.0 nghttp2/1.56.0 ngtcp2/0.19.1 nghttp3/0.15.0

operating system

Windows 11

@bagder bagder added the HTTP/2 label Oct 3, 2023
@bagder
Copy link
Member

bagder commented Oct 3, 2023

I bet the double 10x responses is the reason.

@bagder bagder added the HTTP label Oct 3, 2023
@icing
Copy link
Contributor

icing commented Oct 4, 2023

This is not a valid server response. It points to a bug in the server.

@djelinski
Copy link
Contributor Author

https://datatracker.ietf.org/doc/html/rfc7230#section-6.7 appears to suggest that the server response is valid:

A client cannot begin using an upgraded protocol on the connection until it has completely sent the request message (i.e., the client can't change the protocol it is sending in the middle of a message). If a server receives both an Upgrade and an Expect header field with the "100-continue" expectation (Section 5.1.1 of [RFC7231]), the server MUST send a 100 (Continue) response before sending a 101 (Switching Protocols) response.

@icing
Copy link
Contributor

icing commented Oct 4, 2023

Ah, @djelinski thanks for the link. You learn something new every day. In Apache httpd, I never allow protocol switching on requests with a body. Which allows me to remain ignorant so far of these intricacies.

The easiest way to fix the curl handling of this would be, my guess, to never send Upgrade: together with an Expect:, I guess.

@bagder
Copy link
Member

bagder commented Oct 4, 2023

Sensible. Or do it like you mention Apache does, avoid the upgrade if there's a request body.

bagder added a commit that referenced this issue Oct 8, 2023
@bagder bagder closed this as completed in f2de575 Oct 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

3 participants