From a2314225e02ea2f3bd49dc8557f2452846e49b19 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 31 Mar 2008 10:02:23 +0000 Subject: - Added CURLFORM_STREAM as a supported option to curl_formadd() to allow an application to provide data for a multipart with the read callback. Note that the size needs to be provided with CURLFORM_CONTENTSLENGTH when the stream option is used. This feature is verified by the new test case 554. This feature was sponsored by Xponaut. --- tests/data/test554 | 68 ++++++++++++++++++++++++ tests/libtest/Makefile.am | 4 +- tests/libtest/lib554.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 tests/data/test554 create mode 100644 tests/libtest/lib554.c (limited to 'tests') diff --git a/tests/data/test554 b/tests/data/test554 new file mode 100644 index 000000000..134f7ef97 --- /dev/null +++ b/tests/data/test554 @@ -0,0 +1,68 @@ + +# +# Server-side + + +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 + + + +# Client-side + + +http + +# tool is what to use instead of 'curl' + +lib554 + + + +HTTP multi-part formpost using read callback for the file part + + +http://%HOSTIP:%HTTPPORT/554 + + + +# +# Verify data after the test has been "shot" + + +s/^------------------------------[a-z0-9]*/------------------------------/ +s/boundary=----------------------------[a-z0-9]*/boundary=----------------------------/ + +# Note that the stripping above removes 12 bytes from every occurance of the +# boundary string and since 4 of them are in the body contents, we see +# 415 - (4*12) here == 367 bytes. + +POST /554 HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +Accept: */* +Content-Length: 415 +Expect: 100-continue +Content-Type: multipart/form-data; boundary=---------------------------- + +------------------------------ +Content-Disposition: form-data; name="sendfile"; filename="postit2.c" + +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 +-------------------------------- + + + diff --git a/tests/libtest/Makefile.am b/tests/libtest/Makefile.am index 8a9e3a42e..c6e6910cf 100644 --- a/tests/libtest/Makefile.am +++ b/tests/libtest/Makefile.am @@ -48,7 +48,7 @@ noinst_PROGRAMS = lib500 lib501 lib502 lib503 lib504 lib505 lib506 \ lib507 lib508 lib510 lib511 lib512 lib513 lib514 lib515 lib516 \ lib517 lib518 lib519 lib520 lib521 lib523 lib524 lib525 lib526 lib527 \ lib529 lib530 lib532 lib533 lib536 lib537 lib540 lib541 lib542 lib543 \ - lib544 lib545 lib547 lib548 lib549 lib552 lib553 + lib544 lib545 lib547 lib548 lib549 lib552 lib553 lib554 # Dependencies (may need to be overriden) LDADD = $(LIBDIR)/libcurl.la @@ -147,3 +147,5 @@ lib549_SOURCES = lib549.c $(SUPPORTFILES) lib552_SOURCES = lib552.c $(SUPPORTFILES) lib553_SOURCES = lib553.c $(SUPPORTFILES) + +lib554_SOURCES = lib554.c $(SUPPORTFILES) diff --git a/tests/libtest/lib554.c b/tests/libtest/lib554.c new file mode 100644 index 000000000..f04bc811a --- /dev/null +++ b/tests/libtest/lib554.c @@ -0,0 +1,130 @@ +/***************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * $Id$ + */ + +#include "test.h" + +static char data[]="this is what we post to the silly web server\n"; + +struct WriteThis { + char *readptr; + size_t sizeleft; +}; + +static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp) +{ + struct WriteThis *pooh = (struct WriteThis *)userp; + + if(size*nmemb < 1) + return 0; + + if(pooh->sizeleft) { + *(char *)ptr = pooh->readptr[0]; /* copy one single byte */ + pooh->readptr++; /* advance pointer */ + pooh->sizeleft--; /* less data left */ + return 1; /* we return 1 byte at a time! */ + } + + return 0; /* no more data left to deliver */ +} + +int test(char *URL) +{ + CURL *curl; + CURLcode res=CURLE_OK; + CURLFORMcode formrc; + + struct curl_httppost *formpost=NULL; + struct curl_httppost *lastptr=NULL; + struct WriteThis pooh; + + pooh.readptr = data; + pooh.sizeleft = strlen(data); + + curl_global_init(CURL_GLOBAL_ALL); + + /* Fill in the file upload field */ + formrc = curl_formadd(&formpost, + &lastptr, + CURLFORM_COPYNAME, "sendfile", + CURLFORM_STREAM, &pooh, + CURLFORM_CONTENTSLENGTH, pooh.sizeleft, + CURLFORM_FILENAME, "postit2.c", + CURLFORM_END); + + if(formrc) + printf("curl_formadd(1) = %d\n", formrc); + + /* Fill in the filename field */ + formrc = curl_formadd(&formpost, + &lastptr, + CURLFORM_COPYNAME, "filename", + CURLFORM_COPYCONTENTS, "postit2.c", + CURLFORM_END); + + if(formrc) + printf("curl_formadd(2) = %d\n", formrc); + + /* Fill in a submit field too */ + formrc = curl_formadd(&formpost, + &lastptr, + CURLFORM_COPYNAME, "submit", + CURLFORM_COPYCONTENTS, "send", + CURLFORM_END); + + if(formrc) + printf("curl_formadd(3) = %d\n", formrc); + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* First set the URL that is about to receive our POST. */ + curl_easy_setopt(curl, CURLOPT_URL, URL); + + /* Now specify we want to POST data */ + curl_easy_setopt(curl, CURLOPT_POST, TRUE); + + /* Set the expected POST size */ + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)pooh.sizeleft); + + /* we want to use our own read function */ + curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); + + /* pointer to pass to our read function */ + curl_easy_setopt(curl, CURLOPT_READDATA, &pooh); + + /* send a multi-part formpost */ + curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); + + /* get verbose debug output please */ + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); + + /* include headers in the output */ + curl_easy_setopt(curl, CURLOPT_HEADER, TRUE); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + + /* always cleanup */ + curl_easy_cleanup(curl); + curl_global_cleanup(); + + /* now cleanup the formpost chain */ + curl_formfree(formpost); + + return res; +} -- cgit v1.2.3