static void *worker_thread(void *ptr) { net_io_request_t *request = (net_io_request_t*)ptr; printf("thread: running\n"); CURL *curl = curl_easy_init(); if(curl) { FILE *outfile = NULL; gboolean ok = FALSE; /* prepare target (file, memory, ...) */ switch(request->type) { case NET_IO_DL_FILE: outfile = fopen(request->filename, "w"); ok = (outfile != NULL); break; case NET_IO_DL_MEM: request->mem.ptr = NULL; request->mem.len = 0; ok = TRUE; break; default: printf("thread: unsupported request\n"); /* ugh?? */ ok = TRUE; break; } if(ok) { curl_easy_setopt(curl, CURLOPT_URL, request->url); curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); switch(request->type) { case NET_IO_DL_FILE: curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite); break; case NET_IO_DL_MEM: curl_easy_setopt(curl, CURLOPT_WRITEDATA, &request->mem); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, mem_write); break; case NET_IO_DELETE: curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); break; } net_io_set_proxy(curl, request->proxy); /* set user name and password for the authentication */ if(request->user) curl_easy_setopt(curl, CURLOPT_USERPWD, request->user); /* setup progress notification */ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); #ifdef CURLOPT_XFERINFOFUNCTION curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, curl_progress_func); #else curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, curl_progress_func); #endif curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, request); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, request->buffer); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1l); /* play nice and report some user agent */ curl_easy_setopt(curl, CURLOPT_USERAGENT, PACKAGE "-libcurl/" VERSION); request->res = curl_easy_perform(curl); printf("thread: curl perform returned with %d\n", request->res); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &request->response); #if 0 /* try to read "Error" */ struct curl_slist *slist = NULL; slist = curl_slist_append(slist, "Error:"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); #endif if(request->type == NET_IO_DL_FILE) fclose(outfile); } /* always cleanup */ curl_easy_cleanup(curl); } else printf("thread: unable to init curl\n"); printf("thread: io done\n"); request_free(request); printf("thread: terminating\n"); return NULL; }
static gboolean osm_delete_item(struct log_s *log, char *xml_str, char *url, char *user, proxy_t *proxy) { int retry = MAX_TRY; char buffer[CURL_ERROR_SIZE]; CURL *curl; CURLcode res; /* delete has a payload since api 0.6 */ curl_data_t read_data; curl_data_t write_data; while(retry >= 0) { if(retry != MAX_TRY) appendf(log, NULL, _("Retry %d/%d "), MAX_TRY-retry, MAX_TRY-1); /* get a curl handle */ curl = curl_easy_init(); if(!curl) { appendf(log, NULL, _("CURL init error\n")); return FALSE; } read_data.ptr = xml_str; read_data.len = xml_str?strlen(xml_str):0; write_data.ptr = NULL; write_data.len = 0; /* we want to use our own read/write functions */ curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(curl, CURLOPT_INFILESIZE, (curl_off_t)read_data.len); /* now specify which file to upload */ curl_easy_setopt(curl, CURLOPT_READDATA, &read_data); /* we pass our 'chunk' struct to the callback function */ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_data); /* enable uploading */ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); /* no read/write functions required */ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); /* specify target URL, and note that this URL should include a file name, not only a directory */ curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); /* some servers don't like requests that are made without a user-agent field, so we provide one */ curl_easy_setopt(curl, CURLOPT_USERAGENT, PACKAGE "-libcurl/" VERSION); #ifdef NO_EXPECT struct curl_slist *slist = NULL; slist = curl_slist_append(slist, "Expect:"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); #endif curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, buffer); /* set user name and password for the authentication */ curl_easy_setopt(curl, CURLOPT_USERPWD, user); net_io_set_proxy(curl, proxy); /* Now run off and do what you've been told! */ res = curl_easy_perform(curl); long response; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); /* always cleanup */ #ifdef NO_EXPECT curl_slist_free_all(slist); #endif curl_easy_cleanup(curl); if(res != 0) appendf(log, COLOR_ERR, _("failed: %s\n"), buffer); else if(response != 200) appendf(log, COLOR_ERR, _("failed, code: %ld %s\n"), response, osm_http_message(response)); else appendf(log, COLOR_OK, _("ok\n")); /* if it's neither "ok" (200), nor "internal server error" (500) */ /* then write the message to the log */ if((response != 200) && (response != 500) && write_data.ptr) { appendf(log, NULL, _("Server reply: ")); appendf(log, COLOR_ERR, _("%s\n"), write_data.ptr); } g_free(write_data.ptr); /* don't retry unless we had an "internal server error" */ if(response != 500) return((res == 0)&&(response == 200)); retry--; } return FALSE; }