cURL / Mailing Lists / curl-library / Single Mail

curl-library

curl_multi_perform usage & easy handle "reset"

From: Davide Pippa <thepyper_at_gmail.com>
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