On Mon, Mar 7, 2016 at 12:10 AM, Waitman Gobble <[email protected]> wrote: > On Sun, Mar 6, 2016 at 11:43 PM, Ray Satiro via curl-library > <[email protected]> wrote: >> On 3/7/2016 1:15 AM, Waitman Gobble wrote: >>> >>> When I set Content-Type header to multipart/form-data and add data to >>> CURLOPT_POSTFIELDS it seems to hang. I thought maybe proxy issue but >>> tried with/without. >>> 1) If sending simple string like a=foo&j=boo then there isn't an issue >>> 2) If I don't set Content-Length then it doesn't hang, makes the post. >>> However receiving side doesn't get data (content length 172 but should >>> be 134610 >>> >>> Thanks for any help or pointers. >>> >>> >>> system, >>> >>> FreeBSD ob4.cloudqx.com 10.2-RELEASE-p9 FreeBSD 10.2-RELEASE-p9 #0: >>> >>> curl-7.47.0 from ports >>> >>> >>> #include <iostream> >>> #include <fstream> >>> #include <string> >>> #include <curl/curl.h> >>> >>> using namespace std; >>> >>> int main(void) { >>> >>> CURL *conn = NULL; >>> curl_global_init(CURL_GLOBAL_DEFAULT); >>> >>> conn = curl_easy_init(); >>> static char errorBuffer[CURL_ERROR_SIZE]; >>> >>> curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer); >>> //curl_easy_setopt(conn, CURLOPT_URL, >>> "http://wp.amodaco.com/filepost.php"); >>> curl_easy_setopt(conn, CURLOPT_HEADER, 1L); >>> //curl_easy_setopt(conn, CURLOPT_PROXY, "http://127.0.0.1"); >>> //curl_easy_setopt(conn, CURLOPT_PROXYPORT, 3128); >>> >>> curl_easy_setopt(conn, CURLOPT_URL, >>> "https://hub.zilla.tech/filepost.php"); >>> >>> char* post_string; >>> int post_size; >>> ifstream file; >>> file.open("/c/nginx/0/11/0000000110",ios_base::binary); >>> //file.open("/c/nginx/7/10/0000000107",ios_base::binary); >>> file.seekg(0,ios::end); >>> post_size = file.tellg(); >>> file.seekg(0,ios::beg); >>> post_string = new char[post_size]; >>> file.read(post_string,post_size); >>> file.close(); >>> >>> struct curl_slist *chunk = NULL; >>> chunk = curl_slist_append(chunk, "Content-Type: multipart/form-data; >>> boundary=-----------------------------84927149120355803091994092429"); >>> std::string cl = "Content-Length: " + std::to_string(post_size); >>> chunk = curl_slist_append(chunk, cl.c_str()); >>> curl_easy_setopt(conn, CURLOPT_POSTFIELDS, post_string); >>> curl_easy_setopt(conn, CURLOPT_HTTPHEADER, chunk); >>> cout << "before perform\r\n"; >>> curl_easy_perform(conn); >>> curl_easy_cleanup(conn); >>> cout << "finis\r\n"; >>> cout << cl << "\r\n"; >>> >>> return(0); >>> } >>> >> >> Don't set those headers and if you want to do multipart don't use >> CURLOPT_POSTFIELDS, use CURLOPT_HTTPPOST [1] instead. Look at the EXAMPLE >> section it probably does what you need. Also review curl_formadd [2], If you >> have a particularly large file you'll need to use CURLFORM_STREAM and >> CURLOPT_READFUNCTION instead of loading the entire thing in memory. >> >> struct curl_httppost *formpost = NULL; >> struct curl_httppost *lastptr = NULL; >> >> <curl_formadd calls> >> >> curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); >> >> >> As an aside, if you don't want multipart and you use CURLOPT_POSTFIELDS and >> pass it binary data set the size using CURLOPT_POSTFIELDSIZE [3] or >> CURLOPT_POSTFIELDSIZE_LARGE [4] and make sure you use exactly the type >> specified, for example: >> >> curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)post_size); >> or >> curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)post_size); >> >> >> [1]: https://curl.haxx.se/libcurl/c/CURLOPT_HTTPPOST.html >> [2]: https://curl.haxx.se/libcurl/c/curl_formadd.html >> [3]: https://curl.haxx.se/libcurl/c/CURLOPT_POSTFIELDSIZE.html >> [4]: https://curl.haxx.se/libcurl/c/CURLOPT_POSTFIELDSIZE_LARGE.html >> >> >> >> ------------------------------------------------------------------- >> List admin: https://cool.haxx.se/list/listinfo/curl-library >> Etiquette: https://curl.haxx.se/mail/etiquette.html > > Thanks for the replies, I will read through them and figure it out. I > really appreciate it. > I didn't post the entire file. > > One thing I think the problem is in lib/http.c > > else if(data->set.postfields) > expectsend = (curl_off_t)strlen(data->set.postfields); > > strlen is wrong, the binary data has a character that cuts it off at > byte 172, the string is actually much bigger. > > The documentation states that curl will use strlen if POSTFIELDSIZE is > not provided. But it looks like it's using strlen anyway.. :( > I'm guessing that' why it's sitting there until the end of time? > > using the form struct doesn't look like it will help. I don't see how > to put "already" formatted data into the struct.. Basically I'd have > to regurgitate the data and break it into objects and feed back into > the form api, which seems not so good. But perhaps I'm mistaken. > > > > > -- > Waitman Gobble > Los Altos California USA > 650-900-8557
example: ... post_size = ftell(fp); rewind(fp); post_string = (char *)malloc((post_size+1)*sizeof(char)); size_t checklen = fread(post_string, 1, post_size, fp); fclose(fp); cout << "check len " << checklen << " post size " << post_size << " strlen " << (long)strlen(post_string) << "\r\n"; check len 134610 post size 134610 strlen 172 -- Waitman Gobble Los Altos California USA 650-900-8557 ------------------------------------------------------------------- List admin: https://cool.haxx.se/list/listinfo/curl-library Etiquette: https://curl.haxx.se/mail/etiquette.html
