cURL / Mailing Lists / curl-library / Single Mail

curl-library

Curl write callback doesn't get called for some handles

From: Jayaprakasam, Kannan <kjayaprakasam_at_informatica.com>
Date: Wed, 20 Apr 2011 16:53:06 +0530

I just followed the curl multihandle example given in
http://curl.haxx.se/libcurl/c/multi-single.html with the following
modifications:

    1. I added 2 handles to the multihandle instead of one.

    2. I set CURLOPT_WRITEDATA AND CURLOPT_WRITEFUNCTION curl options on
both the handles.

The responses are supposed to go to the write callback function, and not
to stdout. But when I run the program, for one curl handle, the response
gets written to stdout, and for the other, the write callback function
gets called. If you are interested below is my complete program. I'm not
just trying to try out the examples, I face a similar problem in my real
code (only it is worse there, for some curl handles response neither
goes to stdout nor to callback), so it is important. Please help before
I shoot myself.

 

     #include <stdio.h>

    #include <string>

    #include<iostream>

     

    /* somewhat unix-specific */

    #include <sys/time.h>

    #include <unistd.h>

     

    /* curl stuff */

    #include <curl/curl.h>

    using namespace std;

    size_t write_data(void *buffer, size_t size, size_t nmemb, void
*userp) //no ordering of responses against requests maintained yet.

    {

            cout << "\nwrite_data called with non 0 data with userp " <<
userp;

            cout.flush();

            string* stored_response = (string*)userp;

            string chunk((char*)buffer,nmemb*size/sizeof(char));

            stored_response->append(chunk);

            return nmemb*size;

    

    }

    /*

     * Simply download a HTTP file.

     */

    int main(void)

    {

      CURL *http_handle;

      CURLM *multi_handle;

     

      int still_running; /* keep number of running handles */

     

      http_handle = curl_easy_init();

     

     string* response = new string("");

    cout<<"\nresponse pointer for yahoo.com=" << response;

    cout.flush();

     curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, response);

     curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION,write_data);

    

      /* set the options (I left out a few, you'll get the point anyway)
*/

      curl_easy_setopt(http_handle, CURLOPT_URL,
"http://www.yahoo.com/");

     

      /* init a multi stack */

      multi_handle = curl_multi_init();

     

      /* add the individual transfers */

      curl_multi_add_handle(multi_handle, http_handle);

     http_handle = curl_easy_init();

    

     response = new string("");

    cout<<"\nresponse pointer for google.com=" << response;

    cout.flush();

    // curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, response);

     // curl_easy_setopt(http_handle,
CURLOPT_WRITEFUNCTION,write_data);

    

      /* set the options (I left out a few, you'll get the point anyway)
*/

      curl_easy_setopt(http_handle, CURLOPT_URL,
"http://www.google.com/");

     curl_multi_add_handle(multi_handle, http_handle);

     

      /* we start some action by calling perform right away */

     int multi_perform_ret;

            do

            {

                    multi_perform_ret = curl_multi_perform(multi_handle,
&still_running);

            }

     while(multi_perform_ret == CURLM_CALL_MULTI_PERFORM);

      while(still_running) {

    cout<<"\nstill_running="<<still_running;

    cout.flush();

        struct timeval timeout;

        int rc; /* select() return code */

     

        fd_set fdread;

        fd_set fdwrite;

        fd_set fdexcep;

        int maxfd = -1;

     

        long curl_timeo = -1;

     

        FD_ZERO(&fdread);

        FD_ZERO(&fdwrite);

        FD_ZERO(&fdexcep);

     

        /* set a suitable timeout to play around with */

    /*

        timeout.tv_sec = 1;

        timeout.tv_usec = 0;

     

        curl_multi_timeout(multi_handle, &curl_timeo);

        if(curl_timeo >= 0) {

          timeout.tv_sec = curl_timeo / 1000;

          if(timeout.tv_sec > 1)

            timeout.tv_sec = 1;

          else

            timeout.tv_usec = (curl_timeo % 1000) * 1000;

        }

    */

     

        /* get file descriptors from the transfers */

        curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep,
&maxfd);

     

        rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

     

        switch(rc) {

        case -1:

          /* select error */

          still_running = 0;

          printf("select() returns error, this is badness\n");

          break;

        case 0:

        default:

          /* timeout or readable/writable sockets */

     do

            {

                    multi_perform_ret = curl_multi_perform(multi_handle,
&still_running);

            }

     while(multi_perform_ret == CURLM_CALL_MULTI_PERFORM);

          break;

        }

      }

     

      curl_multi_cleanup(multi_handle);

     

      curl_easy_cleanup(http_handle);

     

      return 0;

    }

 

 

Thanks

Kannan

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2011-04-20