1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-22 08:08:50 -05:00

Fix behaviour when passing NULL to CURLOPT_POSTFIELDS and CURLOPT_HTTPPOST.

This commit is contained in:
Daniel Stenberg 2004-11-11 23:11:04 +00:00
parent 8c16696f47
commit 59c063dfd3
11 changed files with 209 additions and 19 deletions

18
CHANGES
View File

@ -6,6 +6,24 @@
Changelog Changelog
Daniel (12 November 2004)
- *** New Behaviour Alert ***
Setting CURLOPT_POSTFIELDS to NULL will no longer do a GET.
Setting CURLOPT_POSTFIELDS to "" will send a zero byte POST and setting
CURLOPT_POSTFIELDS to NULL and CURLOPT_POSTFIELDSIZE to zero will also make
a zero byte POST. Added test case 515 to verify this.
Setting CURLOPT_HTTPPOST to NULL makes a zero byte post. Added test case 516
to verify this.
CURLOPT_POSTFIELDSIZE must now be set to -1 to signal "we don't know".
Setting it to zero simply says this is a zero byte POST.
When providing POST data with a read callback, setting the size up front
is now made with CURLOPT_POSTFIELDSIZE and not with CURLOPT_INFILESIZE.
Daniel (11 November 2004) Daniel (11 November 2004)
- Dan Fandrich added --disable-verbose to the configure script to allow builds - Dan Fandrich added --disable-verbose to the configure script to allow builds
without verbose strings in the code, to save some 12KB space. Makes sense without verbose strings in the code, to save some 12KB space. Makes sense

View File

@ -555,6 +555,7 @@ void curl_easy_reset(CURL *curl)
data->set.fread = (curl_read_callback)fread; data->set.fread = (curl_read_callback)fread;
data->set.infilesize = -1; /* we don't know any size */ data->set.infilesize = -1; /* we don't know any size */
data->set.postfieldsize = -1;
data->state.current_speed = -1; /* init to negative == impossible */ data->state.current_speed = -1; /* init to negative == impossible */

View File

@ -1767,6 +1767,24 @@ CURLcode Curl_http(struct connectdata *conn)
switch(httpreq) { switch(httpreq) {
case HTTPREQ_POST_FORM: case HTTPREQ_POST_FORM:
if(!http->sendit) {
/* nothing to post! */
result = add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
if(result)
return result;
result = add_buffer_send(req_buffer, conn,
&data->info.request_size);
if(result)
failf(data, "Failed sending POST request");
else
/* setup variables for the upcoming transfer */
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount,
-1, NULL);
break;
}
if(Curl_FormInit(&http->form, http->sendit)) { if(Curl_FormInit(&http->form, http->sendit)) {
failf(data, "Internal HTTP POST error!"); failf(data, "Internal HTTP POST error!");
return CURLE_HTTP_POST_ERROR; return CURLE_HTTP_POST_ERROR;
@ -1895,7 +1913,7 @@ CURLcode Curl_http(struct connectdata *conn)
/* this is the simple POST, using x-www-form-urlencoded style */ /* this is the simple POST, using x-www-form-urlencoded style */
/* store the size of the postfields */ /* store the size of the postfields */
postsize = data->set.postfieldsize? postsize = (data->set.postfieldsize != -1)?
data->set.postfieldsize: data->set.postfieldsize:
(data->set.postfields?(curl_off_t)strlen(data->set.postfields):0); (data->set.postfields?(curl_off_t)strlen(data->set.postfields):0);
@ -1989,12 +2007,14 @@ CURLcode Curl_http(struct connectdata *conn)
else { else {
add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
/* set the upload size to the progress meter */ if(data->set.postfieldsize) {
Curl_pgrsSetUploadSize(data, data->set.infilesize); /* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
/* set the pointer to mark that we will send the post body using /* set the pointer to mark that we will send the post body using
the read callback */ the read callback */
http->postdata = (char *)&http->postdata; http->postdata = (char *)&http->postdata;
}
} }
/* issue the request */ /* issue the request */
result = add_buffer_send(req_buffer, conn, result = add_buffer_send(req_buffer, conn,

View File

@ -317,6 +317,7 @@ CURLcode Curl_open(struct SessionHandle **curl)
data->set.fread = (curl_read_callback)fread; data->set.fread = (curl_read_callback)fread;
data->set.infilesize = -1; /* we don't know any size */ data->set.infilesize = -1; /* we don't know any size */
data->set.postfieldsize = -1;
data->state.current_speed = -1; /* init to negative == impossible */ data->state.current_speed = -1; /* init to negative == impossible */
@ -657,11 +658,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
case CURLOPT_POSTFIELDS: case CURLOPT_POSTFIELDS:
/* /*
* A string with POST data. Makes curl HTTP POST. * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
*/ */
data->set.postfields = va_arg(param, char *); data->set.postfields = va_arg(param, char *);
if(data->set.postfields) data->set.httpreq = HTTPREQ_POST;
data->set.httpreq = HTTPREQ_POST;
break; break;
case CURLOPT_POSTFIELDSIZE: case CURLOPT_POSTFIELDSIZE:
@ -685,8 +685,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
* Set to make us do HTTP POST * Set to make us do HTTP POST
*/ */
data->set.httppost = va_arg(param, struct curl_httppost *); data->set.httppost = va_arg(param, struct curl_httppost *);
if(data->set.httppost) data->set.httpreq = HTTPREQ_POST_FORM;
data->set.httpreq = HTTPREQ_POST_FORM;
break; break;
case CURLOPT_REFERER: case CURLOPT_REFERER:

View File

@ -177,7 +177,6 @@ typedef enum {
#define CONF_NETRC (1<<22) /* read user+password from .netrc */ #define CONF_NETRC (1<<22) /* read user+password from .netrc */
#define CONF_FOLLOWLOCATION (1<<23) /* use Location: Luke! */ #define CONF_FOLLOWLOCATION (1<<23) /* use Location: Luke! */
#define CONF_GETTEXT (1<<24) /* use ASCII/text for transfer */ #define CONF_GETTEXT (1<<24) /* use ASCII/text for transfer */
#define CONF_HTTPPOST (1<<25) /* multipart/form-data HTTP POST */
#define CONF_MUTE (1<<28) /* force NOPROGRESS */ #define CONF_MUTE (1<<28) /* force NOPROGRESS */
#define CONF_NETRC_OPT (1<<29) /* read user+password from either #define CONF_NETRC_OPT (1<<29) /* read user+password from either
@ -2850,6 +2849,7 @@ operate(struct Configurable *config, int argc, char *argv[])
helpf("error initializing curl library\n"); helpf("error initializing curl library\n");
return CURLE_FAILED_INIT; return CURLE_FAILED_INIT;
} }
config->postfieldsize = -1;
config->showerror=TRUE; config->showerror=TRUE;
config->conf=CONF_DEFAULT; config->conf=CONF_DEFAULT;
config->use_httpget=FALSE; config->use_httpget=FALSE;
@ -3365,11 +3365,18 @@ operate(struct Configurable *config, int argc, char *argv[])
curl_easy_setopt(curl, CURLOPT_RANGE, config->range); curl_easy_setopt(curl, CURLOPT_RANGE, config->range);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, config->timeout); curl_easy_setopt(curl, CURLOPT_TIMEOUT, config->timeout);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, config->postfields);
/* new in libcurl 7.2: */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, config->postfieldsize);
switch(config->httpreq) {
case HTTPREQ_SIMPLEPOST:
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, config->postfields);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, config->postfieldsize);
break;
case HTTPREQ_POST:
curl_easy_setopt(curl, CURLOPT_HTTPPOST, config->httppost);
break;
default:
break;
}
curl_easy_setopt(curl, CURLOPT_REFERER, config->referer); curl_easy_setopt(curl, CURLOPT_REFERER, config->referer);
curl_easy_setopt(curl, CURLOPT_AUTOREFERER, curl_easy_setopt(curl, CURLOPT_AUTOREFERER,
config->conf&CONF_AUTO_REFERER); config->conf&CONF_AUTO_REFERER);
@ -3381,7 +3388,6 @@ operate(struct Configurable *config, int argc, char *argv[])
config->use_resume?config->resume_from:0); config->use_resume?config->resume_from:0);
curl_easy_setopt(curl, CURLOPT_COOKIE, config->cookie); curl_easy_setopt(curl, CURLOPT_COOKIE, config->cookie);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, config->headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, config->headers);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, config->httppost);
curl_easy_setopt(curl, CURLOPT_SSLCERT, config->cert); curl_easy_setopt(curl, CURLOPT_SSLCERT, config->cert);
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, config->cert_type); curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, config->cert_type);
curl_easy_setopt(curl, CURLOPT_SSLKEY, config->key); curl_easy_setopt(curl, CURLOPT_SSLKEY, config->key);

View File

@ -27,7 +27,7 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
test172 test204 test205 test173 test174 test175 test176 test177 \ test172 test204 test205 test173 test174 test175 test176 test177 \
test513 test514 test178 test179 test180 test181 test182 test183 \ test513 test514 test178 test179 test180 test181 test182 test183 \
test184 test185 test186 test187 test188 test189 test191 test192 \ test184 test185 test186 test187 test188 test189 test191 test192 \
test193 test194 test195 test196 test197 test198 test193 test194 test195 test196 test197 test198 test515 test516
# The following tests have been removed from the dist since they no longer # The following tests have been removed from the dist since they no longer
# work. We need to fix the test suite's FTPS server first, then bring them # work. We need to fix the test suite's FTPS server first, then bring them

46
tests/data/test515 Normal file
View File

@ -0,0 +1,46 @@
#
# Server-side
<reply>
<data>
HTTP/1.1 200 OK swsclose
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
OK
</data>
</reply>
# Client-side
<client>
<server>
http
</server>
# tool is what to use instead of 'curl'
<tool>
lib515
</tool>
<name>
make a POSTFIELDS set to NULL with POSTFIELDSIZE set to zero
</name>
<command>
http://%HOSTIP:%HTTPPORT/515
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol>
POST /515 HTTP/1.1
Host: 127.0.0.1:%HTTPPORT
Pragma: no-cache
Accept: */*
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
</protocol>
</verify>

45
tests/data/test516 Normal file
View File

@ -0,0 +1,45 @@
#
# Server-side
<reply>
<data>
HTTP/1.1 200 OK swsclose
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
OK
</data>
</reply>
# Client-side
<client>
<server>
http
</server>
# tool is what to use instead of 'curl'
<tool>
lib516
</tool>
<name>
make a HTTPPOST set to NULL
</name>
<command>
http://%HOSTIP:%HTTPPORT/516
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol>
POST /516 HTTP/1.1
Host: 127.0.0.1:%HTTPPORT
Pragma: no-cache
Accept: */*
Content-Length: 0
</protocol>
</verify>

View File

@ -39,7 +39,7 @@ SUPPORTFILES = first.c test.h
# These are all libcurl test programs # These are all libcurl test programs
noinst_PROGRAMS = lib500 lib501 lib502 lib503 lib504 lib505 lib506 lib507 \ noinst_PROGRAMS = lib500 lib501 lib502 lib503 lib504 lib505 lib506 lib507 \
lib508 lib509 lib510 lib511 lib512 lib513 lib514 lib508 lib509 lib510 lib511 lib512 lib513 lib514 lib515 lib516
lib500_SOURCES = lib500.c $(SUPPORTFILES) lib500_SOURCES = lib500.c $(SUPPORTFILES)
lib500_LDADD = $(LIBDIR)/libcurl.la lib500_LDADD = $(LIBDIR)/libcurl.la
@ -100,3 +100,11 @@ lib513_DEPENDENCIES = $(LIBDIR)/libcurl.la
lib514_SOURCES = lib514.c $(SUPPORTFILES) lib514_SOURCES = lib514.c $(SUPPORTFILES)
lib514_LDADD = $(LIBDIR)/libcurl.la lib514_LDADD = $(LIBDIR)/libcurl.la
lib514_DEPENDENCIES = $(LIBDIR)/libcurl.la lib514_DEPENDENCIES = $(LIBDIR)/libcurl.la
lib515_SOURCES = lib515.c $(SUPPORTFILES)
lib515_LDADD = $(LIBDIR)/libcurl.la
lib515_DEPENDENCIES = $(LIBDIR)/libcurl.la
lib516_SOURCES = lib516.c $(SUPPORTFILES)
lib516_LDADD = $(LIBDIR)/libcurl.la
lib516_DEPENDENCIES = $(LIBDIR)/libcurl.la

24
tests/libtest/lib515.c Normal file
View File

@ -0,0 +1,24 @@
#include "test.h"
int test(char *URL)
{
CURL *curl;
CURLcode res=CURLE_OK;
curl = curl_easy_init();
if(curl) {
/* First set the URL that is about to receive our POST. */
curl_easy_setopt(curl, CURLOPT_URL, URL);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, NULL);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 0);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); /* show verbose for debug */
curl_easy_setopt(curl, CURLOPT_HEADER, 1); /* include header */
/* Now, we should be making a zero byte POST request */
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return (int)res;
}

23
tests/libtest/lib516.c Normal file
View File

@ -0,0 +1,23 @@
#include "test.h"
int test(char *URL)
{
CURL *curl;
CURLcode res=CURLE_OK;
curl = curl_easy_init();
if(curl) {
/* First set the URL that is about to receive our POST. */
curl_easy_setopt(curl, CURLOPT_URL, URL);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, NULL);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); /* show verbose for debug */
curl_easy_setopt(curl, CURLOPT_HEADER, 1); /* include header */
/* Now, we should be making a zero byte POST request */
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return (int)res;
}