Closed thedayofcondor closed 9 months ago
This is independent from the path having a handler (if a handler is attached to that path, the handler code is never called) or not (in which case I would expect HTTP 404).
I don't fully understand what you are saying with this statement. Could you explain more? Thanks!
Sorry, I mean, this is mt code
srv.Post("/download", myHandler...)
Using curl -X POST http://192.168.1.1:8080/download
and curl -X POST http://192.168.1.1:8080/downloadxxxxx
- if I don't submit a body I get a 400 response after a 5s delay from both curl
s, independently from the fact /download
is valid endpoint (but myHandler is never called) and /downloadxxxxx
is not (and should return 404)
Im getting the same with PUT and PATCH methods
GET, HEAD, OPTIONS and DELETE work fine
@thedayofcondor in your case, does the request from curl contain the 'Content-Length' header? If so, what is the value?
Yes - you are correct, with an empty POST there is no content-length
at all
$ curl -X POST http://localhost:8080
$ nc -l 8080| cat -v
POST / HTTP/1.1^M
Host: localhost:8080^M
User-Agent: curl/7.81.0^M
Accept: */*^M
^M
$ curl -X POST -d' ' http://localhost:8080
$ nc -l 8080| cat -v
POST / HTTP/1.1^M
Host: localhost:8080^M
User-Agent: curl/7.81.0^M
Accept: */*^M
Content-Length: 1^M
Content-Type: application/x-www-form-urlencoded^M
^M
@thedayofcondor could you test with the latest httplib.h on the master branch? If it works on your machine, I'll publish the next version '0.14.3'. Thanks.
Thanks, I will test it on my next build and let you know!
@thedayofcondor 0.14.3 is actually out already. Please let me know if you have any problem with it. Thanks!
@thedayofcondor 0.14.3 is actually out already. Please let me know if you have any problem with it. Thanks!
I've recently started playing around with this library and I'm pretty sure I'm still experiencing this issue (or a similar one) on 0.14.3 (and on master). Running curl with no post params or body causes it to hang for a short while before calling my Post handler.
So my callback is eventually run but it takes a couple of seconds. Works fine if I add a dummy post param in curl.
@slwwpy just today I migrated to 0.14.3
/install
only has Get
$ time curl -X POST -I http://192.168.2.3:8080/install
HTTP/1.1 404 Not Found
Content-Length: 0
Keep-Alive: timeout=5, max=5
real 0m5.019s
user 0m0.001s
sys 0m0.014s
/download
only has Post
$ time curl -X POST -I http://192.168.2.3:8080/download
HTTP/1.1 404 Not Found
Content-Length: 39
Content-Type: text/plain
Keep-Alive: timeout=5, max=5
real 0m5.021s
user 0m0.003s
sys 0m0.012s
/invalidurl
is not defined at all
$ time curl -X POST -I http://192.168.2.3:8080/invalidurl
HTTP/1.1 404 Not Found
Content-Length: 0
Keep-Alive: timeout=5, max=5
real 0m5.013s
user 0m0.002s
sys 0m0.007s
In all 3 cases a POST without a body seems to take 5 seconds before timing out, so it do not think the behaviour has changed compared to 0.14.2.
Adding -d"" works as expected (explicitly stating empty body).
However, I am not sure how the HTTP standard says you have to handle those cases, assuming the client does not send a content-length=0
how is the web server supposed to know there is not going to be any post data?
Just briefly looking at this respons to an old curl issue (https://github.com/curl/curl/issues/2183#issuecomment-352903012), the "correct" way to use curl appears to be to provide -d"" rather than -XPOST since -d"" implies POST with empty content, while -X just forces curl to use that method.
This is what the HTTP spec has to say: https://www.rfc-editor.org/rfc/rfc9110#section-8.6-5
A user agent SHOULD send Content-Length in a request when the method defines a meaning for enclosed content and it is not sending Transfer-Encoding. For example, a user agent normally sends Content-Length in a POST request even when the value is 0 (indicating empty content). A user agent SHOULD NOT send a Content-Length header field when the request message does not contain content and the method semantics do not anticipate such data.
I interpret this that POST should always come with a content-length 0 when used correctly so this might be a non-issue.
@slwwpy agree - but then httplib should not wait for a body for 5 seconds, at least on endpoints without a Post?
How I read it - the specs say SHOULD - not MUST - setting content-length on a POST is recommended, not compulsory, so waiting is the right thing to do
However is not clear at what point httplib should return a 404? Do we need to read the POST body before determining we do not have anyone to send that data to?
@yhirose my change at b4748a2 is not to return a response with 400 instead of 400, and the 'waiting 5 seconds' thing remains. It's because the request doesn't contain Content-Length and the server expects arbitrary length of data might come. Checking the reading time out is the only way for the server to recognize the incoming data ends. (You can change the reading time out with set_read_timeout
method at runtime or CPPHTTPLIB_READ_TIMEOUT_SECOND
at compile time. Hope it helps.
Hi,
I am using v0.14.2
If I do a POST without a body, eg:
curl -X POST http://192.168.1.1:8080/download
cpp-httplib waits for 5 seconds (presumably waiting to read the body) and then returns HTTP 400.This is independent from the path having a handler (if a handler is attached to that path, the handler code is never called) or not (in which case I would expect HTTP 404).