JNIEXPORT jint JNICALL Java_com_netbirdtech_libcurl_Curl_setFormdataNative (JNIEnv* env, jobject obj, jlong handle, jobjectArray multi_array) { Holder* holder = (Holder*) handle; if (holder == NULL) { return 0; } CURL* curl = holder->getCurl(); struct curl_httppost* post = holder->getPost();; struct curl_httppost* last = NULL; // clear all if (post != NULL) { //LOGD("clear previous form."); curl_formfree(post); post = NULL; } if (multi_array != NULL) { CURLFORMcode code; int len = env->GetArrayLength(multi_array); //LOGD("set name/parts size=%d", len); for (int i = 0; i < len; i++) { //LOGV("."); jobject part = env->GetObjectArrayElement(multi_array, i); jstring name = (jstring) env->CallObjectMethod(part, MID_MultiPart_get_name); jstring filename = (jstring) env->CallObjectMethod(part, MID_MultiPart_get_filename); jstring content_type = (jstring) env->CallObjectMethod(part, MID_MultiPart_get_content_type); jbyteArray content = (jbyteArray) env->CallObjectMethod(part, MID_MultiPart_get_content); jbyte* bytes = env->GetByteArrayElements(content, 0); int content_length = env->GetArrayLength(content); holder->addByteArrayGlobalRefs(env->NewGlobalRef(content), (const char*)bytes); // release after perform const char* name_str = env->GetStringUTFChars(name, 0); // content_type and filename may be null if (content_type == NULL && filename == NULL) { code = curl_formadd(&post, &last, CURLFORM_COPYNAME, name_str, CURLFORM_BUFFER, "file.dat", CURLFORM_BUFFERPTR, bytes, CURLFORM_BUFFERLENGTH, content_length, CURLFORM_END); } else if (content_type == NULL) { const char* filename_str = env->GetStringUTFChars(filename, 0); code = curl_formadd(&post, &last, CURLFORM_COPYNAME, name_str, CURLFORM_BUFFER, filename_str, CURLFORM_BUFFERPTR, bytes, CURLFORM_BUFFERLENGTH, content_length, CURLFORM_END); env->ReleaseStringUTFChars(filename, filename_str); } else if (filename == NULL) { const char* content_type_str = env->GetStringUTFChars(content_type, 0); code = curl_formadd(&post, &last, CURLFORM_COPYNAME, name_str, CURLFORM_BUFFER, "file.dat", CURLFORM_CONTENTTYPE, content_type_str, CURLFORM_BUFFERPTR, bytes, CURLFORM_BUFFERLENGTH, content_length, CURLFORM_END); env->ReleaseStringUTFChars(content_type, content_type_str); } else { const char* filename_str = env->GetStringUTFChars(filename, 0); const char* content_type_str = env->GetStringUTFChars(content_type, 0); code = curl_formadd(&post, &last, CURLFORM_COPYNAME, name_str, CURLFORM_BUFFER, filename_str, CURLFORM_CONTENTTYPE, content_type_str, CURLFORM_BUFFERPTR, bytes, CURLFORM_BUFFERLENGTH, content_length, CURLFORM_END); env->ReleaseStringUTFChars(filename, filename_str); env->ReleaseStringUTFChars(content_type, content_type_str); } env->ReleaseStringUTFChars(name, name_str); } if (code != CURL_FORMADD_OK) { ////LOGW("curl_formadd error %d", code); curl_formfree(post); // TODO return fromadd error or setopt error? return (int) code; } } if (post != NULL) { //LOGV("set_opt CURLOPT_HTTPPOST"); holder->setPost(post); return curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); } return 0; }
bool setOption(CURLoption option, T data) { return CURLE_OK == curl_easy_setopt(_curl, option, data); }
// blocking asset fetch which bypasses the VFS // this is a very limited function for use by the simstate loader and other one-offs S32 LLHTTPAssetStorage::getURLToFile(const LLUUID& uuid, LLAssetType::EType asset_type, const std::string &url, const std::string& filename, progress_callback callback, void *userdata) { // *NOTE: There is no guarantee that the uuid and the asset_type match // - not that it matters. - Doug lldebugs << "LLHTTPAssetStorage::getURLToFile() - " << url << llendl; FILE *fp = LLFile::fopen(filename, "wb"); /*Flawfinder: ignore*/ if (! fp) { llwarns << "Failed to open " << filename << " for writing" << llendl; return LL_ERR_ASSET_REQUEST_FAILED; } // make sure we use the normal curl setup, even though we don't really need a request object LLHTTPAssetRequest req(this, uuid, asset_type, RT_DOWNLOAD, url, mCurlMultiHandle); req.mFP = fp; req.setupCurlHandle(); curl_easy_setopt(req.mCurlHandle, CURLOPT_FOLLOWLOCATION, TRUE); curl_easy_setopt(req.mCurlHandle, CURLOPT_WRITEFUNCTION, &curlFileDownCallback); curl_easy_setopt(req.mCurlHandle, CURLOPT_WRITEDATA, req.mCurlHandle); curl_multi_add_handle(mCurlMultiHandle, req.mCurlHandle); llinfos << "Requesting as file " << req.mURLBuffer << llendl; // braindead curl loop int queue_length; CURLMsg *curl_msg; LLTimer timeout; timeout.setTimerExpirySec(GET_URL_TO_FILE_TIMEOUT); bool success = false; S32 xfer_result = 0; do { curl_multi_perform(mCurlMultiHandle, &queue_length); curl_msg = curl_multi_info_read(mCurlMultiHandle, &queue_length); if (callback) { callback(userdata); } if ( curl_msg && (CURLMSG_DONE == curl_msg->msg) ) { success = true; } else if (timeout.hasExpired()) { llwarns << "Request for " << url << " has timed out." << llendl; success = false; xfer_result = LL_ERR_ASSET_REQUEST_FAILED; break; } } while (!success); if (success) { long curl_result = 0; curl_easy_getinfo(curl_msg->easy_handle, CURLINFO_HTTP_CODE, &curl_result); if (curl_result == HTTP_OK && curl_msg->data.result == CURLE_OK) { S32 size = ftell(req.mFP); if (size > 0) { // everything seems to be in order llinfos << "Success downloading " << req.mURLBuffer << " to file, size " << size << llendl; } else { llwarns << "Found " << req.mURLBuffer << " to be zero size" << llendl; xfer_result = LL_ERR_ASSET_REQUEST_FAILED; } } else { xfer_result = curl_result == HTTP_MISSING ? LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE : LL_ERR_ASSET_REQUEST_FAILED; llinfos << "Failure downloading " << req.mURLBuffer << " with result " << curl_easy_strerror(curl_msg->data.result) << ", http result " << curl_result << llendl; } } fclose(fp); if (xfer_result) { LLFile::remove(filename); } return xfer_result; }
int main(void) { CURL *curl; CURLcode res; struct WriteThis pooh; pooh.readptr = data; pooh.sizeleft = strlen(data); curl = curl_easy_init(); if(curl) { /* First set the URL that is about to receive our POST. */ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/index.cgi"); /* Now specify we want to POST data */ curl_easy_setopt(curl, CURLOPT_POST, 1L); /* 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); /* get verbose debug output please */ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); /* If you use POST to a HTTP 1.1 server, you can send data without knowing the size before starting the POST if you use chunked encoding. You enable this by adding a header like "Transfer-Encoding: chunked" with CURLOPT_HTTPHEADER. With HTTP 1.0 or without chunked transfer, you must specify the size in the request. */ #ifdef USE_CHUNKED { struct curl_slist *chunk = NULL; chunk = curl_slist_append(chunk, "Transfer-Encoding: chunked"); res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk); /* use curl_slist_free_all() after the *perform() call to free this list again */ } #else /* Set the expected POST size. If you want to POST large amounts of data, consider CURLOPT_POSTFIELDSIZE_LARGE */ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, pooh.sizeleft); #endif #ifdef DISABLE_EXPECT /* Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header. You can disable this header with CURLOPT_HTTPHEADER as usual. NOTE: if you want chunked transfer too, you need to combine these two since you can only set one list of headers with CURLOPT_HTTPHEADER. */ /* A less good option would be to enforce HTTP 1.0, but that might also have other implications. */ { struct curl_slist *chunk = NULL; chunk = curl_slist_append(chunk, "Expect:"); res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk); /* use curl_slist_free_all() after the *perform() call to free this list again */ } #endif /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); /* always cleanup */ curl_easy_cleanup(curl); } return 0; }
void oc_curl_debug(OCstate* state) { curl_easy_setopt(state->curl,CURLOPT_VERBOSE,1); curl_easy_setopt(state->curl,CURLOPT_ERRORBUFFER,(void*)state->curlerror); }
bool Get_a_URL (_String& urls, _String* fileName) { #ifdef __HYPHYCURL__ CURL *curl; CURLcode res ; curl = curl_easy_init (); FILE * f = nil; _String* s = nil; char cErr [CURL_ERROR_SIZE+1]; if(curl) { if (fileName) { f = fopen (fileName->sData,"wb"); if (!f) { urls = _String ("Failed to open ") & *fileName & " for writing"; return false; } } else { s = new _String (8192, true); checkPointer (s); } curl_easy_setopt (curl, CURLOPT_URL, urls.sData ); curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, cErr); if (f) curl_easy_setopt (curl, CURLOPT_FILE, (void*)f); else curl_easy_setopt (curl, CURLOPT_FILE, (void*)s); _String ver (GetVersionString()); curl_easy_setopt (curl, CURLOPT_USERAGENT, ver.sData); //curl_easy_setopt (curl, CURLOPT_VERBOSE, 1); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, (void*)(f?url2File:url2String)); _Parameter vbl = 0.0; checkParameter (VerbosityLevelString,vbl,0.0); if (vbl<0.5) { curl_easy_setopt (curl,CURLOPT_NOPROGRESS,1); } res = curl_easy_perform (curl); curl_easy_cleanup (curl); if (f) fclose (f); else { s->Finalize(); urls = *s; DeleteObject (s); } if (!res) return true; } else { urls = "Failed to initialize CURL object"; return false; } urls = _String ("CURL error:") & (long)res & "." & cErr; return false; #else urls = "This feature requires libcurl"; return false; #endif }
static int testMultithreadedPut () { struct MHD_Daemon *d; CURL *c; char buf[2048]; struct CBC cbc; unsigned int pos = 0; int done_flag = 0; int i; cbc.buf = buf; cbc.size = 2048; cbc.pos = 0; d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION /* | MHD_USE_DEBUG */ , 11080, NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END); if (d == NULL) return 16; zzuf_socat_start (); for (i = 0; i < LOOP_COUNT; i++) { fprintf (stderr, "."); c = curl_easy_init (); curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11081/hello_world"); curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer); curl_easy_setopt (c, CURLOPT_READDATA, &pos); curl_easy_setopt (c, CURLOPT_UPLOAD, 1L); curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L); curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT); if (oneone) curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); else curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT); // NOTE: use of CONNECTTIMEOUT without also // setting NOSIGNAL results in really weird // crashes on my system! curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); curl_easy_perform (c); curl_easy_cleanup (c); } fprintf (stderr, "\n"); zzuf_socat_stop (); MHD_stop_daemon (d); return 0; }
//http://acm.hdu.edu.cn/status.php?first=&pid=1000&user=bnuvjudge&lang=1&status=0 bool getStatus(string pid,string lang,string & result,string& ce_info,string &tu,string &mu) { int begin=time(NULL); string runid; tu=mu="0"; string ts; int tried=0; while (true) { FILE * fp=fopen(tfilename,"w+"); curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "hdu.cookie"); string url=(string)"http://acm.hdu.edu.cn/status.php?first=&pid="+pid+"&user="******"&lang=&status=0"; //cout<<url; curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); res = curl_easy_perform(curl); curl_easy_cleanup(curl); } fclose(fp); if (res) return false; ts=getLineFromFile(tfilename,77); //cout<<ts; //writelog((char *)ts.c_str()); /*if (ts.find("alert(\"Login failed!)")!=string::npos) return false; */ if (ts.find("Connect(0) to MySQL Server failed.")!=string::npos||ts.find("<b>One or more following ERROR(s) occurred.")!=string::npos||ts.find("<h2>The requested URL could not be retrieved</h2>")!=string::npos||ts.find("PHP: Maximum execution time of")!=string::npos) { tried++; if (tried>=MAX_TRY_TIME) return false; continue; } runid=getRunid(ts); result=getResult(ts); cout << result<<endl<<runid<<endl; if (result.find("Waiting")==string::npos &&result.find("Running")==string::npos &&result.find("Judging")==string::npos &&result.find("Queuing")==string::npos &&result.find("Compiling")==string::npos &&result.find("\n")&&result!="") { break; } if (time(NULL)-begin>MAX_WAIT_TIME) break; } if (!(result.find("Waiting")==string::npos &&result.find("Running")==string::npos &&result.find("Judging")==string::npos &&result.find("Queuing")==string::npos &&result.find("Compiling")==string::npos)) return false; if (result=="Compilation Error") { //result="Compile Error"; ce_info=getCEinfo(runid); } else ce_info=""; tu=getUsedTime(ts); mu=getUsedMem(ts); /* if (result != "Accepted" && result[result.length()-1] == 'd') { result.erase(result.end()-2,result.end()); } */ return true; }
/* **************************************************************************** * * httpRequestSend - */ std::string httpRequestSend ( const std::string& _ip, unsigned short port, const std::string& protocol, const std::string& verb, const std::string& tenant, const std::string& servicePath, const std::string& xauthToken, const std::string& resource, const std::string& content_type, const std::string& content, bool useRush, bool waitForResponse, const std::string& acceptFormat, long timeoutInMilliseconds ) { char portAsString[16]; static unsigned long long callNo = 0; std::string result; std::string ip = _ip; struct curl_slist* headers = NULL; MemoryStruct* httpResponse = NULL; CURLcode res; int outgoingMsgSize = 0; CURL* curl; ++callNo; if (timeoutInMilliseconds == -1) { timeoutInMilliseconds = defaultTimeout; } LM_TRANSACTION_START("to", ip.c_str(), port, resource.c_str()); // Preconditions check if (port == 0) { LM_E(("Runtime Error (port is ZERO)")); LM_TRANSACTION_END(); return "error"; } if (ip.empty()) { LM_E(("Runtime Error (ip is empty)")); LM_TRANSACTION_END(); return "error"; } if (verb.empty()) { LM_E(("Runtime Error (verb is empty)")); LM_TRANSACTION_END(); return "error"; } if (resource.empty()) { LM_E(("Runtime Error (resource is empty)")); LM_TRANSACTION_END(); return "error"; } if ((content_type.empty()) && (!content.empty())) { LM_E(("Runtime Error (Content-Type is empty but there is actual content)")); LM_TRANSACTION_END(); return "error"; } if ((!content_type.empty()) && (content.empty())) { LM_E(("Runtime Error (Content-Type non-empty but there is no content)")); LM_TRANSACTION_END(); return "error"; } if ((curl = curl_easy_init()) == NULL) { LM_E(("Runtime Error (could not init libcurl)")); LM_TRANSACTION_END(); return "error"; } // Allocate to hold HTTP response httpResponse = new MemoryStruct; httpResponse->memory = (char*) malloc(1); // will grow as needed httpResponse->size = 0; // no data at this point // // Rush // Every call to httpRequestSend specifies whether RUSH should be used or not. // But, this depends also on how the broker was started, so here the 'useRush' // parameter is cancelled in case the broker was started without rush. // // If rush is to be used, the IP/port is stored in rushHeaderIP/rushHeaderPort and // after that, the host and port of rush is set as ip/port for the message, that is // now sent to rush instead of to its final destination. // Also, a few HTTP headers for rush must be setup. // if ((rushPort == 0) || (rushHost == "")) useRush = false; if (useRush) { char rushHeaderPortAsString[16]; uint16_t rushHeaderPort = 0; std::string rushHeaderIP = ""; std::string headerRushHttp = ""; rushHeaderIP = ip; rushHeaderPort = port; ip = rushHost; port = rushPort; snprintf(rushHeaderPortAsString, sizeof(rushHeaderPortAsString), "%d", rushHeaderPort); headerRushHttp = "X-relayer-host: " + rushHeaderIP + ":" + rushHeaderPortAsString; LM_T(LmtHttpHeaders, ("HTTP-HEADERS: '%s'", headerRushHttp.c_str())); headers = curl_slist_append(headers, headerRushHttp.c_str()); outgoingMsgSize += headerRushHttp.size(); if (protocol == "https:") { headerRushHttp = "X-relayer-protocol: https"; LM_T(LmtHttpHeaders, ("HTTP-HEADERS: '%s'", headerRushHttp.c_str())); headers = curl_slist_append(headers, headerRushHttp.c_str()); outgoingMsgSize += headerRushHttp.size(); } } snprintf(portAsString, sizeof(portAsString), "%d", port); // ----- User Agent char cvBuf[CURL_VERSION_MAX_LENGTH]; char headerUserAgent[HTTP_HEADER_USER_AGENT_MAX_LENGTH]; snprintf(headerUserAgent, sizeof(headerUserAgent), "User-Agent: orion/%s libcurl/%s", versionGet(), curlVersionGet(cvBuf, sizeof(cvBuf))); LM_T(LmtHttpHeaders, ("HTTP-HEADERS: '%s'", headerUserAgent)); headers = curl_slist_append(headers, headerUserAgent); outgoingMsgSize += strlen(headerUserAgent) + 1; // ----- Host char headerHost[HTTP_HEADER_HOST_MAX_LENGTH]; snprintf(headerHost, sizeof(headerHost), "Host: %s:%d", ip.c_str(), (int) port); LM_T(LmtHttpHeaders, ("HTTP-HEADERS: '%s'", headerHost)); headers = curl_slist_append(headers, headerHost); outgoingMsgSize += strlen(headerHost) + 1; // ----- Tenant if (tenant != "") { headers = curl_slist_append(headers, ("fiware-service: " + tenant).c_str()); outgoingMsgSize += tenant.size() + 16; // "fiware-service: " } // ----- Service-Path if (servicePath != "") { headers = curl_slist_append(headers, ("Fiware-ServicePath: " + servicePath).c_str()); outgoingMsgSize += servicePath.size() + strlen("Fiware-ServicePath: "); } // ----- X-Auth-Token if (xauthToken != "") { headers = curl_slist_append(headers, ("X-Auth-Token: " + xauthToken).c_str()); outgoingMsgSize += xauthToken.size() + strlen("X-Auth-Token: "); } // ----- Accept std::string acceptedFormats = "application/xml, application/json"; if (acceptFormat != "") { acceptedFormats = acceptFormat; } std::string acceptString = "Accept: " + acceptedFormats; headers = curl_slist_append(headers, acceptString.c_str()); outgoingMsgSize += acceptString.size(); // ----- Expect headers = curl_slist_append(headers, "Expect: "); outgoingMsgSize += 8; // from "Expect: " // ----- Content-length std::stringstream contentLengthStringStream; contentLengthStringStream << content.size(); std::string headerContentLength = "Content-length: " + contentLengthStringStream.str(); LM_T(LmtHttpHeaders, ("HTTP-HEADERS: '%s'", headerContentLength.c_str())); headers = curl_slist_append(headers, headerContentLength.c_str()); outgoingMsgSize += contentLengthStringStream.str().size() + 16; // from "Content-length: " outgoingMsgSize += content.size(); // ----- Content-type headers = curl_slist_append(headers, ("Content-type: " + content_type).c_str()); outgoingMsgSize += content_type.size() + 14; // from "Content-type: " // Check if total outgoing message size is too big if (outgoingMsgSize > MAX_DYN_MSG_SIZE) { LM_E(("Runtime Error (HTTP request to send is too large: %d bytes)", outgoingMsgSize)); // Cleanup curl environment curl_slist_free_all(headers); curl_easy_cleanup(curl); free(httpResponse->memory); delete httpResponse; LM_TRANSACTION_END(); return "error"; } // Contents const char* payload = content.c_str(); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (u_int8_t*) payload); // Set up URL std::string url; if (isIPv6(ip)) url = "[" + ip + "]"; else url = ip; url = url + ":" + portAsString + (resource.at(0) == '/'? "" : "/") + resource; // Prepare CURL handle with obtained options curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, verb.c_str()); // Set HTTP verb curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // Allow redirection (?) curl_easy_setopt(curl, CURLOPT_HEADER, 1); // Activate include the header in the body output curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // Put headers in place curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &writeMemoryCallback); // Send data here curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*) httpResponse); // Custom data for response handling // // Timeout // // The parameter timeoutInMilliseconds holds the timeout time in milliseconds. // If the timeout time requested is 0, then no timeuot is used. // if (timeoutInMilliseconds != 0) { curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, timeoutInMilliseconds); } // Synchronous HTTP request LM_T(LmtClientOutputPayload, ("Sending message %lu to HTTP server: sending message of %d bytes to HTTP server", callNo, outgoingMsgSize)); res = curl_easy_perform(curl); if (res != CURLE_OK) { // // NOTE: This log line is used by the functional tests in cases/880_timeout_for_forward_and_notifications/ // So, this line should not be removed/altered, at least not without also modifying the functests. // LM_W(("Notification failure for %s:%s (curl_easy_perform failed: %s)", ip.c_str(), portAsString, curl_easy_strerror(res))); result = ""; } else { // The Response is here LM_I(("Notification Successfully Sent to %s", url.c_str())); result.assign(httpResponse->memory, httpResponse->size); } // Cleanup curl environment curl_slist_free_all(headers); curl_easy_cleanup(curl); free(httpResponse->memory); delete httpResponse; LM_TRANSACTION_END(); return result; }
/* * Source code in here hugely as reported in bug report 651464 by * Christopher R. Palmer. * * Use multi interface to get document over proxy with bad port number. * This caused the interface to "hang" in libcurl 7.10.2. */ int test(char *URL) { CURL *c; int ret=0; CURLM *m; fd_set rd, wr, exc; CURLMcode res; char done = FALSE; int running; int max_fd; int rc; struct timeval ml_start; struct timeval mp_start; char ml_timedout = FALSE; char mp_timedout = FALSE; if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { fprintf(stderr, "curl_global_init() failed\n"); return TEST_ERR_MAJOR_BAD; } if ((c = curl_easy_init()) == NULL) { fprintf(stderr, "curl_easy_init() failed\n"); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } /* the point here being that there must not run anything on the given proxy port */ curl_easy_setopt(c, CURLOPT_PROXY, arg2); curl_easy_setopt(c, CURLOPT_URL, URL); curl_easy_setopt(c, CURLOPT_VERBOSE, 1); if ((m = curl_multi_init()) == NULL) { fprintf(stderr, "curl_multi_init() failed\n"); curl_easy_cleanup(c); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } if ((res = curl_multi_add_handle(m, c)) != CURLM_OK) { fprintf(stderr, "curl_multi_add_handle() failed, " "with code %d\n", res); curl_multi_cleanup(m); curl_easy_cleanup(c); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } ml_timedout = FALSE; ml_start = tutil_tvnow(); while (!done) { struct timeval interval; interval.tv_sec = 1; interval.tv_usec = 0; if (tutil_tvdiff(tutil_tvnow(), ml_start) > MAIN_LOOP_HANG_TIMEOUT) { ml_timedout = TRUE; break; } mp_timedout = FALSE; mp_start = tutil_tvnow(); fprintf(stderr, "curl_multi_perform()\n"); res = CURLM_CALL_MULTI_PERFORM; while (res == CURLM_CALL_MULTI_PERFORM) { res = curl_multi_perform(m, &running); if (tutil_tvdiff(tutil_tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) { mp_timedout = TRUE; break; } } if (mp_timedout) break; if(!running) { /* This is where this code is expected to reach */ int numleft; CURLMsg *msg = curl_multi_info_read(m, &numleft); fprintf(stderr, "Expected: not running\n"); if(msg && !numleft) ret = 100; /* this is where we should be */ else ret = 99; /* not correct */ break; } fprintf(stderr, "running == %d, res == %d\n", running, res); if (res != CURLM_OK) { ret = 2; break; } FD_ZERO(&rd); FD_ZERO(&wr); FD_ZERO(&exc); max_fd = 0; fprintf(stderr, "curl_multi_fdset()\n"); if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) { fprintf(stderr, "unexpected failured of fdset.\n"); ret = 3; break; } rc = select_test(max_fd+1, &rd, &wr, &exc, &interval); fprintf(stderr, "select returned %d\n", rc); } if (ml_timedout || mp_timedout) { if (ml_timedout) fprintf(stderr, "ml_timedout\n"); if (mp_timedout) fprintf(stderr, "mp_timedout\n"); fprintf(stderr, "ABORTING TEST, since it seems " "that it would have run forever.\n"); ret = TEST_ERR_RUNS_FOREVER; } curl_multi_remove_handle(m, c); curl_easy_cleanup(c); curl_multi_cleanup(m); curl_global_cleanup(); return ret; }
/* * Simply download a HTTP file. */ int main(int argc, char **argv) { CURL *http_handle; CURLM *multi_handle; int still_running; /* keep number of running handles */ http_handle = curl_easy_init(); /* set the options (I left out a few, you'll get the point anyway) */ curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.haxx.se/"); curl_easy_setopt(http_handle, CURLOPT_DEBUGFUNCTION, my_trace); curl_easy_setopt(http_handle, CURLOPT_VERBOSE, 1L); /* init a multi stack */ multi_handle = curl_multi_init(); /* add the individual transfers */ curl_multi_add_handle(multi_handle, http_handle); /* we start some action by calling perform right away */ while(CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &still_running)); while(still_running) { struct timeval timeout; int rc; /* select() return code */ fd_set fdread; fd_set fdwrite; fd_set fdexcep; int maxfd = -1; FD_ZERO(&fdread); FD_ZERO(&fdwrite); FD_ZERO(&fdexcep); /* set a suitable timeout to play around with */ timeout.tv_sec = 1; timeout.tv_usec = 0; /* get file descriptors from the transfers */ curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); /* In a real-world program you OF COURSE check the return code of the function calls. On success, the value of maxfd is guaranteed to be greater or equal than -1. We call select(maxfd + 1, ...), specially in case of (maxfd == -1), we call select(0, ...), which is basically equal to sleep. */ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); switch(rc) { case -1: /* select error */ still_running = 0; printf("select() returns error, this is badness\n"); break; case 0: default: /* timeout or readable/writable sockets */ while(CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &still_running)); break; } } curl_multi_cleanup(multi_handle); curl_easy_cleanup(http_handle); return 0; }
int main(int argc, char **argv) { CURL *curl; CURLcode res; FILE *ftpfile; FILE * hd_src ; int hd ; struct stat file_info; struct curl_slist *headerlist=NULL; char buf_1 [] = "RNFR " UPLOAD_FILE_AS; char buf_2 [] = "RNTO " RENAME_FILE_TO; /* get the file size of the local file */ hd = open(LOCAL_FILE, O_RDONLY) ; fstat(hd, &file_info); close(hd) ; /* get a FILE * of the same file, could also be made with fdopen() from the previous descriptor, but hey this is just an example! */ hd_src = fopen(LOCAL_FILE, "rb"); /* In windows, this will init the winsock stuff */ curl_global_init(CURL_GLOBAL_ALL); /* get a curl handle */ curl = curl_easy_init(); if(curl) { /* build a list of commands to pass to libcurl */ // headerlist = curl_slist_append(headerlist, buf_1); // headerlist = curl_slist_append(headerlist, buf_2); /* enable uploading */ curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE) ; /* set user name and password */ curl_easy_setopt(curl, CURLOPT_USERPWD, "rutul:topspin"); /* specify target */ curl_easy_setopt(curl,CURLOPT_URL, REMOTE_URL); /* pass in that last of FTP commands to run after the transfer */ // curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist); /* now specify which file to upload */ curl_easy_setopt(curl, CURLOPT_INFILE, hd_src); /* and give the size of the upload (optional) */ curl_easy_setopt(curl, CURLOPT_INFILESIZE, file_info.st_size); /* Switch on full protocol/debug output */ curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE); /* Now run off and do what you've been told! */ res = curl_easy_perform(curl); /* clean up the FTP commands list */ curl_slist_free_all (headerlist); /* always cleanup */ curl_easy_cleanup(curl); } fclose(hd_src); /* close the local file */ curl_global_cleanup(); return 0; }
void http_client_request(const char *url, const char *post_data, http_client_callback_t *callback, void *data) { struct http_request *request = g_new(struct http_request, 1); CURLcode code; CURLMcode mcode; bool success; request->callback = callback; request->callback_data = data; /* create a CURL request */ request->curl = curl_easy_init(); if (request->curl == NULL) { g_free(request); callback(0, NULL, data); return; } mcode = curl_multi_add_handle(http_client.multi, request->curl); if (mcode != CURLM_OK) { curl_easy_cleanup(request->curl); g_free(request); callback(0, NULL, data); return; } /* .. and set it up */ curl_easy_setopt(request->curl, CURLOPT_USERAGENT, "mpdcron/" VERSION); curl_easy_setopt(request->curl, CURLOPT_WRITEFUNCTION, http_request_writefunction); curl_easy_setopt(request->curl, CURLOPT_WRITEDATA, request); curl_easy_setopt(request->curl, CURLOPT_FAILONERROR, true); curl_easy_setopt(request->curl, CURLOPT_ERRORBUFFER, request->error); curl_easy_setopt(request->curl, CURLOPT_BUFFERSIZE, 2048); if (file_config.proxy != NULL) curl_easy_setopt(request->curl, CURLOPT_PROXY, file_config.proxy); request->post_data = g_strdup(post_data); if (request->post_data != NULL) { curl_easy_setopt(request->curl, CURLOPT_POST, true); curl_easy_setopt(request->curl, CURLOPT_POSTFIELDS, request->post_data); } code = curl_easy_setopt(request->curl, CURLOPT_URL, url); if (code != CURLE_OK) { curl_multi_remove_handle(http_client.multi, request->curl); curl_easy_cleanup(request->curl); g_free(request); callback(0, NULL, data); return; } request->body = g_string_sized_new(256); http_client.requests = g_slist_prepend(http_client.requests, request); /* initiate the transfer */ success = http_multi_perform(); if (!success) { http_client.requests = g_slist_remove(http_client.requests, request); http_request_free(request); callback(0, NULL, data); return; } http_multi_info_read(); }
JNIEXPORT jint JNICALL Java_com_netbirdtech_libcurl_Curl_curlEasySetoptLongNative (JNIEnv *env, jobject obj, jlong handle, jint opt, jlong value) { Holder* holder = (Holder*) handle; return (int) curl_easy_setopt(holder->getCurl(), (CURLoption) opt, (long) value); }
int main(void) { CURL *handles[HANDLECOUNT]; CURLM *multi_handle; int still_running = 0; /* keep number of running handles */ int i; CURLMsg *msg; /* for picking up messages with the transfer status */ int msgs_left; /* how many messages are left */ /* Allocate one CURL handle per transfer */ for(i = 0; i<HANDLECOUNT; i++) handles[i] = curl_easy_init(); /* set the options (I left out a few, you'll get the point anyway) */ curl_easy_setopt(handles[HTTP_HANDLE], CURLOPT_URL, "https://example.com"); curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_URL, "ftp://example.com"); curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_UPLOAD, 1L); /* init a multi stack */ multi_handle = curl_multi_init(); /* add the individual transfers */ for(i = 0; i<HANDLECOUNT; i++) curl_multi_add_handle(multi_handle, handles[i]); /* we start some action by calling perform right away */ curl_multi_perform(multi_handle, &still_running); while(still_running) { struct timeval timeout; int rc; /* select() return code */ CURLMcode mc; /* curl_multi_fdset() return code */ fd_set fdread; fd_set fdwrite; fd_set fdexcep; int maxfd = -1; long curl_timeo = -1; FD_ZERO(&fdread); FD_ZERO(&fdwrite); FD_ZERO(&fdexcep); /* set a suitable timeout to play around with */ timeout.tv_sec = 1; timeout.tv_usec = 0; curl_multi_timeout(multi_handle, &curl_timeo); if(curl_timeo >= 0) { timeout.tv_sec = curl_timeo / 1000; if(timeout.tv_sec > 1) timeout.tv_sec = 1; else timeout.tv_usec = (curl_timeo % 1000) * 1000; } /* get file descriptors from the transfers */ mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); if(mc != CURLM_OK) { fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); break; } /* On success the value of maxfd is guaranteed to be >= -1. We call select(maxfd + 1, ...); specially in case of (maxfd == -1) there are no fds ready yet so we call select(0, ...) --or Sleep() on Windows-- to sleep 100ms, which is the minimum suggested value in the curl_multi_fdset() doc. */ if(maxfd == -1) { #ifdef _WIN32 Sleep(100); rc = 0; #else /* Portable sleep for platforms other than Windows. */ struct timeval wait = { 0, 100 * 1000 }; /* 100ms */ rc = select(0, NULL, NULL, NULL, &wait); #endif } else { /* Note that on some platforms 'timeout' may be modified by select(). If you need access to the original value save a copy beforehand. */ rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); } switch(rc) { case -1: /* select error */ break; case 0: /* timeout */ default: /* action */ curl_multi_perform(multi_handle, &still_running); break; } } /* See how the transfers went */ while((msg = curl_multi_info_read(multi_handle, &msgs_left))) { if(msg->msg == CURLMSG_DONE) { int idx, found = 0; /* Find out which handle this message is about */ for(idx = 0; idx<HANDLECOUNT; idx++) { found = (msg->easy_handle == handles[idx]); if(found) break; } switch(idx) { case HTTP_HANDLE: printf("HTTP transfer completed with status %d\n", msg->data.result); break; case FTP_HANDLE: printf("FTP transfer completed with status %d\n", msg->data.result); break; } } } curl_multi_cleanup(multi_handle); /* Free the CURL handles */ for(i = 0; i<HANDLECOUNT; i++) curl_easy_cleanup(handles[i]); return 0; }
bool SocketStreamHandle::connect() { ASSERT(state() == Connecting); MutexLocker lock(m_close_mutex); m_curlHandle = curl_easy_init(); if ( !m_curlHandle ) { m_curl_code = CURLE_OUT_OF_MEMORY; sendMessageToMainThread(DidFail); return false; } curl_easy_setopt(m_curlHandle, CURLOPT_PRIVATE, this); curl_easy_setopt(m_curlHandle, CURLOPT_ERRORBUFFER, m_curl_error_buffer); if (m_socket == -1) { // Curl connect and setup const String & proxy = ResourceHandleManager::sharedInstance()->getProxyString(); if (proxy.length()) { bool isLocalHttp = (m_url.host() == "localhost" || m_url.host().startsWith("127.0.0.") || m_url.host().startsWith("::1")); if (!isLocalHttp) { curl_easy_setopt(m_curlHandle, CURLOPT_PROXY, proxy.utf8().data()); curl_easy_setopt(m_curlHandle, CURLOPT_PROXYTYPE, ResourceHandleManager::sharedInstance()->getProxyType()); } } // curl doesn't understand a ws:// protocol, so switch it to http if ( m_url.protocolIs("ws") ) { KURL urlcopy = m_url; urlcopy.setProtocol("http"); curl_easy_setopt(m_curlHandle, CURLOPT_URL, urlcopy.string().latin1().data()); } else if ( m_url.protocolIs("wss") ) { KURL urlcopy = m_url; urlcopy.setProtocol("https"); curl_easy_setopt(m_curlHandle, CURLOPT_URL, urlcopy.string().latin1().data()); m_use_curl_easy_send_recv = true; } else { curl_easy_setopt(m_curlHandle, CURLOPT_URL, m_url.string().latin1().data()); } curl_easy_setopt(m_curlHandle, CURLOPT_PORT, m_url.port()); curl_easy_setopt(m_curlHandle, CURLOPT_CONNECTTIMEOUT, 15); // we'll wait for up to 15 seconds for the connection to be made. curl_easy_setopt(m_curlHandle, CURLOPT_TCP_NODELAY, TRUE); // in case we want to close the connection while it's being made: curl_easy_setopt(m_curlHandle, CURLOPT_PROGRESSFUNCTION, progressFunctionStatic); curl_easy_setopt(m_curlHandle, CURLOPT_PROGRESSDATA, this); curl_easy_setopt(m_curlHandle, CURLOPT_NOPROGRESS, 0); } else { // The connection has already been made. Initialize the curl handle with the // provided fd. We're not really connecting to 127.0.0.1, but have to provide // a URL or CURL will fail the handle almost immediately. The URL needs // to be unique from other active SocketStreamHandle instances or CURL // will try to re-use a different connection. char url_buf[32]; sprintf(url_buf, "http://127.0.0.1:%d", m_socket % 0x10000); curl_easy_setopt(m_curlHandle, CURLOPT_URL, url_buf); curl_easy_setopt(m_curlHandle, CURLOPT_OPENSOCKETFUNCTION, getsocket); curl_easy_setopt(m_curlHandle, CURLOPT_SOCKOPTFUNCTION, getsockopts); curl_easy_setopt(m_curlHandle, CURLOPT_OPENSOCKETDATA, m_socket); } curl_easy_setopt(m_curlHandle, CURLOPT_CONNECT_ONLY, 1L); //comment this // curl_easy_setopt(m_curlHandle, CURLOPT_VERBOSE, 1); // curl_easy_setopt(m_curlHandle, CURLOPT_DEBUGFUNCTION, cURL_debug); m_curl_code = curl_easy_perform(m_curlHandle); if ( m_curl_code != CURLE_OK ) { LOG_CONNECT(Network, "SocketStreamHandleCurl: startConnect failed to connect [%p][thread=%d]\n", this, GetCurrentThreadId()); sendMessageToMainThread(DidFail); return false; } if (m_socket == -1) { m_curl_code = curl_easy_getinfo(m_curlHandle, CURLINFO_LASTSOCKET, &m_socket); if ( m_curl_code != CURLE_OK ) { LOG_CONNECT(Network, "SocketStreamHandleCurl: startConnect failed to get socket from curl [%p][thread=%d]\n", this, GetCurrentThreadId()); sendMessageToMainThread(DidFail); return false; } } if (!m_platformCloseRequested) { LOG_CONNECT(Network, "SocketStreamHandleCurl: startConnect success, changing state to open [%p][thread=%d]\n", this, GetCurrentThreadId()); m_state = Open; sendMessageToMainThread(DidOpen); return true; } else { return false; } }
int main(void) { CURL *curl; CURLM *multi_handle; int still_running; struct curl_httppost *formpost=NULL; struct curl_httppost *lastptr=NULL; struct curl_slist *headerlist=NULL; static const char buf[] = "Expect:"; /* Fill in the file upload field. This makes libcurl load data from the given file name when curl_easy_perform() is called. */ curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "sendfile", CURLFORM_FILE, "postit2.c", CURLFORM_END); /* Fill in the filename field */ curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "filename", CURLFORM_COPYCONTENTS, "postit2.c", CURLFORM_END); /* Fill in the submit field too, even if this is rarely needed */ curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "send", CURLFORM_END); curl = curl_easy_init(); multi_handle = curl_multi_init(); /* initialize custom header list (stating that Expect: 100-continue is not wanted */ headerlist = curl_slist_append(headerlist, buf); if(curl && multi_handle) { /* what URL that receives this POST */ curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/upload.cgi"); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); curl_multi_add_handle(multi_handle, curl); curl_multi_perform(multi_handle, &still_running); do { struct timeval timeout; int rc; /* select() return code */ CURLMcode mc; /* curl_multi_fdset() return code */ fd_set fdread; fd_set fdwrite; fd_set fdexcep; int maxfd = -1; long curl_timeo = -1; FD_ZERO(&fdread); FD_ZERO(&fdwrite); FD_ZERO(&fdexcep); /* set a suitable timeout to play around with */ timeout.tv_sec = 1; timeout.tv_usec = 0; curl_multi_timeout(multi_handle, &curl_timeo); if(curl_timeo >= 0) { timeout.tv_sec = curl_timeo / 1000; if(timeout.tv_sec > 1) timeout.tv_sec = 1; else timeout.tv_usec = (curl_timeo % 1000) * 1000; } /* get file descriptors from the transfers */ mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); if(mc != CURLM_OK) { fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); break; } /* On success the value of maxfd is guaranteed to be >= -1. We call select(maxfd + 1, ...); specially in case of (maxfd == -1) there are no fds ready yet so we call select(0, ...) --or Sleep() on Windows-- to sleep 100ms, which is the minimum suggested value in the curl_multi_fdset() doc. */ if(maxfd == -1) { #ifdef _WIN32 Sleep(100); rc = 0; #else /* Portable sleep for platforms other than Windows. */ struct timeval wait = { 0, 100 * 1000 }; /* 100ms */ rc = select(0, NULL, NULL, NULL, &wait); #endif } else { /* Note that on some platforms 'timeout' may be modified by select(). If you need access to the original value save a copy beforehand. */ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); } switch(rc) { case -1: /* select error */ break; case 0: default: /* timeout or readable/writable sockets */ printf("perform!\n"); curl_multi_perform(multi_handle, &still_running); printf("running: %d!\n", still_running); break; } } while(still_running); curl_multi_cleanup(multi_handle); /* always cleanup */ curl_easy_cleanup(curl); /* then cleanup the formpost chain */ curl_formfree(formpost); /* free slist */ curl_slist_free_all (headerlist); } return 0; }
static int testExternalGet () { struct MHD_Daemon *d; CURL *c; char buf[2048]; struct CBC cbc; CURLM *multi; CURLMcode mret; fd_set rs; fd_set ws; fd_set es; MHD_socket maxsock; #ifdef MHD_WINSOCK_SOCKETS int maxposixs; /* Max socket number unused on W32 */ #else /* MHD_POSIX_SOCKETS */ #define maxposixs maxsock #endif /* MHD_POSIX_SOCKETS */ int running; struct CURLMsg *msg; time_t start; struct timeval tv; multi = NULL; cbc.buf = buf; cbc.size = 2048; cbc.pos = 0; d = MHD_start_daemon (MHD_USE_DEBUG, 21080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); if (d == NULL) return 256; c = curl_easy_init (); curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:21080/hello+world?k=v+x&hash=%23foo&space=%A0bar"); curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); if (oneone) curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); else curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L); curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L); /* NOTE: use of CONNECTTIMEOUT without also setting NOSIGNAL results in really weird crashes on my system! */ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); multi = curl_multi_init (); if (multi == NULL) { curl_easy_cleanup (c); MHD_stop_daemon (d); return 512; } mret = curl_multi_add_handle (multi, c); if (mret != CURLM_OK) { curl_multi_cleanup (multi); curl_easy_cleanup (c); MHD_stop_daemon (d); return 1024; } start = time (NULL); while ((time (NULL) - start < 5) && (multi != NULL)) { maxsock = MHD_INVALID_SOCKET; maxposixs = -1; FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); curl_multi_perform (multi, &running); mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs); if (mret != CURLM_OK) { curl_multi_remove_handle (multi, c); curl_multi_cleanup (multi); curl_easy_cleanup (c); MHD_stop_daemon (d); return 2048; } if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock)) { curl_multi_remove_handle (multi, c); curl_multi_cleanup (multi); curl_easy_cleanup (c); MHD_stop_daemon (d); return 4096; } tv.tv_sec = 0; tv.tv_usec = 1000; if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv)) { if (EINTR != errno) abort (); } curl_multi_perform (multi, &running); if (running == 0) { msg = curl_multi_info_read (multi, &running); if (msg == NULL) break; if (msg->msg == CURLMSG_DONE) { if (msg->data.result != CURLE_OK) printf ("%s failed at %s:%d: `%s'\n", "curl_multi_perform", __FILE__, __LINE__, curl_easy_strerror (msg->data.result)); curl_multi_remove_handle (multi, c); curl_multi_cleanup (multi); curl_easy_cleanup (c); c = NULL; multi = NULL; } } MHD_run (d); } if (multi != NULL) { curl_multi_remove_handle (multi, c); curl_easy_cleanup (c); curl_multi_cleanup (multi); } MHD_stop_daemon (d); if (cbc.pos != strlen ("/hello+world")) return 8192; if (0 != strncmp ("/hello+world", cbc.buf, strlen ("/hello+world"))) return 16384; return 0; }
static int action_failoverip(struct uwsgi_legion *ul, char *arg) { int ret = -1; char *url = NULL; char *auth = NULL; struct hetzner_failoverip_config hfc; memset(&hfc, 0, sizeof(struct hetzner_failoverip_config)); if (uwsgi_kvlist_parse(arg, strlen(arg), ',', '=', "username", &hfc.username, "password", &hfc.password, "user", &hfc.username, "pass", &hfc.password, "url", &hfc.url, "timeout", &hfc.timeout, "ip", &hfc.ip, "active_ip", &hfc.active_ip, "active_server_ip", &hfc.active_ip, "ssl_no_verify", &hfc.ssl_no_verify, NULL)) { uwsgi_log("unable to parse hetzner-failopeverip options\n"); return -1; } if (!hfc.username || !hfc.password || !hfc.ip || !hfc.active_ip) { uwsgi_log("hetzner-failopeverip action requires username, password, ip and active_ip keys\n"); goto clear; } if (hfc.url) { url = uwsgi_str(hfc.url); } else { url = uwsgi_concat2(HETNZER_FAILOVERIP_URL, hfc.ip); } struct curl_httppost *formpost = NULL; struct curl_httppost *lastptr=NULL; curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "active_server_ip", CURLFORM_COPYCONTENTS, hfc.active_ip, CURLFORM_END); CURL *curl = curl_easy_init(); if (!curl) { curl_formfree(formpost); goto clear; } int timeout = 60; if (hfc.timeout) timeout = atoi(hfc.timeout); curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); auth = uwsgi_concat3(hfc.username, ":", hfc.password); curl_easy_setopt(curl, CURLOPT_USERPWD, auth); if (hfc.ssl_no_verify) { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); } curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, hetzner_curl_writefunc); CURLcode res = curl_easy_perform(curl); if (res != CURLE_OK) { uwsgi_log("[hetzner-failoverip] curl error: %s\n", curl_easy_strerror(res)); curl_formfree(formpost); curl_easy_cleanup(curl); goto clear; } long http_code = 0; #ifdef CURLINFO_RESPONSE_CODE curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); #else curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &http_code); #endif // allows Ok and Conflict uwsgi_log("[hetzner-failoverip] HTTP status code: %ld\n", http_code); if (http_code == 200 || http_code == 409) { ret = 0; } curl_formfree(formpost); curl_easy_cleanup(curl); clear: if (url) free(url); if (auth) free(auth); if (hfc.username) free(hfc.username); if (hfc.password) free(hfc.password); if (hfc.url) free(hfc.url); if (hfc.timeout) free(hfc.timeout); if (hfc.ip) free(hfc.ip); if (hfc.active_ip) free(hfc.active_ip); if (hfc.ssl_no_verify) free(hfc.ssl_no_verify); return ret; }
void elasticsearch_plugin_impl::sendBulk(std::string _elasticsearch_node_url, bool _elasticsearch_logs) { // curl buffers to read std::string readBuffer; std::string readBuffer_logs; std::string bulking = ""; bulking = boost::algorithm::join(bulk, "\n"); bulking = bulking + "\n"; bulk.clear(); //wlog((bulking)); struct curl_slist *headers = NULL; curl_slist_append(headers, "Content-Type: application/json"); std::string url = _elasticsearch_node_url + "_bulk"; curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_POST, true); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, bulking.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&readBuffer); curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcrp/0.1"); //curl_easy_setopt(curl, CURLOPT_VERBOSE, true); curl_easy_perform(curl); long http_code = 0; curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); if(http_code == 200) { // all good, do nothing } else if(http_code == 429) { // repeat request? } else { // exit everything ? } if(_elasticsearch_logs) { auto logs = readBuffer; // do logs std::string url_logs = _elasticsearch_node_url + "logs/data/"; curl_easy_setopt(curl, CURLOPT_URL, url_logs.c_str()); curl_easy_setopt(curl, CURLOPT_POST, true); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, logs.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &readBuffer_logs); curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcrp/0.1"); //curl_easy_setopt(curl, CURLOPT_VERBOSE, true); //ilog("log here curl: ${output}", ("output", readBuffer_logs)); curl_easy_perform(curl); http_code = 0; curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); if(http_code == 200) { // all good, do nothing } else if(http_code == 429) { // repeat request? } else { // exit everything ? } } }
static int testExternalPut () { struct MHD_Daemon *d; CURL *c; char buf[2048]; struct CBC cbc; CURLM *multi; CURLMcode mret; fd_set rs; fd_set ws; fd_set es; int max; int running; time_t start; struct timeval tv; unsigned int pos = 0; int done_flag = 0; int i; multi = NULL; cbc.buf = buf; cbc.size = 2048; cbc.pos = 0; d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_DEBUG */ , 11080, NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END); if (d == NULL) return 256; multi = curl_multi_init (); if (multi == NULL) { MHD_stop_daemon (d); return 512; } zzuf_socat_start (); for (i = 0; i < LOOP_COUNT; i++) { fprintf (stderr, "."); c = curl_easy_init (); curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11081/hello_world"); curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer); curl_easy_setopt (c, CURLOPT_READDATA, &pos); curl_easy_setopt (c, CURLOPT_UPLOAD, 1L); curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L); curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT); if (oneone) curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); else curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT); // NOTE: use of CONNECTTIMEOUT without also // setting NOSIGNAL results in really weird // crashes on my system! curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); mret = curl_multi_add_handle (multi, c); if (mret != CURLM_OK) { curl_multi_cleanup (multi); curl_easy_cleanup (c); zzuf_socat_stop (); MHD_stop_daemon (d); return 1024; } start = time (NULL); while ((time (NULL) - start < 5) && (c != NULL)) { max = 0; FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); curl_multi_perform (multi, &running); mret = curl_multi_fdset (multi, &rs, &ws, &es, &max); if (mret != CURLM_OK) { curl_multi_remove_handle (multi, c); curl_multi_cleanup (multi); curl_easy_cleanup (c); zzuf_socat_stop (); MHD_stop_daemon (d); return 2048; } if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max)) { curl_multi_remove_handle (multi, c); curl_multi_cleanup (multi); curl_easy_cleanup (c); zzuf_socat_stop (); MHD_stop_daemon (d); return 4096; } tv.tv_sec = 0; tv.tv_usec = 1000; select (max + 1, &rs, &ws, &es, &tv); curl_multi_perform (multi, &running); if (running == 0) { curl_multi_info_read (multi, &running); curl_multi_remove_handle (multi, c); curl_easy_cleanup (c); c = NULL; } MHD_run (d); } if (c != NULL) { curl_multi_remove_handle (multi, c); curl_easy_cleanup (c); } } fprintf (stderr, "\n"); curl_multi_cleanup (multi); zzuf_socat_stop (); MHD_stop_daemon (d); return 0; }
void LLCurl::Easy::setopt(CURLoption option, char* value) { curl_easy_setopt(mCurlEasyHandle, option, value); }
static void do_task(void *task_ptr, void *pool_data) { Task *task = task_ptr; CURL *curl; int result; curl = curl_easy_init(); if (curl == NULL) { do_error(task, "Could not initialize http library"); } else { CURLcode result; /* Note that curl doesn't copy the stuff passed into it (e.g. the url) */ curl_easy_setopt(curl, CURLOPT_URL, task->url); curl_easy_setopt(curl, CURLOPT_WRITEDATA, task); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_func); curl_easy_setopt(curl, CURLOPT_READFUNCTION, curl_read_func); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, curl_progress_func); curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, task); result = curl_easy_perform(curl); if (result != CURLE_OK) { do_error(task, curl_easy_strerror(result)); } else { long response_code = 404; #define RESPONSE_CODE_OK 200 #define RESPONSE_CODE_PERM_REDIRECT 301 #define RESPONSE_CODE_TEMP_REDIRECT 302 result = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); if (result != CURLE_OK) { do_error(task, curl_easy_strerror(result)); } else if (response_code != RESPONSE_CODE_OK) { char *s = g_strdup_printf("HTTP error code: %ld", response_code); do_error(task, s); g_free(s); } else { const char *content_type = NULL; result = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &content_type); if (result != CURLE_OK) { do_error(task, curl_easy_strerror(result)); } else if (content_type == NULL) { do_error(task, _("No content type received")); } else { task->content_type = g_strdup(content_type); } } } } curl_easy_cleanup(curl); G_LOCK(completed_queue); completed_tasks = g_slist_prepend(completed_tasks, task); G_UNLOCK(completed_queue); /* Notify the main thread */ while (TRUE) { result = write(pipe_fds[WRITE_END], "b", 1); if (result == 0 || (result < 0 && errno == EINTR)) { continue; } else { if (result < 0) g_warning("Failed to write byte to pipe: %s", strerror(errno)); break; } } }
void* pull_one_url(void *arg_cbget) { if (!arg_cbget) return NULL; cbget *arg = static_cast<cbget*>(arg_cbget); CURL *curl = NULL; if (!arg->_handler) { curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl, CURLOPT_MAXREDIRS,5); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); // do not check on SSL certificate. } else curl = arg->_handler; curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, arg->_connect_timeout_sec); curl_easy_setopt(curl, CURLOPT_TIMEOUT, arg->_transfer_timeout_sec); curl_easy_setopt(curl, CURLOPT_URL, arg->_url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, arg); if (!arg->_cookies.empty()) curl_easy_setopt(curl, CURLOPT_COOKIE, arg->_cookies.c_str()); if (!arg->_proxy_addr.empty()) { std::string proxy_str = arg->_proxy_addr + ":" + miscutil::to_string(arg->_proxy_port); curl_easy_setopt(curl, CURLOPT_PROXY, proxy_str.c_str()); } if (arg->_http_method == "POST") // POST request. { if (arg->_content) { curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (void*)arg->_content->c_str()); if (arg->_content_size >= 0) curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, arg->_content_size); /*std::cerr << "curl_mget POST size: " << arg->_content_size << std::endl << "content: " << *arg->_content << std::endl;*/ } else curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); } else if (arg->_http_method == "PUT" || arg->_http_method == "DELETE") { curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, arg->_http_method.c_str()); } struct curl_slist *slist=NULL; // useful headers. if (arg->_headers) { std::list<const char*>::const_iterator sit = arg->_headers->begin(); while (sit!=arg->_headers->end()) { slist = curl_slist_append(slist,(*sit)); ++sit; } if (arg->_content) { slist = curl_slist_append(slist,strdup(arg->_content_type.c_str())); slist = curl_slist_append(slist,strdup("Expect:")); } } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); char errorbuffer[CURL_ERROR_SIZE]; curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &errorbuffer); try { int status = curl_easy_perform(curl); if (status != 0) // an error occurred. { arg->_status = status; errlog::log_error(LOG_LEVEL_ERROR, "curl error on url %s: %s",arg->_url,errorbuffer); if (arg->_output) { delete arg->_output; arg->_output = NULL; } } } catch (std::exception &e) { arg->_status = -1; errlog::log_error(LOG_LEVEL_ERROR, "Error %s in fetching remote data with curl.", e.what()); if (arg->_output) { delete arg->_output; arg->_output = NULL; } } catch (...) { arg->_status = -2; if (arg->_output) { delete arg->_output; arg->_output = NULL; } } if (!arg->_handler) curl_easy_cleanup(curl); if (slist) curl_slist_free_all(slist); return NULL; }
/* Set various general curl flags */ int ocset_curl_flags(OCstate* state) { CURLcode cstat = CURLE_OK; CURL* curl = state->curl; struct OCcurlflags* flags = &state->curlflags; #if 0 cstat = curl_easy_reset(curl); #endif #ifdef CURLOPT_ENCODING if (flags->compress) { cstat = curl_easy_setopt(curl, CURLOPT_ENCODING,"deflate, gzip"); if(cstat != CURLE_OK) goto done; OCDBG(1,"CURLOPT_ENCODING=deflate, gzip"); } #endif #if 0 Do not think this is correct if (flags->cookiejar) { cstat = curl_easy_setopt(curl, CURLOPT_COOKIESESSION, 1); if (cstat != CURLE_OK) goto done; OCDBG(1,"CURLOPT_COOKIESESSION=1"); } #endif if (flags->cookiejar) { cstat = curl_easy_setopt(curl, CURLOPT_COOKIEJAR, flags->cookiejar); if (cstat != CURLE_OK) goto done; OCDBG1(1,"CURLOPT_COOKIEJAR=%s",flags->cookiejar); cstat = curl_easy_setopt(curl, CURLOPT_COOKIEFILE, flags->cookiejar); if (cstat != CURLE_OK) goto done; OCDBG1(1,"CURLOPT_COOKIEFILE=%s",flags->cookiefile); } if (flags->verbose) { cstat = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); if (cstat != CURLE_OK) goto done; OCDBG1(1,"CURLOPT_VERBOSE=%ld",1L); } if (flags->timeout) { cstat = curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)flags->timeout); if (cstat != CURLE_OK) goto done; OCDBG1(1,"CURLOPT_TIMEOUT=%ld",1L); } if (flags->useragent) { cstat = curl_easy_setopt(curl, CURLOPT_USERAGENT, flags->useragent); if (cstat != CURLE_OK) goto done; OCDBG1(1,"CURLOPT_USERAGENT=%s",flags->useragent); } /* Following are always set */ cstat = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); OCDBG1(1,"CURLOPT_FOLLOWLOCATION=%ld",1L); cstat = curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10L); OCDBG1(1,"CURLOPT_MAXREDIRS=%ld",10L); #if 0 cstat = curl_setopt(curl,CURLOPT_RETURNTRANSFER, 1L); OCDBG1(1,"CURLOPT_RETURNTRANSFER=%ld",1L); #endif cstat = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, state->error.curlerrorbuf); OCDBG1(1,"CURLOPT_ERRORBUFFER",0); done: return cstat; }
int RD_ListSchedCodes(struct rd_schedcodes *scodes[], const char hostname[], const char username[], const char passwd[], unsigned *numrecs) { char post[1500]; char url[1500]; CURL *curl=NULL; XML_Parser parser; struct xml_data xml_data; long response_code; char errbuf[CURL_ERROR_SIZE]; CURLcode res; /* Set number of recs so if fail already set */ *numrecs = 0; /* * Setup the CURL call */ memset(&xml_data,0,sizeof(xml_data)); parser=XML_ParserCreate(NULL); XML_SetUserData(parser,&xml_data); XML_SetElementHandler(parser,__ListSchedCodesElementStart, __ListSchedCodesElementEnd); XML_SetCharacterDataHandler(parser,__ListSchedCodesElementData); snprintf(url,1500,"http://%s/rd-bin/rdxport.cgi",hostname); snprintf(post,1500,"COMMAND=24&LOGIN_NAME=%s&PASSWORD=%s", username,passwd); if((curl=curl_easy_init())==NULL) { return -1; } curl_easy_setopt(curl,CURLOPT_WRITEDATA,parser); curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,__ListSchedCodesCallback); curl_easy_setopt(curl,CURLOPT_URL,url); curl_easy_setopt(curl,CURLOPT_POST,1); curl_easy_setopt(curl,CURLOPT_POSTFIELDS,post); curl_easy_setopt(curl,CURLOPT_NOPROGRESS,1); curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errbuf); // curl_easy_setopt(curl,CURLOPT_VERBOSE,1); res = curl_easy_perform(curl); if(res != CURLE_OK) { size_t len = strlen(errbuf); fprintf(stderr, "\nlibcurl error: (%d)", res); if (len) fprintf(stderr, "%s%s", errbuf, ((errbuf[len-1] != '\n') ? "\n" : "")); else fprintf(stderr, "%s\n", curl_easy_strerror(res)); curl_easy_cleanup(curl); return -1; } /* The response OK - so figure out if we got what we wanted.. */ curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&response_code); curl_easy_cleanup(curl); if (response_code > 199 && response_code < 300) { *scodes=xml_data.schedcodes; *numrecs = xml_data.schedcodes_quan; return 0; } else { fprintf(stderr," Call Returned Error: %s\n",xml_data.strbuf); return (int)response_code; } }
/* Initialize db->curl */ static int cx_init_curl (cx_t *db) /* {{{ */ { db->curl = curl_easy_init (); if (db->curl == NULL) { ERROR ("curl_xml plugin: curl_easy_init failed."); return (-1); } curl_easy_setopt (db->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt (db->curl, CURLOPT_WRITEFUNCTION, cx_curl_callback); curl_easy_setopt (db->curl, CURLOPT_WRITEDATA, db); curl_easy_setopt (db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); curl_easy_setopt (db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf); curl_easy_setopt (db->curl, CURLOPT_URL, db->url); curl_easy_setopt (db->curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt (db->curl, CURLOPT_MAXREDIRS, 50L); if (db->user != NULL) { #ifdef HAVE_CURLOPT_USERNAME curl_easy_setopt (db->curl, CURLOPT_USERNAME, db->user); curl_easy_setopt (db->curl, CURLOPT_PASSWORD, (db->pass == NULL) ? "" : db->pass); #else size_t credentials_size; credentials_size = strlen (db->user) + 2; if (db->pass != NULL) credentials_size += strlen (db->pass); db->credentials = (char *) malloc (credentials_size); if (db->credentials == NULL) { ERROR ("curl_xml plugin: malloc failed."); return (-1); } ssnprintf (db->credentials, credentials_size, "%s:%s", db->user, (db->pass == NULL) ? "" : db->pass); curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials); #endif if (db->digest) curl_easy_setopt (db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); } curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, db->verify_peer ? 1L : 0L); curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYHOST, db->verify_host ? 2L : 0L); if (db->cacert != NULL) curl_easy_setopt (db->curl, CURLOPT_CAINFO, db->cacert); if (db->headers != NULL) curl_easy_setopt (db->curl, CURLOPT_HTTPHEADER, db->headers); if (db->post_body != NULL) curl_easy_setopt (db->curl, CURLOPT_POSTFIELDS, db->post_body); #ifdef HAVE_CURLOPT_TIMEOUT_MS if (db->timeout >= 0) curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) db->timeout); else curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, CDTIME_T_TO_MS(plugin_get_interval())); #endif return (0); } /* }}} int cx_init_curl */
/* Create a new easy handle, and add it to the global curl_multi */ static void new_conn(char *url, GlobalInfo *g ) { ConnInfo *conn; CURLMcode rc; conn = g_malloc0(sizeof(ConnInfo)); conn->error[0]='\0'; conn->easy = curl_easy_init(); if (!conn->easy) { MSG_OUT("curl_easy_init() failed, exiting!\n"); exit(2); } conn->global = g; conn->url = g_strdup(url); curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url); curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb); curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn); curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, (long)SHOW_VERBOSE); curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error); curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn); curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, SHOW_PROGRESS?0L:1L); curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb); curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn); curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(conn->easy, CURLOPT_CONNECTTIMEOUT, 30L); curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 1L); curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30L); MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url); rc =curl_multi_add_handle(g->multi, conn->easy); mcode_or_die("new_conn: curl_multi_add_handle", rc); g->requested++; do { rc = curl_multi_socket_all(g->multi, &g->still_running); } while (CURLM_CALL_MULTI_PERFORM == rc); mcode_or_die("new_conn: curl_multi_socket_all", rc); check_run_count(g); }
// overloaded to additionally move data to/from the webserver void LLHTTPAssetStorage::checkForTimeouts() { CURLMcode mcode; LLAssetRequest *req; while ( (req = findNextRequest(mPendingDownloads, mRunningDownloads)) ) { // Setup this curl download request // We need to generate a new request here // since the one in the list could go away std::string tmp_url; std::string uuid_str; req->getUUID().toString(uuid_str); std::string base_url = getBaseURL(req->getUUID(), req->getType()); tmp_url = llformat("%s/%36s.%s", base_url.c_str() , uuid_str.c_str(), LLAssetType::lookup(req->getType())); LLHTTPAssetRequest *new_req = new LLHTTPAssetRequest(this, req->getUUID(), req->getType(), RT_DOWNLOAD, tmp_url, mCurlMultiHandle); new_req->mTmpUUID.generate(); // Sets pending download flag internally new_req->setupCurlHandle(); curl_easy_setopt(new_req->mCurlHandle, CURLOPT_FOLLOWLOCATION, TRUE); curl_easy_setopt(new_req->mCurlHandle, CURLOPT_WRITEFUNCTION, &curlDownCallback); curl_easy_setopt(new_req->mCurlHandle, CURLOPT_WRITEDATA, new_req->mCurlHandle); mcode = curl_multi_add_handle(mCurlMultiHandle, new_req->mCurlHandle); if (mcode > CURLM_OK) { // Failure. Deleting the pending request will remove it from the running // queue, and push it to the end of the pending queue. new_req->cleanupCurlHandle(); deletePendingRequest(RT_DOWNLOAD, new_req->getType(), new_req->getUUID()); break; } else { llinfos << "Requesting " << new_req->mURLBuffer << llendl; } } while ( (req = findNextRequest(mPendingUploads, mRunningUploads)) ) { // setup this curl upload request bool do_compress = req->getType() == LLAssetType::AT_OBJECT; std::string tmp_url; std::string uuid_str; req->getUUID().toString(uuid_str); tmp_url = mBaseURL + "/" + uuid_str + "." + LLAssetType::lookup(req->getType()); if (do_compress) tmp_url += ".gz"; LLHTTPAssetRequest *new_req = new LLHTTPAssetRequest(this, req->getUUID(), req->getType(), RT_UPLOAD, tmp_url, mCurlMultiHandle); if (req->mIsUserWaiting) //If a user is waiting on a realtime response, we want to perserve information across upload attempts. { new_req->mTime = req->mTime; new_req->mTimeout = req->mTimeout; new_req->mIsUserWaiting = req->mIsUserWaiting; } if (do_compress) { new_req->prepareCompressedUpload(); } // Sets pending upload flag internally new_req->setupCurlHandle(); curl_easy_setopt(new_req->mCurlHandle, CURLOPT_UPLOAD, 1); curl_easy_setopt(new_req->mCurlHandle, CURLOPT_WRITEFUNCTION, &nullOutputCallback); if (do_compress) { curl_easy_setopt(new_req->mCurlHandle, CURLOPT_READFUNCTION, &LLHTTPAssetRequest::curlCompressedUploadCallback); } else { LLVFile file(mVFS, req->getUUID(), req->getType()); curl_easy_setopt(new_req->mCurlHandle, CURLOPT_INFILESIZE, file.getSize()); curl_easy_setopt(new_req->mCurlHandle, CURLOPT_READFUNCTION, &curlUpCallback); } curl_easy_setopt(new_req->mCurlHandle, CURLOPT_READDATA, new_req->mCurlHandle); mcode = curl_multi_add_handle(mCurlMultiHandle, new_req->mCurlHandle); if (mcode > CURLM_OK) { // Failure. Deleting the pending request will remove it from the running // queue, and push it to the end of the pending queue. new_req->cleanupCurlHandle(); deletePendingRequest(RT_UPLOAD, new_req->getType(), new_req->getUUID()); break; } else { // Get the uncompressed file size. LLVFile file(mVFS,new_req->getUUID(),new_req->getType()); S32 size = file.getSize(); llinfos << "Requesting PUT " << new_req->mURLBuffer << ", asset size: " << size << " bytes" << llendl; if (size == 0) { llwarns << "Rejecting zero size PUT request!" << llendl; new_req->cleanupCurlHandle(); deletePendingRequest(RT_UPLOAD, new_req->getType(), new_req->getUUID()); } } // Pending upload will have been flagged by the request } while ( (req = findNextRequest(mPendingLocalUploads, mRunningLocalUploads)) ) { // setup this curl upload request LLVFile file(mVFS, req->getUUID(), req->getType()); std::string tmp_url; std::string uuid_str; req->getUUID().toString(uuid_str); // KLW - All temporary uploads are saved locally "http://localhost:12041/asset" tmp_url = llformat("%s/%36s.%s", mLocalBaseURL.c_str(), uuid_str.c_str(), LLAssetType::lookup(req->getType())); LLHTTPAssetRequest *new_req = new LLHTTPAssetRequest(this, req->getUUID(), req->getType(), RT_LOCALUPLOAD, tmp_url, mCurlMultiHandle); new_req->mRequestingAgentID = req->mRequestingAgentID; // Sets pending upload flag internally new_req->setupCurlHandle(); curl_easy_setopt(new_req->mCurlHandle, CURLOPT_PUT, 1); curl_easy_setopt(new_req->mCurlHandle, CURLOPT_INFILESIZE, file.getSize()); curl_easy_setopt(new_req->mCurlHandle, CURLOPT_WRITEFUNCTION, &nullOutputCallback); curl_easy_setopt(new_req->mCurlHandle, CURLOPT_READFUNCTION, &curlUpCallback); curl_easy_setopt(new_req->mCurlHandle, CURLOPT_READDATA, new_req->mCurlHandle); mcode = curl_multi_add_handle(mCurlMultiHandle, new_req->mCurlHandle); if (mcode > CURLM_OK) { // Failure. Deleting the pending request will remove it from the running // queue, and push it to the end of the pending queue. new_req->cleanupCurlHandle(); deletePendingRequest(RT_LOCALUPLOAD, new_req->getType(), new_req->getUUID()); break; } else { // Get the uncompressed file size. S32 size = file.getSize(); llinfos << "TAT: LLHTTPAssetStorage::checkForTimeouts() : pending local!" << " Requesting PUT " << new_req->mURLBuffer << ", asset size: " << size << " bytes" << llendl; if (size == 0) { llwarns << "Rejecting zero size PUT request!" << llendl; new_req->cleanupCurlHandle(); deletePendingRequest(RT_UPLOAD, new_req->getType(), new_req->getUUID()); } } // Pending upload will have been flagged by the request } S32 count = 0; int queue_length; do { mcode = curl_multi_perform(mCurlMultiHandle, &queue_length); count++; } while (mcode == CURLM_CALL_MULTI_PERFORM && (count < 5)); CURLMsg *curl_msg; do { curl_msg = curl_multi_info_read(mCurlMultiHandle, &queue_length); if (curl_msg && curl_msg->msg == CURLMSG_DONE) { long curl_result = 0; S32 xfer_result = LL_ERR_NOERR; LLHTTPAssetRequest *req = NULL; curl_easy_getinfo(curl_msg->easy_handle, CURLINFO_PRIVATE, &req); // TODO: Throw curl_result at all callbacks. curl_easy_getinfo(curl_msg->easy_handle, CURLINFO_HTTP_CODE, &curl_result); if (RT_UPLOAD == req->mRequestType || RT_LOCALUPLOAD == req->mRequestType) { if (curl_msg->data.result == CURLE_OK && ( curl_result == HTTP_OK || curl_result == HTTP_PUT_OK || curl_result == HTTP_NO_CONTENT)) { llinfos << "Success uploading " << req->getUUID() << " to " << req->mURLBuffer << llendl; if (RT_LOCALUPLOAD == req->mRequestType) { addTempAssetData(req->getUUID(), req->mRequestingAgentID, mHostName); } } else if (curl_msg->data.result == CURLE_COULDNT_CONNECT || curl_msg->data.result == CURLE_OPERATION_TIMEOUTED || curl_result == HTTP_SERVER_BAD_GATEWAY || curl_result == HTTP_SERVER_TEMP_UNAVAILABLE) { llwarns << "Re-requesting upload for " << req->getUUID() << ". Received upload error to " << req->mURLBuffer << " with result " << curl_easy_strerror(curl_msg->data.result) << ", http result " << curl_result << llendl; ////HACK (probably) I am sick of this getting requeued and driving me mad. //if (req->mIsUserWaiting) //{ // deletePendingRequest(RT_UPLOAD, req->getType(), req->getUUID()); //} } else { llwarns << "Failure uploading " << req->getUUID() << " to " << req->mURLBuffer << " with result " << curl_easy_strerror(curl_msg->data.result) << ", http result " << curl_result << llendl; xfer_result = LL_ERR_ASSET_REQUEST_FAILED; } if (!(curl_msg->data.result == CURLE_COULDNT_CONNECT || curl_msg->data.result == CURLE_OPERATION_TIMEOUTED || curl_result == HTTP_SERVER_BAD_GATEWAY || curl_result == HTTP_SERVER_TEMP_UNAVAILABLE)) { // shared upload finished callback // in the base class, this is called from processUploadComplete _callUploadCallbacks(req->getUUID(), req->getType(), (xfer_result == 0), LL_EXSTAT_CURL_RESULT | curl_result); // Pending upload flag will get cleared when the request is deleted } } else if (RT_DOWNLOAD == req->mRequestType) { if (curl_result == HTTP_OK && curl_msg->data.result == CURLE_OK) { if (req->mVFile && req->mVFile->getSize() > 0) { llinfos << "Success downloading " << req->mURLBuffer << ", size " << req->mVFile->getSize() << llendl; req->mVFile->rename(req->getUUID(), req->getType()); } else { // *TODO: if this actually indicates a bad asset on the server // (not certain at this point), then delete it llwarns << "Found " << req->mURLBuffer << " to be zero size" << llendl; xfer_result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE; } } else { // KLW - TAT See if an avatar owns this texture, and if so request re-upload. llwarns << "Failure downloading " << req->mURLBuffer << " with result " << curl_easy_strerror(curl_msg->data.result) << ", http result " << curl_result << llendl; xfer_result = (curl_result == HTTP_MISSING) ? LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE : LL_ERR_ASSET_REQUEST_FAILED; if (req->mVFile) { req->mVFile->remove(); } } // call the static callback for transfer completion // this will cleanup all requests for this asset, including ours downloadCompleteCallback( xfer_result, req->getUUID(), req->getType(), (void *)req, LL_EXSTAT_CURL_RESULT | curl_result); // Pending download flag will get cleared when the request is deleted } else { // nothing, just axe this request // currently this can only mean an asset delete } // Deleting clears the pending upload/download flag if it's set and the request is transferring delete req; req = NULL; } } while (curl_msg && queue_length > 0); // Cleanup // We want to bump to the back of the line any running uploads that have timed out. bumpTimedOutUploads(); LLAssetStorage::checkForTimeouts(); }
ThreadInfo* Init(string Key, string Secret){ //Creating structure ThreadInfo* t = new(ThreadInfo); if(!t) return 0; //Creating cache t->CacheData.First = 0; t->CacheData.Last = 0; t->CacheData.MaxSize = DEFAULT_CACHE_SIZE; t->CacheData.Size = 0; //creating events t->CacheAvailable = CreateMutex(0, false, 0); //cache is available now t->ImageAvailable = CreateEvent(0, true, false, 0); //image is not available now t->Running = CreateEvent(0, true, false, 0); //thread is created in paused state t->Terminate = false; //creating flickcurl flickcurl_init(); t->Flickcurl = flickcurl_new(); if(t->Flickcurl){ flickcurl_set_api_key(t->Flickcurl, Key.c_str()); flickcurl_set_shared_secret(t->Flickcurl, Secret.c_str()); } //creating search params with default values flickcurl_search_params_init(&t->SearchParams); t->SearchParams.user_id = 0; t->SearchParams.media = "photos"; t->SearchParams.license = "1"; t->WantImage = false; t->WantMeta = false; t->WantEXIF = false; t->WantSize = isMedium; t->WorkDir = ""; t->CurImage = 0; t->TotalImages = 0; //creating list params flickcurl_photos_list_params_init(&t->ListParams); t->ListParams.per_page = DEFAULT_LIST_PAGE_SIZE; t->ListParams.page = 1; t->ResultList = 0; //creating curl t->Curl = curl_easy_init(); curl_easy_setopt(t->Curl, CURLOPT_WRITEFUNCTION, WriteFileCallback); //initializing thread t->Thread = _beginthread(ThreadFunc, 0, (void*)t); //checking if everything is ok if(t->CacheAvailable && t->Running && t->Thread && t->Flickcurl && t->Curl && t->ImageAvailable) return t; else{ //killing everything Free(t); return 0; } };