mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
parent
49a991346e
commit
ca5f9341ef
@ -83,7 +83,18 @@ to send away. libcurl will use the pointer and refer to the data in your
|
|||||||
application, so you must make sure it remains until curl no longer needs it.
|
application, so you must make sure it remains until curl no longer needs it.
|
||||||
If the data isn't NUL-terminated, or if you'd like it to contain zero bytes,
|
If the data isn't NUL-terminated, or if you'd like it to contain zero bytes,
|
||||||
you must set its length with \fBCURLFORM_CONTENTSLENGTH\fP.
|
you must set its length with \fBCURLFORM_CONTENTSLENGTH\fP.
|
||||||
|
.IP CURLFORM_CONTENTLEN
|
||||||
|
followed by a curl_off_t value giving the length of the contents. Note that
|
||||||
|
for \fICURLFORM_STREAM\fP contents, this option is mandatory.
|
||||||
|
|
||||||
|
If you pass a 0 (zero) for this option, libcurl will instead do a strlen() on
|
||||||
|
the contents to figure out the size. If you really want to send a zero byte
|
||||||
|
content then you must make sure strlen() on the data pointer returns zero.
|
||||||
|
|
||||||
|
(Option added in 7.46.0)
|
||||||
.IP CURLFORM_CONTENTSLENGTH
|
.IP CURLFORM_CONTENTSLENGTH
|
||||||
|
(This option is deprecated. Use \fICURLFORM_CONTENTLEN\fP instead!)
|
||||||
|
|
||||||
followed by a long giving the length of the contents. Note that for
|
followed by a long giving the length of the contents. Note that for
|
||||||
\fICURLFORM_STREAM\fP contents, this option is mandatory.
|
\fICURLFORM_STREAM\fP contents, this option is mandatory.
|
||||||
|
|
||||||
|
@ -164,6 +164,7 @@ CURLFORM_BUFFER 7.9.8
|
|||||||
CURLFORM_BUFFERLENGTH 7.9.8
|
CURLFORM_BUFFERLENGTH 7.9.8
|
||||||
CURLFORM_BUFFERPTR 7.9.8
|
CURLFORM_BUFFERPTR 7.9.8
|
||||||
CURLFORM_CONTENTHEADER 7.9.3
|
CURLFORM_CONTENTHEADER 7.9.3
|
||||||
|
CURLFORM_CONTENTLEN 7.46.0
|
||||||
CURLFORM_CONTENTSLENGTH 7.9
|
CURLFORM_CONTENTSLENGTH 7.9
|
||||||
CURLFORM_CONTENTTYPE 7.9
|
CURLFORM_CONTENTTYPE 7.9
|
||||||
CURLFORM_COPYCONTENTS 7.9
|
CURLFORM_COPYCONTENTS 7.9
|
||||||
@ -678,6 +679,7 @@ CURL_GLOBAL_DEFAULT 7.8
|
|||||||
CURL_GLOBAL_NOTHING 7.8
|
CURL_GLOBAL_NOTHING 7.8
|
||||||
CURL_GLOBAL_SSL 7.8
|
CURL_GLOBAL_SSL 7.8
|
||||||
CURL_GLOBAL_WIN32 7.8.1
|
CURL_GLOBAL_WIN32 7.8.1
|
||||||
|
CURL_HTTPPOST_LARGE 7.46.0
|
||||||
CURL_HTTP_VERSION_1_0 7.9.1
|
CURL_HTTP_VERSION_1_0 7.9.1
|
||||||
CURL_HTTP_VERSION_1_1 7.9.1
|
CURL_HTTP_VERSION_1_1 7.9.1
|
||||||
CURL_HTTP_VERSION_2 7.43.0
|
CURL_HTTP_VERSION_2 7.43.0
|
||||||
|
@ -127,7 +127,8 @@ struct curl_httppost {
|
|||||||
char *name; /* pointer to allocated name */
|
char *name; /* pointer to allocated name */
|
||||||
long namelength; /* length of name length */
|
long namelength; /* length of name length */
|
||||||
char *contents; /* pointer to allocated data contents */
|
char *contents; /* pointer to allocated data contents */
|
||||||
long contentslength; /* length of contents field */
|
long contentslength; /* length of contents field, see also
|
||||||
|
CURL_HTTPPOST_LARGE */
|
||||||
char *buffer; /* pointer to allocated buffer contents */
|
char *buffer; /* pointer to allocated buffer contents */
|
||||||
long bufferlength; /* length of buffer field */
|
long bufferlength; /* length of buffer field */
|
||||||
char *contenttype; /* Content-Type */
|
char *contenttype; /* Content-Type */
|
||||||
@ -152,12 +153,17 @@ struct curl_httppost {
|
|||||||
/* upload file contents by using the regular read callback to get the data and
|
/* upload file contents by using the regular read callback to get the data and
|
||||||
pass the given pointer as custom pointer */
|
pass the given pointer as custom pointer */
|
||||||
#define CURL_HTTPPOST_CALLBACK (1<<6)
|
#define CURL_HTTPPOST_CALLBACK (1<<6)
|
||||||
|
/* use size in 'contentlen', added in 7.46.0 */
|
||||||
|
#define CURL_HTTPPOST_LARGE (1<<7)
|
||||||
|
|
||||||
char *showfilename; /* The file name to show. If not set, the
|
char *showfilename; /* The file name to show. If not set, the
|
||||||
actual file name will be used (if this
|
actual file name will be used (if this
|
||||||
is a file part) */
|
is a file part) */
|
||||||
void *userp; /* custom pointer used for
|
void *userp; /* custom pointer used for
|
||||||
HTTPPOST_CALLBACK posts */
|
HTTPPOST_CALLBACK posts */
|
||||||
|
curl_off_t contentlen; /* alternative length of contents
|
||||||
|
field. Used if CURL_HTTPPOST_LARGE is
|
||||||
|
set. Added in 7.46.0 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered
|
/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered
|
||||||
@ -1835,6 +1841,7 @@ typedef enum {
|
|||||||
CFINIT(OBSOLETE2),
|
CFINIT(OBSOLETE2),
|
||||||
|
|
||||||
CFINIT(STREAM),
|
CFINIT(STREAM),
|
||||||
|
CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */
|
||||||
|
|
||||||
CURLFORM_LASTENTRY /* the last unused */
|
CURLFORM_LASTENTRY /* the last unused */
|
||||||
} CURLformoption;
|
} CURLformoption;
|
||||||
|
@ -77,7 +77,7 @@ static char *formboundary(struct SessionHandle *data);
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static struct curl_httppost *
|
static struct curl_httppost *
|
||||||
AddHttpPost(char *name, size_t namelength,
|
AddHttpPost(char *name, size_t namelength,
|
||||||
char *value, size_t contentslength,
|
char *value, curl_off_t contentslength,
|
||||||
char *buffer, size_t bufferlength,
|
char *buffer, size_t bufferlength,
|
||||||
char *contenttype,
|
char *contenttype,
|
||||||
long flags,
|
long flags,
|
||||||
@ -93,14 +93,14 @@ AddHttpPost(char *name, size_t namelength,
|
|||||||
post->name = name;
|
post->name = name;
|
||||||
post->namelength = (long)(name?(namelength?namelength:strlen(name)):0);
|
post->namelength = (long)(name?(namelength?namelength:strlen(name)):0);
|
||||||
post->contents = value;
|
post->contents = value;
|
||||||
post->contentslength = (long)contentslength;
|
post->contentlen = contentslength;
|
||||||
post->buffer = buffer;
|
post->buffer = buffer;
|
||||||
post->bufferlength = (long)bufferlength;
|
post->bufferlength = (long)bufferlength;
|
||||||
post->contenttype = contenttype;
|
post->contenttype = contenttype;
|
||||||
post->contentheader = contentHeader;
|
post->contentheader = contentHeader;
|
||||||
post->showfilename = showfilename;
|
post->showfilename = showfilename;
|
||||||
post->userp = userp,
|
post->userp = userp,
|
||||||
post->flags = flags;
|
post->flags = flags | CURL_HTTPPOST_LARGE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -380,11 +380,14 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CURLFORM_CONTENTSLENGTH:
|
case CURLFORM_CONTENTSLENGTH:
|
||||||
if(current_form->contentslength)
|
current_form->contentslength =
|
||||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
array_state?(size_t)array_value:(size_t)va_arg(params, long);
|
||||||
else
|
break;
|
||||||
current_form->contentslength =
|
|
||||||
array_state?(size_t)array_value:(size_t)va_arg(params, long);
|
case CURLFORM_CONTENTLEN:
|
||||||
|
current_form->flags |= CURL_HTTPPOST_LARGE;
|
||||||
|
current_form->contentslength =
|
||||||
|
array_state?(curl_off_t)array_value:va_arg(params, curl_off_t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Get contents from a given file name */
|
/* Get contents from a given file name */
|
||||||
@ -661,9 +664,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
|
HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
|
||||||
HTTPPOST_CALLBACK)) && form->value) {
|
HTTPPOST_CALLBACK)) && form->value) {
|
||||||
/* copy value (without strdup; possibly contains null characters) */
|
/* copy value (without strdup; possibly contains null characters) */
|
||||||
form->value = Curl_memdup(form->value, form->contentslength?
|
size_t clen = (size_t) form->contentslength;
|
||||||
form->contentslength:
|
if(!clen)
|
||||||
strlen(form->value)+1);
|
clen = strlen(form->value)+1;
|
||||||
|
|
||||||
|
form->value = Curl_memdup(form->value, clen);
|
||||||
|
|
||||||
if(!form->value) {
|
if(!form->value) {
|
||||||
return_value = CURL_FORMADD_MEMORY;
|
return_value = CURL_FORMADD_MEMORY;
|
||||||
break;
|
break;
|
||||||
@ -816,7 +822,7 @@ static curl_off_t VmsSpecialSize(const char * name,
|
|||||||
static CURLcode AddFormData(struct FormData **formp,
|
static CURLcode AddFormData(struct FormData **formp,
|
||||||
enum formtype type,
|
enum formtype type,
|
||||||
const void *line,
|
const void *line,
|
||||||
size_t length,
|
curl_off_t length,
|
||||||
curl_off_t *size)
|
curl_off_t *size)
|
||||||
{
|
{
|
||||||
struct FormData *newform = malloc(sizeof(struct FormData));
|
struct FormData *newform = malloc(sizeof(struct FormData));
|
||||||
@ -1306,15 +1312,16 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
|||||||
result = AddFormData(&form, FORM_CONTENT, post->buffer,
|
result = AddFormData(&form, FORM_CONTENT, post->buffer,
|
||||||
post->bufferlength, &size);
|
post->bufferlength, &size);
|
||||||
else if(post->flags & HTTPPOST_CALLBACK)
|
else if(post->flags & HTTPPOST_CALLBACK)
|
||||||
/* the contents should be read with the callback and the size
|
/* the contents should be read with the callback and the size is set
|
||||||
is set with the contentslength */
|
with the contentslength */
|
||||||
result = AddFormData(&form, FORM_CALLBACK, post->userp,
|
result = AddFormData(&form, FORM_CALLBACK, post->userp,
|
||||||
post->contentslength, &size);
|
post->flags&CURL_HTTPPOST_LARGE?
|
||||||
|
post->contentlen:post->contentslength, &size);
|
||||||
else
|
else
|
||||||
/* include the contents we got */
|
/* include the contents we got */
|
||||||
result = AddFormData(&form, FORM_CONTENT, post->contents,
|
result = AddFormData(&form, FORM_CONTENT, post->contents,
|
||||||
post->contentslength, &size);
|
post->flags&CURL_HTTPPOST_LARGE?
|
||||||
|
post->contentlen:post->contentslength, &size);
|
||||||
file = file->more;
|
file = file->more;
|
||||||
} while(file && !result); /* for each specified file for this field */
|
} while(file && !result); /* for each specified file for this field */
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -54,7 +54,7 @@ typedef struct FormInfo {
|
|||||||
size_t namelength;
|
size_t namelength;
|
||||||
char *value;
|
char *value;
|
||||||
bool value_alloc;
|
bool value_alloc;
|
||||||
size_t contentslength;
|
curl_off_t contentslength;
|
||||||
char *contenttype;
|
char *contenttype;
|
||||||
bool contenttype_alloc;
|
bool contenttype_alloc;
|
||||||
long flags;
|
long flags;
|
||||||
|
@ -18,6 +18,22 @@ Content-Type: text/html
|
|||||||
|
|
||||||
hello
|
hello
|
||||||
</data>
|
</data>
|
||||||
|
<datacheck>
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake swsclose
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
hello
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake swsclose
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
hello
|
||||||
|
</datacheck>
|
||||||
</reply>
|
</reply>
|
||||||
|
|
||||||
# Client-side
|
# Client-side
|
||||||
@ -78,6 +94,37 @@ send
|
|||||||
Content-Disposition: form-data; name="somename"; filename="somefile.txt"
|
Content-Disposition: form-data; name="somename"; filename="somefile.txt"
|
||||||
Content-Type: text/plain
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
blah blah
|
||||||
|
--------------------------------
|
||||||
|
POST /554 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
Content-Length: 732
|
||||||
|
Expect: 100-continue
|
||||||
|
Content-Type: multipart/form-data; boundary=----------------------------
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
Content-Disposition: form-data; name="sendfile alternative"; filename="file name 2"
|
||||||
|
|
||||||
|
this is what we post to the silly web server
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
Content-Disposition: form-data; name="callbackdata"
|
||||||
|
|
||||||
|
this is what we post to the silly web server
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
Content-Disposition: form-data; name="filename"
|
||||||
|
|
||||||
|
postit2.c
|
||||||
|
------------------------------
|
||||||
|
Content-Disposition: form-data; name="submit"
|
||||||
|
|
||||||
|
send
|
||||||
|
------------------------------
|
||||||
|
Content-Disposition: form-data; name="somename"; filename="somefile.txt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
blah blah
|
blah blah
|
||||||
--------------------------------
|
--------------------------------
|
||||||
</protocol>
|
</protocol>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -64,7 +64,7 @@ static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int test(char *URL)
|
static int once(char *URL, bool oldstyle)
|
||||||
{
|
{
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
CURLcode res=CURLE_OK;
|
CURLcode res=CURLE_OK;
|
||||||
@ -75,22 +75,29 @@ int test(char *URL)
|
|||||||
struct WriteThis pooh;
|
struct WriteThis pooh;
|
||||||
struct WriteThis pooh2;
|
struct WriteThis pooh2;
|
||||||
|
|
||||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
pooh.readptr = data;
|
pooh.readptr = data;
|
||||||
pooh.sizeleft = strlen(data);
|
pooh.sizeleft = strlen(data);
|
||||||
|
|
||||||
/* Fill in the file upload field */
|
/* Fill in the file upload field */
|
||||||
formrc = curl_formadd(&formpost,
|
if(oldstyle) {
|
||||||
&lastptr,
|
formrc = curl_formadd(&formpost,
|
||||||
CURLFORM_COPYNAME, "sendfile",
|
&lastptr,
|
||||||
CURLFORM_STREAM, &pooh,
|
CURLFORM_COPYNAME, "sendfile",
|
||||||
CURLFORM_CONTENTSLENGTH, (long)pooh.sizeleft,
|
CURLFORM_STREAM, &pooh,
|
||||||
CURLFORM_FILENAME, "postit2.c",
|
CURLFORM_CONTENTSLENGTH, (long)pooh.sizeleft,
|
||||||
CURLFORM_END);
|
CURLFORM_FILENAME, "postit2.c",
|
||||||
|
CURLFORM_END);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* new style */
|
||||||
|
formrc = curl_formadd(&formpost,
|
||||||
|
&lastptr,
|
||||||
|
CURLFORM_COPYNAME, "sendfile alternative",
|
||||||
|
CURLFORM_STREAM, &pooh,
|
||||||
|
CURLFORM_CONTENTLEN, (curl_off_t)pooh.sizeleft,
|
||||||
|
CURLFORM_FILENAME, "file name 2",
|
||||||
|
CURLFORM_END);
|
||||||
|
}
|
||||||
|
|
||||||
if(formrc)
|
if(formrc)
|
||||||
printf("curl_formadd(1) = %d\n", (int)formrc);
|
printf("curl_formadd(1) = %d\n", (int)formrc);
|
||||||
@ -190,10 +197,27 @@ test_cleanup:
|
|||||||
|
|
||||||
/* always cleanup */
|
/* always cleanup */
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
curl_global_cleanup();
|
|
||||||
|
|
||||||
/* now cleanup the formpost chain */
|
/* now cleanup the formpost chain */
|
||||||
curl_formfree(formpost);
|
curl_formfree(formpost);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test(char *URL)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||||
|
fprintf(stderr, "curl_global_init() failed\n");
|
||||||
|
return TEST_ERR_MAJOR_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = once(URL, TRUE); /* old */
|
||||||
|
if(!res)
|
||||||
|
res = once(URL, FALSE); /* new */
|
||||||
|
|
||||||
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user