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

Docs are not clear about zero-byte POST #862

Closed
safinaskar opened this issue Jun 6, 2016 · 8 comments
Closed

Docs are not clear about zero-byte POST #862

safinaskar opened this issue Jun 6, 2016 · 8 comments

Comments

@safinaskar
Copy link
Contributor

I cannot understand from online docs at https://curl.haxx.se/libcurl/c/ how to do zero-byte POST. It seems docs should be fixed. Is the following code ok?

curl_global_init (CURL_GLOBAL_ALL);
CURL *curl_handle = curl_easy_init ();
curl_easy_setopt (curl_handle, CURLOPT_URL, "http://example.com");
curl_easy_setopt (curl_handle, CURLOPT_POSTFIELDSIZE, 0L);
CURLcode code = curl_easy_perform (curl_handle);

Or I should also set CURLOPT_POST or CURLOPT_POSTFIELDS?
Is the following code ok? Does it really perform zero-byte POST?

curl_global_init (CURL_GLOBAL_ALL);
CURL *curl_handle = curl_easy_init ();
curl_easy_setopt (curl_handle, CURLOPT_URL, "http://example.com");
curl_easy_setopt (curl_handle, CURLOPT_POSTFIELDS, NULL); // is this line ok???
curl_easy_setopt (curl_handle, CURLOPT_POSTFIELDSIZE, 0L);
CURLcode code = curl_easy_perform (curl_handle);
@bagder bagder added the HTTP label Jun 6, 2016
@bagder
Copy link
Member

bagder commented Jun 6, 2016

The CURLOPT_POSTFIELDS man page states:

If you want to do a zero-byte POST, you need to set CURLOPT_POSTFIELDSIZE(3) explicitly to zero, as simply setting CURLOPT_POSTFIELDS(3) to NULL or "" just effectively disables the sending of the specified string. libcurl will instead assume that you'll send the POST data using the read callback!

Isn't that good enough?

@jay
Copy link
Member

jay commented Jun 7, 2016

Or I should also set CURLOPT_POST or CURLOPT_POSTFIELDS?

Yes that's what you should do.

@bagder I think maybe it's lost in translation. How about:

If CURLOPT_POSTFIELDS(3) is set to "" or NULL, and CURLOPT_POSTFIELDSIZE(3) is set to 0, then libcurl will do a zero-byte POST. If CURLOPT_POSTFIELDS(3) is set to "" or NULL, and CURLOPT_POSTFIELDSIZE(3) is not set to 0, then libcurl will get the POST data from the read callback.

@bagder
Copy link
Member

bagder commented Jun 7, 2016

@safinaskar, you think @jay's version makes it clearer?

@safinaskar
Copy link
Contributor Author

Yes :)

@jay
Copy link
Member

jay commented Jun 8, 2016

I tried indenting so it isn't so repetitive, how about this:

If CURLOPT_POSTFIELDS(3) is set to "" or NULL, and:
    CURLOPT_POSTFIELDSIZE(3) is set to 0, then libcurl will do a zero-byte POST.
    CURLOPT_POSTFIELDSIZE(3) is \fInot\fP set to 0, then libcurl will get the POST data from the read callback.

screenshot:
capture

is that better or worse

@jay
Copy link
Member

jay commented Jun 10, 2016

I looked at this again and it would be incorrect to say libcurl will get the POST data from the read callback when CURLOPT_POSTFIELDSIZE is not 0 (I was assuming it's the default, but not necessarily).

It is also incorrect to say it will get the POST data from the read callback when just CURLOPT_POSTFIELDS is set to an empty string, even though that's the way it's been documented since 5a6dcdc. I couldn't go all the way back to 7.17 but I went back to curl 7.21 and setting CURLOPT_POSTFIELDS to "" results in a zero byte POST.

So assuming somewhere between 7.17 and 7.21 there wasn't a behavior change, how about this:

diff --git a/docs/libcurl/opts/CURLOPT_POSTFIELDS.3 b/docs/libcurl/opts/CURLOPT_
index f9f9ead..17ec2d7 100644
--- a/docs/libcurl/opts/CURLOPT_POSTFIELDS.3
+++ b/docs/libcurl/opts/CURLOPT_POSTFIELDS.3
@@ -42,16 +42,15 @@ This POST is a normal application/x-www-form-urlencoded kind
 set that Content-Type by default when this option is used), which is commonly
 used by HTML forms. Change Content-Type with \fICURLOPT_HTTPHEADER(3)\fP.

-Using \fICURLOPT_POSTFIELDS(3)\fP implies \fICURLOPT_POST(3)\fP.
-
 You can use \fIcurl_easy_escape(3)\fP to url-encode your data, if necessary. It
 returns a pointer to an encoded string that can be passed as \fIpostdata\fP.

-If you want to do a zero-byte POST, you need to set
-\fICURLOPT_POSTFIELDSIZE(3)\fP explicitly to zero, as simply setting
-\fICURLOPT_POSTFIELDS(3)\fP to NULL or "" just effectively disables the
-sending of the specified string. libcurl will instead assume that you'll send
-the POST data using the read callback!
+Using \fICURLOPT_POSTFIELDS(3)\fP implies \fICURLOPT_POST(3)\fP.
+
+If \fICURLOPT_POSTFIELDS(3)\fP is explicitly set to NULL then libcurl will get
+the POST data from the read callback. If you want to send a zero-byte POST set
+\fICURLOPT_POSTFIELDS(3)\fP to an empty string, or set \fICURLOPT_POST(3)\fP to
+1 and \fICURLOPT_POSTFIELDSIZE(3)\fP to 0.

 Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header.
 You can disable this header with \fICURLOPT_HTTPHEADER(3)\fP as usual.

@bagder
Copy link
Member

bagder commented Jun 11, 2016

Very good digging and research! 👍

jay added a commit that referenced this issue Jun 11, 2016
When CURLOPT_POSTFIELDS is set to an empty string libcurl will send a
zero-byte POST. Prior to this change it was documented as sending data
from the read callback.

This also changes the wording of what happens when empty or NULL so that
it's hopefully easier to understand for people whose primary language
isn't English.

Bug: #862
Reported-by: Askar Safin
@jay
Copy link
Member

jay commented Jun 11, 2016

Tested back to 7.17 and same thing, so this has landed in f77dfbc. Thanks

@jay jay closed this as completed Jun 11, 2016
@lock lock bot locked as resolved and limited conversation to collaborators May 7, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

3 participants