示例#1
0
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;
}
示例#2
0
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;
}