how to properly reuse a curl handle

c, curl, handle, libcurl

Solution

If I understand the question correctly you would like to know if you can make a call to `curl_easy_perform()` and then only change the url through `curl_easy_setopt()` and then make a second call? This should work without any errors since the function does not change any previously set options for the handle. This is a short working example:

size_t writeCallback(char* contents, size_t size, size_t nmemb, std::string* buffer) {
  size_t realsize = size * nmemb;
  if(buffer == NULL) {
    return 0;
  }
  buffer->append(contents, realsize);
  return realsize;  
}

int main(int argc, char** argv) {
  std::string buffer;

  // Initialize global.
  curl_global_init(CURL_GLOBAL_ALL);

  // Start a libcurl easy session.
  CURL* ch = curl_easy_init();
  if (!ch) {
    // Something went wrong
    curl_global_cleanup();
    return -1;
  }

  // These options will only be set once.
  curl_easy_setopt(ch, CURLOPT_VERBOSE, 0);
  curl_easy_setopt(ch, CURLOPT_FOLLOWLOCATION, 1);
  curl_easy_setopt(ch, CURLOPT_USERAGENT, "Crawler");
  curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, &writeCallback);
  curl_easy_setopt(ch, CURLOPT_WRITEDATA, &buffer);

  // Push a couple of URLs onto queue.
  std::vector<const char*> queue;
  queue.push_back("http://www.google.com");
  queue.push_back("http://www.stackoverflow.com");

  const char* url;
  CURLcode code;

  do {
      // Grab an URL from the queue.
      url = queue.back();
      queue.pop_back();

      // Only change the CURLOPT_URL option for the handle
      // the rest will stay intact.
      curl_easy_setopt(ch, CURLOPT_URL, url);

      // Perform transfer.
      code = curl_easy_perform(ch);

      // Check if everything went fine.
      if (code != CURLE_OK) {
        // Handle any errors.
      }

      // Clear the buffer.
      buffer.clear();
  } while (queue.size() > 0);

  // Cleanup.
  curl_easy_cleanup(ch);
  curl_global_cleanup();

  return 0;
}

Or do I need to use curl_easy_reset() on that handle?

The answer is no since `curl_easy_perform()` not will reset any options your code should be fine and you can stick with only changing the url like `curl_easy_setoption(curl, CURLOPT_URL, <newurl>);`.

Problem

I want to properly reuse a curl handle, so that it won't give me errors and function normally. Suppose I have this piece of code: ``` CURL *curl; curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0..."); curl_easy_setopt(curl, CURLOPT_URL, "http://www.google.com"); curl_easy_perform(curl); curl_easy_setopt(curl, CURLOPT_URL, "http://www.bbc.com"); curl_easy_perform(curl); curl_easy_cleanup(curl); curl_global_cleanup(); ``` Would this be a good or correct way of reusing a curl handle? Or do I need to use `curl_easy_reset()` on that handle? I would also appreciate if anyone suggested what you should avoid doing in curl. Maybe someone could give me a link to an already existing source of information?

Original source