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.
|
||||
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.
|
||||
.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
|
||||
(This option is deprecated. Use \fICURLFORM_CONTENTLEN\fP instead!)
|
||||
|
||||
followed by a long giving the length of the contents. Note that for
|
||||
\fICURLFORM_STREAM\fP contents, this option is mandatory.
|
||||
|
||||
|
@ -164,6 +164,7 @@ CURLFORM_BUFFER 7.9.8
|
||||
CURLFORM_BUFFERLENGTH 7.9.8
|
||||
CURLFORM_BUFFERPTR 7.9.8
|
||||
CURLFORM_CONTENTHEADER 7.9.3
|
||||
CURLFORM_CONTENTLEN 7.46.0
|
||||
CURLFORM_CONTENTSLENGTH 7.9
|
||||
CURLFORM_CONTENTTYPE 7.9
|
||||
CURLFORM_COPYCONTENTS 7.9
|
||||
@ -678,6 +679,7 @@ CURL_GLOBAL_DEFAULT 7.8
|
||||
CURL_GLOBAL_NOTHING 7.8
|
||||
CURL_GLOBAL_SSL 7.8
|
||||
CURL_GLOBAL_WIN32 7.8.1
|
||||
CURL_HTTPPOST_LARGE 7.46.0
|
||||
CURL_HTTP_VERSION_1_0 7.9.1
|
||||
CURL_HTTP_VERSION_1_1 7.9.1
|
||||
CURL_HTTP_VERSION_2 7.43.0
|
||||
|
@ -127,7 +127,8 @@ struct curl_httppost {
|
||||
char *name; /* pointer to allocated name */
|
||||
long namelength; /* length of name length */
|
||||
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 */
|
||||
long bufferlength; /* length of buffer field */
|
||||
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
|
||||
pass the given pointer as custom pointer */
|
||||
#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
|
||||
actual file name will be used (if this
|
||||
is a file part) */
|
||||
void *userp; /* custom pointer used for
|
||||
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
|
||||
@ -1835,6 +1841,7 @@ typedef enum {
|
||||
CFINIT(OBSOLETE2),
|
||||
|
||||
CFINIT(STREAM),
|
||||
CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */
|
||||
|
||||
CURLFORM_LASTENTRY /* the last unused */
|
||||
} CURLformoption;
|
||||
|
@ -77,7 +77,7 @@ static char *formboundary(struct SessionHandle *data);
|
||||
***************************************************************************/
|
||||
static struct curl_httppost *
|
||||
AddHttpPost(char *name, size_t namelength,
|
||||
char *value, size_t contentslength,
|
||||
char *value, curl_off_t contentslength,
|
||||
char *buffer, size_t bufferlength,
|
||||
char *contenttype,
|
||||
long flags,
|
||||
@ -93,14 +93,14 @@ AddHttpPost(char *name, size_t namelength,
|
||||
post->name = name;
|
||||
post->namelength = (long)(name?(namelength?namelength:strlen(name)):0);
|
||||
post->contents = value;
|
||||
post->contentslength = (long)contentslength;
|
||||
post->contentlen = contentslength;
|
||||
post->buffer = buffer;
|
||||
post->bufferlength = (long)bufferlength;
|
||||
post->contenttype = contenttype;
|
||||
post->contentheader = contentHeader;
|
||||
post->showfilename = showfilename;
|
||||
post->userp = userp,
|
||||
post->flags = flags;
|
||||
post->flags = flags | CURL_HTTPPOST_LARGE;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
@ -380,11 +380,14 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
}
|
||||
break;
|
||||
case CURLFORM_CONTENTSLENGTH:
|
||||
if(current_form->contentslength)
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else
|
||||
current_form->contentslength =
|
||||
array_state?(size_t)array_value:(size_t)va_arg(params, long);
|
||||
current_form->contentslength =
|
||||
array_state?(size_t)array_value:(size_t)va_arg(params, long);
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
/* Get contents from a given file name */
|
||||
@ -661,9 +664,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
|
||||
HTTPPOST_CALLBACK)) && form->value) {
|
||||
/* copy value (without strdup; possibly contains null characters) */
|
||||
form->value = Curl_memdup(form->value, form->contentslength?
|
||||
form->contentslength:
|
||||
strlen(form->value)+1);
|
||||
size_t clen = (size_t) form->contentslength;
|
||||
if(!clen)
|
||||
clen = strlen(form->value)+1;
|
||||
|
||||
form->value = Curl_memdup(form->value, clen);
|
||||
|
||||
if(!form->value) {
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
break;
|
||||
@ -816,7 +822,7 @@ static curl_off_t VmsSpecialSize(const char * name,
|
||||
static CURLcode AddFormData(struct FormData **formp,
|
||||
enum formtype type,
|
||||
const void *line,
|
||||
size_t length,
|
||||
curl_off_t length,
|
||||
curl_off_t *size)
|
||||
{
|
||||
struct FormData *newform = malloc(sizeof(struct FormData));
|
||||
@ -1306,15 +1312,16 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
||||
result = AddFormData(&form, FORM_CONTENT, post->buffer,
|
||||
post->bufferlength, &size);
|
||||
else if(post->flags & HTTPPOST_CALLBACK)
|
||||
/* the contents should be read with the callback and the size
|
||||
is set with the contentslength */
|
||||
/* the contents should be read with the callback and the size is set
|
||||
with the contentslength */
|
||||
result = AddFormData(&form, FORM_CALLBACK, post->userp,
|
||||
post->contentslength, &size);
|
||||
post->flags&CURL_HTTPPOST_LARGE?
|
||||
post->contentlen:post->contentslength, &size);
|
||||
else
|
||||
/* include the contents we got */
|
||||
result = AddFormData(&form, FORM_CONTENT, post->contents,
|
||||
post->contentslength, &size);
|
||||
|
||||
post->flags&CURL_HTTPPOST_LARGE?
|
||||
post->contentlen:post->contentslength, &size);
|
||||
file = file->more;
|
||||
} 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
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -54,7 +54,7 @@ typedef struct FormInfo {
|
||||
size_t namelength;
|
||||
char *value;
|
||||
bool value_alloc;
|
||||
size_t contentslength;
|
||||
curl_off_t contentslength;
|
||||
char *contenttype;
|
||||
bool contenttype_alloc;
|
||||
long flags;
|
||||
|
@ -18,6 +18,22 @@ Content-Type: text/html
|
||||
|
||||
hello
|
||||
</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>
|
||||
|
||||
# Client-side
|
||||
@ -78,6 +94,37 @@ send
|
||||
Content-Disposition: form-data; name="somename"; filename="somefile.txt"
|
||||
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
|
||||
--------------------------------
|
||||
</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
|
||||
* 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
|
||||
}
|
||||
|
||||
int test(char *URL)
|
||||
static int once(char *URL, bool oldstyle)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res=CURLE_OK;
|
||||
@ -75,22 +75,29 @@ int test(char *URL)
|
||||
struct WriteThis pooh;
|
||||
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.sizeleft = strlen(data);
|
||||
|
||||
/* Fill in the file upload field */
|
||||
formrc = curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "sendfile",
|
||||
CURLFORM_STREAM, &pooh,
|
||||
CURLFORM_CONTENTSLENGTH, (long)pooh.sizeleft,
|
||||
CURLFORM_FILENAME, "postit2.c",
|
||||
CURLFORM_END);
|
||||
if(oldstyle) {
|
||||
formrc = curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "sendfile",
|
||||
CURLFORM_STREAM, &pooh,
|
||||
CURLFORM_CONTENTSLENGTH, (long)pooh.sizeleft,
|
||||
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)
|
||||
printf("curl_formadd(1) = %d\n", (int)formrc);
|
||||
@ -190,10 +197,27 @@ test_cleanup:
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
/* now cleanup the formpost chain */
|
||||
curl_formfree(formpost);
|
||||
|
||||
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