curl-library
curl_multi_perform usage & easy handle "reset"
Date: Fri, 10 Aug 2007 12:26:59 +0200
Hi!
I'm using libcurl to do some http transfer, and I'm having some
trouble with the usage of the curl_multi_perform. I attach a test
program to show what's happening.
I try to download a web page doing a GET request
I'm using libcurl to do http transfers, I'm trying to do a GET on a
web page to download it; I'm using the multi interface with select().
My problem is that the transfer sometimes works sometime not, I guess
there is some problem in my code anyway... it happens that:
- if I first initialize my easy handle with the URL (and other needed
options) and then call the curl_multi_perform(), then the transfer
works;
- if I first do a curl_multi_perform() on an uninitialized easy handle
(as it is returned by curl_easy_init()) it says "no URL"; that's ok;
then I initialize the easy handle and call again the
curl_multi_perform(); here the transfer does not work. Is there any
missing initialization/reset to do between two transfers?
I have the same problem trying to do POST operations.
I'm using libcurl 7.16.4 under Mac os X 10.4.9.
Here is the code of a test program I've extracted from my app; if you
set the TRIGGER_GET_AT_CYCLE at 0 it works, if you set it at
1,2,3,4... it does not work.
Note: I know code here contains an useless select(), anyway that's to make code
the same of the application that may use more that one easy handle...
Thanks for the help, sorry if that's a very trivial question probably! :)
Davide
--------------------------------------------------------- test.cpp
---------------------
#include <sys/select.h>
#include <iostream>
#include <curl/curl.h>
#define TRIGGER_GET_AT_CYCLE 0
int main(int argc, char **argv) {
CURLM* multi;
CURL* easy;
// Init libcurl
curl_global_init(CURL_GLOBAL_ALL);
// Create multi handle
multi = curl_multi_init();
// Create easy handle
easy = curl_easy_init();
// Set some options
curl_easy_setopt(easy,CURLOPT_HTTPAUTH,CURLAUTH_ANYSAFE);
curl_easy_setopt(easy,CURLOPT_VERBOSE,1);
// Add to multi hanle
curl_multi_add_handle(multi,easy);
// Make fdset for multi handle
fd_set read_fds, write_fds, exc_fds; int high_fd;
FD_ZERO(&read_fds); FD_ZERO(&write_fds); FD_ZERO(&exc_fds); high_fd = 0;
curl_multi_fdset(multi,&read_fds,&write_fds,&exc_fds,&high_fd);
struct timeval to;
to.tv_sec = 333 / 1000;
to.tv_usec = (333 % 1000) * 1000;
// Cycle
for (int i = 0; i < 100; i++) {
std::cerr << "Cycle " << i << "\n";
if (i == TRIGGER_GET_AT_CYCLE) {
CURLcode res;
res = curl_easy_setopt(easy,CURLOPT_URL,"www.google.com");
res = curl_easy_setopt(easy,CURLOPT_AUTOREFERER,1);
res = curl_easy_setopt(easy,CURLOPT_ENCODING,"gzip");
res = curl_easy_setopt(easy,CURLOPT_FOLLOWLOCATION,1);
res = curl_easy_setopt(easy,CURLOPT_UNRESTRICTED_AUTH,1);
res = curl_easy_setopt(easy,CURLOPT_MAXREDIRS,20);
res = curl_easy_setopt(easy,CURLOPT_HTTPGET,1);
res = curl_easy_setopt(easy,CURLOPT_TIMEOUT,1000);
}
// Wait for activity with timeout
select(high_fd,&read_fds,&write_fds,&exc_fds,&to);
// Perform activity with multi handle
int running;
curl_multi_perform(multi,&running);
// Manage messages
CURLMsg *msg; int remaining;
while (msg = curl_multi_info_read(multi,&remaining)) {
if ((msg->easy_handle == easy) && (msg->msg == CURLMSG_DONE)) {
std::cerr << "Done!\n";
}
}
// Wait some time
usleep(1000000);
}
// Delete multi hanle
curl_multi_remove_handle(multi,easy);
curl_multi_cleanup(multi);
// Delete easy handle
curl_easy_cleanup(easy);
return(0);
}
Received on 2007-08-10