-
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
-
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
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
Unable to perform "Chunked" uploading of multiform data over HTTP/2 #1013
Comments
This version of the code works for me against my local Apache. If this fails for you, can you please show us what headers are sent/received? |
Daniel,
|
So HTTP/2 is required for this bug to trigger? |
Yes this happens for HTTP2. I understand the risk here, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE is to be used only if we are sure that the server accepts HTTP2 requests and it would fail for other servers that doesnt support HTTP2. Right now all my requests are targeted for a particular server(which supports http2) so this is safe for my implementation. Regarding the issue, I went through some documentation for HTTP2 and because of the framed structure of HTTP/2 it is no longer necessary (in fact explicitly forbidden) to use the chunked transfer encoding that HTTP/1.1 uses for entities of unknown lengths . So I think CURLFORM_STREAM ideally we should ignore Content length for HTTP2 requests. Isnt it? |
The problem with chunked in curl's HTTP/2 handling is known: see https://curl.haxx.se/docs/knownbugs.html#transfer_encoding_chunked_in_HT and #662 |
I updated the formpost example in the gist above to enable HTTP/2 and I removed the custom My proposed patch for fixing the bug is here: 0001-http-accept-Transfer-Encoding-chunked-for-HTTP-2-as-.patch |
Hi Daniel, I tried the patch this does fix the issue mentioned in #662now there is no transfer encoding or content length field in header, but now the transfer is always failing , specifically the read callback is not being called by libcurl , please check the latest dump . My original issue was that the transfer would happen successfully but the "still_running" flag would always be set even after the response is downloaded. I am looking for a solution where after the response is downloaded the flag would be reset to 0. |
My example works against my HTTP/2 server, what more can I do? Are you saying the same example fails against your server? If so, please show me that output. |
The new output is here . After applying the patch the read callback function is not invoked . I can see from the dump that only the HTTP headers are sent and not the body. |
That output is not made with the example code we use to reproduce the case with. Please reproduce the case with the example you and me have worked on together (and update as you see fit so that it matches your problematic case) so that we both run the same thing! |
HI Daniel, so that we both are on the same page I have created a sample program which is based on our previous example which can reproduce the issue, here you will be making a request to the same server which I am also using so that there is no discrepancy . The example program is here:demo_code.c . Without the patch the "read callback function" (datareader) is invoked as intended but with patch the read callback function is not invoked. Thanks for your support. You might require a sample audio , you can find it here. PS: I am writing the dump to external file, please change according to your convenience . |
I had to adjust the example slightly for it to build and run properly (your debug function didn't redirect everything to the output file for example). I got this to work just fine actually. It produced this I then looked at your dump again, and we can see that you're getting a 400 response very quickly from the server and that can very well be why curl stopped sending: your server refused it already so there was no point in continue sending it! So, either curl sends the entire thing before it gets an error back - or it gets a positive response back (<400), otherwise we're not looking for the (same) bug anymore. |
I tried both your example and Daniel's example after applying the patch. In both cases when I connect to localhost Apache/2.4.18 it uses http2 and POSTs fine. However, when I connect to 54.239.23.243 using @akshayvernekar's example the server will disconnect (FIN) immediately after the headers are sent:
libcurl built from curl-7_50_3-2-gd932156 In @akshayvernekar's dump2.txt after the headers are sent there's some |
I used this build for my tests (on a Debian Linux): curl 7.51.0-DEV (x86_64-pc-linux-gnu) libcurl/7.51.0-DEV OpenSSL/1.0.2h zlib/1.2.8 c-ares/1.11.0 libidn/1.33 libpsl/0.14.0 (+libicu/57.1) nghttp2/1.15.0-DEV librtmp/2.3 |
Ah sorry, that was silly of me. The 400 in question is returned because it says it didn't get any multipart formpost so it is an effect of the problem and not a cause of it as I thought there for a moment. |
Results seem to vary for me in Ubuntu 16 LTS, I get curl 7.50.3 (x86_64-pc-linux-gnu) libcurl/7.50.3 OpenSSL/1.0.2h zlib/1.2.8 libidn/1.32 nghttp2/1.14.1 librtmp/2.3 |
My curl version is
My latest debug dump is here. The 403 error code is because the access tokens expire after 1 hour. Here is the new access token, this is valid for 1hour more. @jay I guess even though you got a 403 response , the uploading of http body wouldnt have happened. @bagder your output is what is desired , it seems like the uploading is happening fine in your code base. Just to make sure , http.c is the only file changed in the patch correct ? |
We fixed at least two h2 bugs in 7.50.2 that might affect this program and since you're rebuilding from source anyway to try out the patch I suggest you bump up to 7.50.3 or use the code straight from git. That also makes us try the same code. Your latest dump has these two really weird lines at line 145-146 that I can't explain and that seem to indicate a problem:
Any change you can reubuild curl with
Correct! |
Uh, it struck me that the fix is still incomplete since it actually sends data in "chunked" format even over h2 and that's incorrect. I'll work on a follow-up patch to address that. I doubt that's the reason for the remaining problem @akshayvernekar reports though. |
Here's my slightly updated patch: 0001-http-accept-Transfer-Encoding-chunked-for-HTTP-2-as-.patch It avoids the chunked formatting of the request body when sent over h2. |
The issue I reported seems to be fixed in the latest version of CURL. I updated my CURL version from GIT ,as per your suggestion and I didn’t see this issue. Thanks for your support . The request is working without applying the patch too. |
Oh lovely! Thanks for reporting back. I'll push my patch to master within shortly. |
Hi! Can you please update docs in curl.haxx.se for CURLFORM_STREAM option? I mean, that setting CONTENTS_LENGTH to arbitrary value is allowed when using chunked encoding. |
Added a comment just now about it not being needed when data is sent chunked. |
Thanks a lot! |
I did this
Currently I am able to chunked transfer the data when the CURLFORM_CONTENTSLENGTH is known, but my application requires me to transfer the data as a stream which means that the CURLFORM_CONTENTSLENGTH is not known. I tried setting the CURLFORM_CONTENTSLENGTH to a false value , the uploading of data is successful and I am even getting the response from the server, but the number of running handles still_running from curl_multi_perform(multi_handle,&still_running) never becomes 0. It always returns "1" which makes my application to hang. Below is the pseudocode, this isnt the exact code i am using but explains the problem i am facing
I expected the following
Current version of Curl doesnt allow the user to do chunked transfer of Mutiform data using the "CURLFORM_STREAM" without knowing the "CURLFORM_CONTENTSLENGTH" . It would be great if we can ignore the "CURLFORM_CONTENTSLENGTH" for chunked transfer .
curl/libcurl version
curl v50
operating system
Android ndk
The text was updated successfully, but these errors were encountered: