Example #1
0
int test(char *URL)
{
  CURL *c;
  CURLM *m = NULL;
  int res = 0;
  int running=1;
  double connect_time = 0.0;
  struct timeval mp_start;
  char mp_timedout = FALSE;

  if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    fprintf(stderr, "curl_global_init() failed\n");
    return TEST_ERR_MAJOR_BAD;
  }

  if ((c = curl_easy_init()) == NULL) {
    fprintf(stderr, "curl_easy_init() failed\n");
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  test_setopt(c, CURLOPT_HEADER, 1L);
  test_setopt(c, CURLOPT_URL, URL);

  if ((m = curl_multi_init()) == NULL) {
    fprintf(stderr, "curl_multi_init() failed\n");
    curl_easy_cleanup(c);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  if ((res = (int)curl_multi_add_handle(m, c)) != CURLM_OK) {
    fprintf(stderr, "curl_multi_add_handle() failed, "
            "with code %d\n", res);
    curl_multi_cleanup(m);
    curl_easy_cleanup(c);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  mp_timedout = FALSE;
  mp_start = tutil_tvnow();

  while (running) {
    res = (int)curl_multi_perform(m, &running);
    if (tutil_tvdiff(tutil_tvnow(), mp_start) >
        MULTI_PERFORM_HANG_TIMEOUT) {
      mp_timedout = TRUE;
      break;
    }
    if (running <= 0) {
      fprintf(stderr, "nothing left running.\n");
      break;
    }
  }

  if (mp_timedout) {
    if (mp_timedout) fprintf(stderr, "mp_timedout\n");
    fprintf(stderr, "ABORTING TEST, since it seems "
            "that it would have run forever.\n");
    res = TEST_ERR_RUNS_FOREVER;
  }

  curl_easy_getinfo(c, CURLINFO_CONNECT_TIME, &connect_time);
  if (connect_time <= 0.0) {
    fprintf(stderr, "connect time is <=0.0\n");
    res = TEST_ERR_MAJOR_BAD;
  }

test_cleanup:

  if(m) {
    curl_multi_remove_handle(m, c);
    curl_multi_cleanup(m);
  }
  curl_easy_cleanup(c);
  curl_global_cleanup();

  return res;
}
Example #2
0
/*
 * Upload all files over HTTP/2, using the same physical connection!
 */
int main(int argc, char **argv)
{
  struct input trans[NUM_HANDLES];
  CURLM *multi_handle;
  int i;
  int still_running = 0; /* keep number of running handles */
  const char *filename = "index.html";
  int num_transfers;

  if(argc > 1) {
    /* if given a number, do that many transfers */
    num_transfers = atoi(argv[1]);

    if(!num_transfers || (num_transfers > NUM_HANDLES))
      num_transfers = 3; /* a suitable low default */

    if(argc > 2)
      /* if given a file name, upload this! */
      filename = argv[2];
  }
  else
    num_transfers = 3;

  /* init a multi stack */
  multi_handle = curl_multi_init();

  for(i = 0; i<num_transfers; i++) {
    setup(&trans[i], i, filename);

    /* add the individual transfer */
    curl_multi_add_handle(multi_handle, trans[i].hnd);
  }

  curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);

  /* We do HTTP/2 so let's stick to one connection per host */
  curl_multi_setopt(multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, 1L);

  /* we start some action by calling perform right away */
  curl_multi_perform(multi_handle, &still_running);

  while(still_running) {
    struct timeval timeout;
    int rc; /* select() return code */
    CURLMcode mc; /* curl_multi_fdset() 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 */
    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

    if(mc != CURLM_OK) {
      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
      break;
    }

    /* On success the value of maxfd is guaranteed to be >= -1. We call
       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
       to sleep 100ms, which is the minimum suggested value in the
       curl_multi_fdset() doc. */

    if(maxfd == -1) {
#ifdef _WIN32
      Sleep(100);
      rc = 0;
#else
      /* Portable sleep for platforms other than Windows. */
      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
      rc = select(0, NULL, NULL, NULL, &wait);
#endif
    }
    else {
      /* Note that on some platforms 'timeout' may be modified by select().
         If you need access to the original value save a copy beforehand. */
      rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
    }

    switch(rc) {
    case -1:
      /* select error */
      break;
    case 0:
    default:
      /* timeout or readable/writable sockets */
      curl_multi_perform(multi_handle, &still_running);
      break;
    }
  }

  curl_multi_cleanup(multi_handle);

  for(i = 0; i<num_transfers; i++) {
    curl_multi_remove_handle(multi_handle, trans[i].hnd);
    curl_easy_cleanup(trans[i].hnd);
  }

  return 0;
}
Example #3
0
File: lib591.c Project: 2px/curl
int test(char *URL)
{
  CURL *easy = NULL;
  CURLM *multi = NULL;
  int res = 0;
  int running;
  int msgs_left;
  CURLMsg *msg;
  FILE *upload = NULL;
  int error;

  start_test_timing();

  upload = fopen(libtest_arg3, "rb");
  if(!upload) {
    error = ERRNO;
    fprintf(stderr, "fopen() failed with error: %d (%s)\n",
            error, strerror(error));
    fprintf(stderr, "Error opening file: (%s)\n", libtest_arg3);
    return TEST_ERR_FOPEN;
  }

  res_global_init(CURL_GLOBAL_ALL);
  if(res) {
    fclose(upload);
    return res;
  }

  easy_init(easy);

  /* go verbose */
  easy_setopt(easy, CURLOPT_VERBOSE, 1L);

  /* specify target */
  easy_setopt(easy, CURLOPT_URL, URL);

  /* enable uploading */
  easy_setopt(easy, CURLOPT_UPLOAD, 1L);

  /* data pointer for the file read function */
  easy_setopt(easy, CURLOPT_READDATA, upload);

  /* use active mode FTP */
  easy_setopt(easy, CURLOPT_FTPPORT, "-");

  /* server connection timeout */
  easy_setopt(easy, CURLOPT_ACCEPTTIMEOUT_MS,
              strtol(libtest_arg2, NULL, 10)*1000);

  multi_init(multi);

  multi_add_handle(multi, easy);

  for(;;) {
    struct timeval interval;
    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    long timeout = -99;
    int maxfd = -99;

    multi_perform(multi, &running);

    abort_on_test_timeout();

    if(!running)
      break; /* done */

    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);

    /* At this point, maxfd is guaranteed to be greater or equal than -1. */

    multi_timeout(multi, &timeout);

    /* At this point, timeout is guaranteed to be greater or equal than -1. */

    if(timeout != -1L) {
      int itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
      interval.tv_sec = itimeout/1000;
      interval.tv_usec = (itimeout%1000)*1000;
    }
    else {
      interval.tv_sec = 0;
      interval.tv_usec = 100000L; /* 100 ms */
    }

    select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &interval);

    abort_on_test_timeout();
  }

  msg = curl_multi_info_read(multi, &msgs_left);
  if(msg)
    res = msg->data.result;

test_cleanup:

  /* undocumented cleanup sequence - type UA */

  curl_multi_cleanup(multi);
  curl_easy_cleanup(easy);
  curl_global_cleanup();

  /* close the local file */
  fclose(upload);

  return res;
}
Example #4
0
int cetcd_multi_watch(cetcd_client *cli) {
    int           i, count;
    int           maxfd, left, added;
    long          timeout;
    long          backoff, backoff_max;
    fd_set        r, w, e;
    cetcd_array   *watchers;
    cetcd_watcher *watcher;
    CURLM         *mcurl;

    struct timeval tv;

    mcurl = curl_multi_init();
    watchers = &cli->watchers;
    count = cetcd_array_size(watchers);
    for (i = 0; i < count; ++i) {
        watcher = cetcd_array_get(watchers, i);
        curl_easy_setopt(watcher->curl, CURLOPT_PRIVATE, watcher);
        curl_multi_add_handle(mcurl, watcher->curl);
    }
    backoff = 100; /*100ms*/
    backoff_max = 1000; /*1 sec*/
    for(;;) {
        curl_multi_perform(mcurl, &left);
        if (left) {
            FD_ZERO(&r);
            FD_ZERO(&w);
            FD_ZERO(&e);
            curl_multi_fdset(mcurl, &r, &w, &e, &maxfd);
            curl_multi_timeout(mcurl, &timeout);
            if (timeout == -1) {
                timeout = 100; /*wait for 0.1 seconds*/
            }
            tv.tv_sec = timeout/1000;
            tv.tv_usec = (timeout%1000)*1000;

            /*TODO handle errors*/
            select(maxfd+1, &r, &w, &e, &tv);
        }
        added = cetcd_reap_watchers(cli, mcurl);
        if (added == 0 && left == 0) {
        /* It will call curl_multi_perform immediately if:
         * 1. left is 0
         * 2. a new attempt should be issued
         * It is expected to sleep a mount time between attempts.
         * So we fix this by increasing added counter only
         * when a new request should be issued.
         * When added is 0, maybe there are retring requests or nothing.
         * Either situations should wait before issuing the request.
         * */
            if (backoff < backoff_max) {
                backoff = 2 * backoff;
            } else {
                backoff = backoff_max;
            }
            tv.tv_sec = backoff/1000;
            tv.tv_usec = (backoff%1000) * 1000;
            select(1, 0, 0, 0, &tv);
        }
    }
    curl_multi_cleanup(mcurl);
    return count;
}
Example #5
0
/*
 * Simply download two HTTP files!
 */
int main(void)
{
  CURL *http_handle;
  CURL *http_handle2;
  CURLM *multi_handle;

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

  http_handle = curl_easy_init();
  http_handle2 = curl_easy_init();

  /* set options */
  curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/");

  /* set options */
  curl_easy_setopt(http_handle2, CURLOPT_URL, "http://localhost/");

  /* init a multi stack */
  multi_handle = curl_multi_init();

  /* add the individual transfers */
  curl_multi_add_handle(multi_handle, http_handle);
  curl_multi_add_handle(multi_handle, http_handle2);

  /* we start some action by calling perform right away */
  curl_multi_perform(multi_handle, &still_running);

  while(still_running) {
    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);

    /* In a real-world program you OF COURSE check the return code of the
       function calls.  On success, the value of maxfd is guaranteed to be
       greater or equal than -1.  We call select(maxfd + 1, ...), specially in
       case of (maxfd == -1), we call select(0, ...), which is basically equal
       to sleep. */

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

    switch(rc) {
    case -1:
      /* select error */
      break;
    case 0:
    default:
      /* timeout or readable/writable sockets */
      curl_multi_perform(multi_handle, &still_running);
      break;
    }
  }

  curl_multi_cleanup(multi_handle);

  curl_easy_cleanup(http_handle);
  curl_easy_cleanup(http_handle2);

  return 0;
}
Example #6
0
// Responsible to read the tileData from the service
// takes a vector of tileCoordinates to be read from the service.
bool MapzenVectorTileJson::LoadTile(std::vector<glm::ivec3> _tileCoords) {
    std::vector<std::unique_ptr<std::string>> urls;

    if(_tileCoords.size() == 0) {
        logMsg("No tiles to fetch.");
    }

    //construct tileID and url for every tileCoord
    for(auto& tileCoord : _tileCoords) {
        urls.push_back(constructURL(tileCoord));
    }

    CURLM *multiHandle;
    CURLMsg *handleMsg;
    // file descriptors to be used with curl_multi_fdset and select()
    fd_set fdRead;
    fd_set fdWrite;
    fd_set fdExcep;
    int fdMax;
    struct timeval timeout;
    int rc; //return value for select() call
    CURLMcode cres;

    int queuedHandles, numHandles = urls.size();
    int prevHandle;
    int fetchTry = 0; //Counter to check for curl/select timeOuts.. maxed by static count MAX_FETCH_TRY
    int fdsetTimeoutCount = 0;

    // out will store the stringStream contents from libCurl
    std::stringstream *out[urls.size()];

    curl_global_init(CURL_GLOBAL_DEFAULT);

    multiHandle = curl_multi_init();
    int count = 0;

    // initialize curl simple interface for every url
    for(auto& url : urls) {
        out[count] = new std::stringstream;
        curlInit(multiHandle, *url.get(), out[count]);
        count++;
    }

    //do curl stuff
    if(multiHandle) {
        //start fetching
        cres = curl_multi_perform(multiHandle, &numHandles);
        if(cres != CURLM_OK) {
            logMsg("curl_multi_perform failed %d\n", cres);
            for(auto i = 0; i < urls.size(); i++) {
                delete out[i];
            }
            urls.clear();
            return false;
        }

        //if numHandles is 0, then multi_perform has no easy handles to perform fetching
        if(!numHandles) {
            logMsg("Number of easy handles returned by curl_multi_perform is 0, should not be.");
            for(auto i = 0; i < urls.size(); i++) {
                delete out[i];
            }
            urls.clear();
            return true;
        }
        
        //Start fetching info until no easy handle left to fetch data
        do {
            //set all file descriptors to 0
            FD_ZERO(&fdRead);
            FD_ZERO(&fdWrite);
            FD_ZERO(&fdExcep);

            //timeout specification for select() call
            //select() will unblock either when a fd is ready or tileout is reached
            timeout.tv_sec = 1; //enough time for fd to be ready reading data... could be optimized.
            timeout.tv_usec = 0;

            //get file descriptors from the transfer
            cres = curl_multi_fdset(multiHandle, &fdRead, &fdWrite, &fdExcep, &fdMax);

            if(cres != CURLM_OK) {
                logMsg("curl_multi_fdset failed: %d\n", cres);
                for(auto i = 0; i < urls.size(); i++) {
                    delete out[i];
                }
                urls.clear();
                return false;
            }
            
            //wait and repeat until curl has something to report to the kernel wrt file descriptors
            // TODO: if no internet, then this gets stuck... put a timeout here.
            while(fdMax < 0 && fdsetTimeoutCount < 20) {
                //TODO: Get a better heuristic on the sleep milliseconds

                //sleeps for 100 msec and calls perform and fdset to see if multi perform has started its job
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
                cres = curl_multi_perform(multiHandle, &numHandles);
                prevHandle = numHandles;
                curl_multi_fdset(multiHandle, &fdRead, &fdWrite, &fdExcep, &fdMax);
                std::cout<<"Here\n"; //TODO: Remove this. Its here to test how many times this loop runs till
                                     //multi_perform starts doing stuff
                fdsetTimeoutCount++;
            }

            if(fdMax < 0) {
                logMsg("fdMax set timeout: fdmax still not set by curl_multi_fdset. Internet connection??");
                for(auto i = 0; i < urls.size(); i++) {
                    delete out[i];
                }
                urls.clear();
                return false;
            }

            //select blocks the thread until the fd set by curl is ready with data.
            rc = select(fdMax+1, &fdRead, &fdWrite, &fdExcep, &timeout);

            // helper variables to convert extracted data to Json on the spot instead of waiting for all urls to be
            // fetched and then converting the extracted data to json
            char *url;
            char *tmpOutData; //to read the CURLINFO_PRIVATE data which is type casted to char* from stringstream*
            std::string tmpJsonData;
            int length;
            std::shared_ptr<Json::Value> jsonVal(new Json::Value);
            Json::Reader jsonReader;

            // see what select returned
            switch(rc) {
                case -1:
                    //select call ERRORed
                    break;
                case 0:
                    std::cout<<"Here timeout\n"; //TODO: Remove this. Its here to test how many times select times out.
                                                 // So far never with 1 sec of timeout.
                    //select call Timed out. No fd ready to read anything.
                    fetchTry++;
                    if(fetchTry == MAX_FETCH_TRY) {
                        curl_multi_cleanup(multiHandle);
                        curl_global_cleanup();
                        for(auto i = 0; i < urls.size(); i++) {
                            delete out[i];
                        }
                        urls.clear();
                        return false;
                    }
                    break;
                default:
                    // sleep for 5 msec to give enough time for curl to read data for any of the file descriptors.
                    std::this_thread::sleep_for(std::chrono::milliseconds(5));
                    std::cout<<"Possible Change\n"; //TODO: Remove this. Its here to test how many times fd is ready and
                                                    // will result in a complete data read
                    //Perform again to see what happened with individual easy handles
                    curl_multi_perform(multiHandle,&numHandles);
                    // if easy  handle status changed some urls are done.
                    if(prevHandle != numHandles) {
                        std::cout<<"Change happened\n";//TODO: Remove this. Only here for testing
                        prevHandle = numHandles;
                        handleMsg = curl_multi_info_read(multiHandle, &queuedHandles);
                        // for every url done fill the jsonValue
                        for(auto qHandItr = 0; qHandItr <= queuedHandles; qHandItr++) {
                            if(handleMsg->msg == CURLMSG_DONE) {
                                //get the url from the easyHandle
                                curl_easy_getinfo(handleMsg->easy_handle, CURLINFO_EFFECTIVE_URL , &url);
                                //get the tmpOutData which is holding the extracted info from the url
                                curl_easy_getinfo(handleMsg->easy_handle, CURLINFO_PRIVATE , &tmpOutData);
                                // typecast back from char* to std::stringstream
                                tmpJsonData = ((std::stringstream *)tmpOutData)->str();
                                length = tmpJsonData.size();
                                jsonReader.parse(tmpJsonData.c_str(), tmpJsonData.c_str() + length, *(jsonVal.get()));
                                // no way to get what ID this url was for so have to extract ID from url
                                m_JsonRoots[extractIDFromUrl(std::string(url))] = jsonVal;
                                logMsg("R: %d - %s <%s>\n", handleMsg->data.result, curl_easy_strerror(handleMsg->data.result), url);
                                curl_multi_remove_handle(multiHandle, handleMsg->easy_handle);
                                curl_easy_cleanup(handleMsg->easy_handle);
                            }
                        }
                    }
                    break;
            }
        }while(numHandles);
        
        curl_multi_cleanup(multiHandle);
        curl_global_cleanup();
    }

    for(auto i = 0; i < urls.size(); i++) {
        delete out[i];
    }
    urls.clear();
    return true;
}
Example #7
0
static void
tr_webThreadFunc( void * vsession )
{
    CURLM * multi;
    struct tr_web * web;
    int taskCount = 0;
    struct tr_web_task * task;
    tr_session * session = vsession;

    /* try to enable ssl for https support; but if that fails,
     * try a plain vanilla init */
    if( curl_global_init( CURL_GLOBAL_SSL ) )
        curl_global_init( 0 );

    web = tr_new0( struct tr_web, 1 );
    web->close_mode = ~0;
    web->taskLock = tr_lockNew( );
    web->tasks = NULL;
    web->curl_verbose = getenv( "TR_CURL_VERBOSE" ) != NULL;
    web->cookie_filename = tr_buildPath( session->configDir, "cookies.txt", NULL );

    multi = curl_multi_init( );
    session->web = web;

    for( ;; )
    {
        long msec;
        int unused;
        CURLMsg * msg;
        CURLMcode mcode;

        if( web->close_mode == TR_WEB_CLOSE_NOW )
            break;
        if( ( web->close_mode == TR_WEB_CLOSE_WHEN_IDLE ) && ( web->tasks == NULL ) )
            break;

        /* add tasks from the queue */
        tr_lockLock( web->taskLock );
        while(( task = tr_list_pop_front( &web->tasks )))
        {
            dbgmsg( "adding task to curl: [%s]", task->url );
            curl_multi_add_handle( multi, createEasy( session, web, task ));
            /*fprintf( stderr, "adding a task.. taskCount is now %d\n", taskCount );*/
            ++taskCount;
        }
        tr_lockUnlock( web->taskLock );

        /* maybe wait a little while before calling curl_multi_perform() */
        msec = 0;
        curl_multi_timeout( multi, &msec );
        if( msec < 0 )
            msec = THREADFUNC_MAX_SLEEP_MSEC;
        if( session->isClosed )
            msec = 100; /* on shutdown, call perform() more frequently */
        if( msec > 0 )
        {
            int usec;
            int max_fd;
            struct timeval t;
            fd_set r_fd_set, w_fd_set, c_fd_set;

            max_fd = 0;
            FD_ZERO( &r_fd_set );
            FD_ZERO( &w_fd_set );
            FD_ZERO( &c_fd_set );
            curl_multi_fdset( multi, &r_fd_set, &w_fd_set, &c_fd_set, &max_fd );

            if( msec > THREADFUNC_MAX_SLEEP_MSEC )
                msec = THREADFUNC_MAX_SLEEP_MSEC;

            usec = msec * 1000;
            t.tv_sec =  usec / 1000000;
            t.tv_usec = usec % 1000000;
            tr_select( max_fd+1, &r_fd_set, &w_fd_set, &c_fd_set, &t );
        }

        /* call curl_multi_perform() */
        do {
            mcode = curl_multi_perform( multi, &unused );
        } while( mcode == CURLM_CALL_MULTI_PERFORM );

        /* pump completed tasks from the multi */
        while(( msg = curl_multi_info_read( multi, &unused )))
        {
            if(( msg->msg == CURLMSG_DONE ) && ( msg->easy_handle != NULL ))
            {
                double total_time;
                struct tr_web_task * task;
                long req_bytes_sent;
                CURL * e = msg->easy_handle;
                curl_easy_getinfo( e, CURLINFO_PRIVATE, (void*)&task );
                curl_easy_getinfo( e, CURLINFO_RESPONSE_CODE, &task->code );
                curl_easy_getinfo( e, CURLINFO_REQUEST_SIZE, &req_bytes_sent );
                curl_easy_getinfo( e, CURLINFO_TOTAL_TIME, &total_time );
                task->did_connect = task->code>0 || req_bytes_sent>0;
                task->did_timeout = !task->code && ( total_time >= task->timeout_secs );
                curl_multi_remove_handle( multi, e );
                curl_easy_cleanup( e );
/*fprintf( stderr, "removing a completed task.. taskCount is now %d (response code: %d, response len: %d)\n", taskCount, (int)task->code, (int)evbuffer_get_length(task->response) );*/
                tr_runInEventThread( task->session, task_finish_func, task );
                --taskCount;
            }
        }

#if 0
{
tr_list * l;
for( l=web->tasks; l!=NULL; l=l->next )
    fprintf( stderr, "still pending: %s\n", ((struct tr_web_task*)l->data)->url );
}
fprintf( stderr, "loop is ending... web is closing\n" );
#endif
    }

    /* Discard any remaining tasks.
     * This is rare, but can happen on shutdown with unresponsive trackers. */
    while(( task = tr_list_pop_front( &web->tasks ))) {
        dbgmsg( "Discarding task \"%s\"", task->url );
        task_free( task );
    }

    /* cleanup */
    curl_multi_cleanup( multi );
    tr_lockFree( web->taskLock );
    tr_free( web->cookie_filename );
    tr_free( web );
    session->web = NULL;
}
static int
testExternalPut ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  int max;
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;
  unsigned int pos = 0;
  int done_flag = 0;

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_DEBUG,
                        11082,
                        NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
  if (d == NULL)
    return 256;
  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11082/hello_world");
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
  curl_easy_setopt (c, CURLOPT_READDATA, &pos);
  curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
  /*
     // by not giving the file size, we force chunking!
     curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
   */
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
  // NOTE: use of CONNECTTIMEOUT without also
  //   setting NOSIGNAL results in really weird
  //   crashes on my system!
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);


  multi = curl_multi_init ();
  if (multi == NULL)
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 512;
    }
  mret = curl_multi_add_handle (multi, c);
  if (mret != CURLM_OK)
    {
      curl_multi_cleanup (multi);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 1024;
    }
  start = time (NULL);
  while ((time (NULL) - start < 5) && (multi != NULL))
    {
      max = 0;
      FD_ZERO (&rs);
      FD_ZERO (&ws);
      FD_ZERO (&es);
      curl_multi_perform (multi, &running);
      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
      if (mret != CURLM_OK)
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 2048;
        }
      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 4096;
        }
      tv.tv_sec = 0;
      tv.tv_usec = 1000;
      select (max + 1, &rs, &ws, &es, &tv);
      curl_multi_perform (multi, &running);
      if (running == 0)
        {
          msg = curl_multi_info_read (multi, &running);
          if (msg == NULL)
            break;
          if (msg->msg == CURLMSG_DONE)
            {
              if (msg->data.result != CURLE_OK)
                printf ("%s failed at %s:%d: `%s'\n",
                        "curl_multi_perform",
                        __FILE__,
                        __LINE__, curl_easy_strerror (msg->data.result));
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              c = NULL;
              multi = NULL;
            }
        }
      MHD_run (d);
    }
  if (multi != NULL)
    {
      curl_multi_remove_handle (multi, c);
      curl_easy_cleanup (c);
      curl_multi_cleanup (multi);
    }
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello_world"))
    return 8192;
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 16384;
  return 0;
}
Example #9
0
int main(void)
{
  CURL *curl;
  CURLM *mcurl;
  int still_running = 1;
  struct timeval mp_start;

  curl_global_init(CURL_GLOBAL_DEFAULT);

  curl = curl_easy_init();
  if(!curl)
    return 1;

  mcurl = curl_multi_init();
  if(!mcurl)
    return 2;

  /* Set username and password */
  curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
  curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");

  /* This will retrieve message 1 from the user's mailbox */
  curl_easy_setopt(curl, CURLOPT_URL, "pop3://pop.example.com/1");

  /* Tell the multi stack about our easy handle */
  curl_multi_add_handle(mcurl, curl);

  /* Record the start time which we can use later */
  mp_start = tvnow();

  /* We start some action by calling perform right away */
  curl_multi_perform(mcurl, &still_running);

  while(still_running) {
    struct timeval timeout;
    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int maxfd = -1;
    int rc;
    CURLMcode mc; /* curl_multi_fdset() return code */

    long curl_timeo = -1;

    /* Initialise the file descriptors */
    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(mcurl, &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 */
    mc = curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);

    if(mc != CURLM_OK)
    {
      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
      break;
    }

    /* On success the value of maxfd is guaranteed to be >= -1. We call
       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
       to sleep 100ms, which is the minimum suggested value in the
       curl_multi_fdset() doc. */

    if(maxfd == -1) {
#ifdef _WIN32
      Sleep(100);
      rc = 0;
#else
      /* Portable sleep for platforms other than Windows. */
      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
      rc = select(0, NULL, NULL, NULL, &wait);
#endif
    }
    else {
      /* Note that on some platforms 'timeout' may be modified by select().
         If you need access to the original value save a copy beforehand. */
      rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
    }

    if(tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
      fprintf(stderr,
              "ABORTING: Since it seems that we would have run forever.\n");
      break;
    }

    switch(rc) {
    case -1:  /* select error */
      break;
    case 0:   /* timeout */
    default:  /* action */
      curl_multi_perform(mcurl, &still_running);
      break;
    }
  }

  /* Always cleanup */
  curl_multi_remove_handle(mcurl, curl);
  curl_multi_cleanup(mcurl);
  curl_easy_cleanup(curl);
  curl_global_cleanup();

  return 0;
}
Example #10
0
int main(void)
{
  CURL *curl;
  CURLM *mcurl;
  int still_running = 1;
  struct timeval mp_start;

  curl_global_init(CURL_GLOBAL_DEFAULT);

  curl = curl_easy_init();
  if(!curl)
    return 1;

  mcurl = curl_multi_init();
  if(!mcurl)
    return 2;

  /* Set username and password */
  curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
  curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");

  /* This will fetch message 1 from the user's inbox */
  curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX/;UID=1");

  /* Tell the multi stack about our easy handle */
  curl_multi_add_handle(mcurl, curl);

  /* Record the start time which we can use later */
  mp_start = tvnow();

  /* We start some action by calling perform right away */
  curl_multi_perform(mcurl, &still_running);

  while(still_running) {
    struct timeval timeout;
    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int maxfd = -1;
    int rc;

    long curl_timeo = -1;

    /* Initialise the file descriptors */
    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(mcurl, &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(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);

    /* In a real-world program you OF COURSE check the return code of the
       function calls.  On success, the value of maxfd is guaranteed to be
       greater or equal than -1.  We call select(maxfd + 1, ...), specially in
       case of (maxfd == -1), we call select(0, ...), which is basically equal
       to sleep. */
    rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);

    if(tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
      fprintf(stderr,
              "ABORTING: Since it seems that we would have run forever.\n");
      break;
    }

    switch(rc) {
    case -1:  /* select error */
      break;
    case 0:   /* timeout */
    default:  /* action */
      curl_multi_perform(mcurl, &still_running);
      break;
    }
  }

  /* Always cleanup */
  curl_multi_remove_handle(mcurl, curl);
  curl_multi_cleanup(mcurl);
  curl_easy_cleanup(curl);
  curl_global_cleanup();

  return 0;
}
Example #11
0
int test(char *URL)
{
  CURL *easy = NULL;
  CURLM *multi = NULL;
  int res = 0;
  int running;
  int msgs_left;
  int phase;
  CURLMsg *msg;

  start_test_timing();

  res_global_init(CURL_GLOBAL_ALL);
  if(res) {
    return res;
  }

  easy_init(easy);

  multi_init(multi);

  for (phase = CONNECT_ONLY_PHASE; phase < LAST_PHASE; ++phase) {
    /* go verbose */
    easy_setopt(easy, CURLOPT_VERBOSE, 1L);

    /* specify target */
    easy_setopt(easy, CURLOPT_URL, URL);

    /* enable 'CONNECT_ONLY' option when in connect phase */
    if (phase == CONNECT_ONLY_PHASE)
      easy_setopt(easy, CURLOPT_CONNECT_ONLY, 1L);

    /* enable 'NOBODY' option to send 'QUIT' command in quit phase */
    if (phase == QUIT_PHASE) {
      easy_setopt(easy, CURLOPT_CONNECT_ONLY, 0L);
      easy_setopt(easy, CURLOPT_NOBODY, 1L);
      easy_setopt(easy, CURLOPT_FORBID_REUSE, 1L);
    }

    multi_add_handle(multi, easy);

    for(;;) {
      struct timeval interval;
      fd_set fdread;
      fd_set fdwrite;
      fd_set fdexcep;
      long timeout = -99;
      int maxfd = -99;

      multi_perform(multi, &running);

      abort_on_test_timeout();

      if(!running)
        break; /* done */

      FD_ZERO(&fdread);
      FD_ZERO(&fdwrite);
      FD_ZERO(&fdexcep);

      multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);

      /* At this point, maxfd is guaranteed to be greater or equal than -1. */

      multi_timeout(multi, &timeout);

      /* At this point, timeout is guaranteed to be greater or equal than -1. */

      if(timeout != -1L) {
        int itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
        interval.tv_sec = itimeout/1000;
        interval.tv_usec = (itimeout%1000)*1000;
      }
      else {
        interval.tv_sec = TEST_HANG_TIMEOUT/1000+1;
        interval.tv_usec = 0;
      }

      select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &interval);

      abort_on_test_timeout();
    }

    msg = curl_multi_info_read(multi, &msgs_left);
    if(msg)
      res = msg->data.result;

    multi_remove_handle(multi, easy);
  }

test_cleanup:

  /* undocumented cleanup sequence - type UA */

  curl_multi_cleanup(multi);
  curl_easy_cleanup(easy);
  curl_global_cleanup();

  return res;
}
std::set<std::string> YoutubeCrawler::getVideoFile(std::map<std::string, std::string> &result){
	std::set<std::string> unFinishVids;
	if(result.size() == 0){
		return unFinishVids;
	}
	CURL *handle = curl_easy_init();
	if(handle == NULL){
		return unFinishVids;
	}
	CURLM *mhandle = curl_multi_init();
	if(mhandle == NULL){
		curl_easy_cleanup(handle);
		return unFinishVids;
	}
	CURLcode code;
	curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writeFileCallback);
	curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);
	curl_easy_setopt(handle, CURLOPT_MAXREDIRS, 10);
	curl_easy_setopt(handle, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)");
	curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, 10);
	curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1);
	curl_easy_setopt(handle, CURLOPT_LOW_SPEED_LIMIT, 1);
	curl_easy_setopt(handle, CURLOPT_LOW_SPEED_TIME, 60);
	std::map<std::string, CURL*> handleList;
	std::map<std::string, RecInfo> addrsList;
	BDB::AddrType tmpAddr;
	std::pair<std::map<std::string, RecInfo>::iterator, bool> addrIt;
	RecInfo recInfo;
	recInfo.ybdb = &ybdb;
	for(std::map<std::string, std::string>::iterator it = result.begin(); it != result.end(); it++){
		tmpAddr = ybdb.put("", 0);
		if(tmpAddr == -1){
			continue;
		}
		recInfo.addr = tmpAddr;
		recInfo.size = 0;
		addrIt = addrsList.insert(std::pair<std::string, RecInfo>(it->first, recInfo));
		curl_easy_setopt(handle, CURLOPT_WRITEDATA, &(addrIt.first->second));
		curl_easy_setopt(handle, CURLOPT_URL, it->second.c_str());
		handleList.insert(std::pair<std::string, CURL*>(it->first, handle));
		curl_multi_add_handle(mhandle, handle);
		handle = curl_easy_duphandle(handle);
	}
	curl_easy_cleanup(handle);
	if(handleList.size() == 0){
		curl_multi_cleanup(mhandle);
		return unFinishVids;
	}
	int runningHandles = 0;
	while(curl_multi_perform(mhandle, &runningHandles) == CURLM_CALL_MULTI_PERFORM){}
	struct timeval timeout;
	timeout.tv_sec = 0;
	timeout.tv_usec = 0;
	int max_fd = 0;
	fd_set read_fd_set;
	fd_set write_fd_set;
	fd_set exc_fd_set;
	FD_ZERO(&read_fd_set);
	FD_ZERO(&write_fd_set);
	FD_ZERO(&exc_fd_set);
	while(runningHandles > 0){
		curl_multi_fdset(mhandle, &read_fd_set, &write_fd_set, &exc_fd_set, &max_fd);
		curl_multi_timeout(mhandle, &(timeout.tv_usec));
		if(timeout.tv_usec > 0){
			select(max_fd + 1, &read_fd_set, &write_fd_set, &exc_fd_set, &timeout);
		}
		while(curl_multi_perform(mhandle, &runningHandles) == CURLM_CALL_MULTI_PERFORM){}
	}
	for(std::map<std::string, CURL*>::iterator it = handleList.begin(); it != handleList.end(); it++){
		curl_multi_remove_handle(mhandle, it->second);
		curl_easy_cleanup(it->second);
	}
	curl_multi_cleanup(mhandle);
	std::map<std::string, std::string>::iterator uIt;
	for(std::map<std::string, RecInfo>::iterator it = addrsList.begin(); it != addrsList.end(); it++){
		if(it->second.size == 0){
			unFinishVids.insert(it->first);
			ybdb.del(it->second.addr);
		}else{
			uIt = result.find(it->first);
			logRids << std::setw(11) << it->first 
				<< std::setfill('0') << std::setw(9) << std::hex << it->second.addr 
				<< std::setfill('0') << std::setw(9) << std::hex << it->second.size 
				<< getExtensionName(uIt->second) << std::endl;
			logRids.flush();
		}
	}
	return unFinishVids;
}
Example #13
0
int test(char *URL)
{
  int res = 0;
  CURLM *m = NULL;
  CURLMsg *msg; /* for picking up messages with the transfer status */
  int msgs_left; /* how many messages are left */
  int running;
  int handlenum = 0;
  struct timeval last_handle_add;

  if(parse_url_file("log/urls.txt") <= 0)
    goto test_cleanup;

  start_test_timing();

  curl_global_init(CURL_GLOBAL_ALL);

  multi_init(m);

  create_handles();

  multi_setopt(m, CURLMOPT_PIPELINING, 1L);
  multi_setopt(m, CURLMOPT_MAX_HOST_CONNECTIONS, 2L);
  multi_setopt(m, CURLMOPT_MAX_PIPELINE_LENGTH, 3L);
  multi_setopt(m, CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, 15000L);
  multi_setopt(m, CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, 10000L);

  multi_setopt(m, CURLMOPT_PIPELINING_SITE_BL, site_blacklist);
  multi_setopt(m, CURLMOPT_PIPELINING_SERVER_BL, server_blacklist);

  last_handle_add = tutil_tvnow();

  for(;;) {
    struct timeval interval;
    struct timeval now;
    long int msnow, mslast;
    fd_set rd, wr, exc;
    int maxfd = -99;
    long timeout;

    interval.tv_sec = 1;
    interval.tv_usec = 0;

    if(handlenum < num_handles) {
      now = tutil_tvnow();
      msnow = now.tv_sec * 1000 + now.tv_usec / 1000;
      mslast = last_handle_add.tv_sec * 1000 + last_handle_add.tv_usec / 1000;
      if(msnow - mslast >= urltime[handlenum] && handlenum < num_handles) {
        fprintf(stdout, "Adding handle %d\n", handlenum);
        setup_handle(URL, m, handlenum);
        last_handle_add = now;
        handlenum++;
      }
    }

    curl_multi_perform(m, &running);

    abort_on_test_timeout();

    /* See how the transfers went */
    while ((msg = curl_multi_info_read(m, &msgs_left))) {
      if (msg->msg == CURLMSG_DONE) {
        int i, found = 0;

        /* Find out which handle this message is about */
        for (i = 0; i < num_handles; i++) {
          found = (msg->easy_handle == handles[i]);
          if(found)
            break;
        }

        printf("Handle %d Completed with status %d\n", i, msg->data.result);
        curl_multi_remove_handle(m, handles[i]);
      }
    }

    if(handlenum == num_handles && !running) {
      break; /* done */
    }

    FD_ZERO(&rd);
    FD_ZERO(&wr);
    FD_ZERO(&exc);

    curl_multi_fdset(m, &rd, &wr, &exc, &maxfd);

    /* At this point, maxfd is guaranteed to be greater or equal than -1. */

    curl_multi_timeout(m, &timeout);

    if(timeout < 0)
      timeout = 1;

    interval.tv_sec = timeout / 1000;
    interval.tv_usec = (timeout % 1000) * 1000;

    interval.tv_sec = 0;
    interval.tv_usec = 1000;

    select_test(maxfd+1, &rd, &wr, &exc, &interval);

    abort_on_test_timeout();
  }

test_cleanup:

  remove_handles();

  /* undocumented cleanup sequence - type UB */

  curl_multi_cleanup(m);
  curl_global_cleanup();

  free_urls();
  return res;
}
Example #14
0
/*
 * Simply download a HTTP file.
 */
int main(int argc, char **argv)
{
  CURL *http_handle;
  CURLM *multi_handle;

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

  http_handle = curl_easy_init();

  /* set the options (I left out a few, you'll get the point anyway) */
  curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.haxx.se/");

  curl_easy_setopt(http_handle, CURLOPT_DEBUGFUNCTION, my_trace);
  curl_easy_setopt(http_handle, CURLOPT_VERBOSE, 1L);

  /* init a multi stack */
  multi_handle = curl_multi_init();

  /* add the individual transfers */
  curl_multi_add_handle(multi_handle, http_handle);

  /* we start some action by calling perform right away */
  while(CURLM_CALL_MULTI_PERFORM ==
        curl_multi_perform(multi_handle, &still_running));

  while(still_running) {
    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);

    /* In a real-world program you OF COURSE check the return code of the
       function calls.  On success, the value of maxfd is guaranteed to be
       greater or equal than -1.  We call select(maxfd + 1, ...), specially in
       case of (maxfd == -1), we call select(0, ...), which is basically equal
       to sleep. */

    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 */
      while(CURLM_CALL_MULTI_PERFORM ==
            curl_multi_perform(multi_handle, &still_running));
      break;
    }
  }

  curl_multi_cleanup(multi_handle);

  curl_easy_cleanup(http_handle);

  return 0;
}
Example #15
0
File: lib504.c Project: VoxOx/VoxOx
/*
 * Source code in here hugely as reported in bug report 651464 by
 * Christopher R. Palmer.
 *
 * Use multi interface to get document over proxy with bad port number.
 * This caused the interface to "hang" in libcurl 7.10.2.
 */
int test(char *URL)
{
  CURL *c;
  int ret=0;
  CURLM *m;
  fd_set rd, wr, exc;
  CURLMcode res;
  char done = FALSE;
  int running;
  int max_fd;
  int rc;
  struct timeval ml_start;
  struct timeval mp_start;
  char ml_timedout = FALSE;
  char mp_timedout = FALSE;

  if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    fprintf(stderr, "curl_global_init() failed\n");
    return TEST_ERR_MAJOR_BAD;
  }

  if ((c = curl_easy_init()) == NULL) {
    fprintf(stderr, "curl_easy_init() failed\n");
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  /* the point here being that there must not run anything on the given
     proxy port */
  curl_easy_setopt(c, CURLOPT_PROXY, arg2);
  curl_easy_setopt(c, CURLOPT_URL, URL);
  curl_easy_setopt(c, CURLOPT_VERBOSE, 1);

  if ((m = curl_multi_init()) == NULL) {
    fprintf(stderr, "curl_multi_init() failed\n");
    curl_easy_cleanup(c);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  if ((res = curl_multi_add_handle(m, c)) != CURLM_OK) {
    fprintf(stderr, "curl_multi_add_handle() failed, "
            "with code %d\n", res);
    curl_multi_cleanup(m);
    curl_easy_cleanup(c);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  ml_timedout = FALSE;
  ml_start = curlx_tvnow();

  while (!done) {
    struct timeval interval;

    interval.tv_sec = 1;
    interval.tv_usec = 0;

    if (curlx_tvdiff(curlx_tvnow(), ml_start) > 
        MAIN_LOOP_HANG_TIMEOUT) {
      ml_timedout = TRUE;
      break;
    }
    mp_timedout = FALSE;
    mp_start = curlx_tvnow();

    fprintf(stderr, "curl_multi_perform()\n");

    res = CURLM_CALL_MULTI_PERFORM;

    while (res == CURLM_CALL_MULTI_PERFORM) {
      res = curl_multi_perform(m, &running);
      if (curlx_tvdiff(curlx_tvnow(), mp_start) > 
          MULTI_PERFORM_HANG_TIMEOUT) {
        mp_timedout = TRUE;
        break;
      }
    }
    if (mp_timedout)
      break;

    if(!running) {
      /* This is where this code is expected to reach */
      int numleft;
      CURLMsg *msg = curl_multi_info_read(m, &numleft);
      fprintf(stderr, "Expected: not running\n");
      if(msg && !numleft)
        ret = 100; /* this is where we should be */
      else
        ret = 99; /* not correct */
      break;
    }
    fprintf(stderr, "running == %d, res == %d\n", running, res);

    if (res != CURLM_OK) {
      ret = 2;
      break;
    }

    FD_ZERO(&rd);
    FD_ZERO(&wr);
    FD_ZERO(&exc);
    max_fd = 0;

    fprintf(stderr, "curl_multi_fdset()\n");
    if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
      fprintf(stderr, "unexpected failured of fdset.\n");
      ret = 3;
      break;
    }
    rc = select_test(max_fd+1, &rd, &wr, &exc, &interval);
    fprintf(stderr, "select returned %d\n", rc);
  }

  if (ml_timedout || mp_timedout) {
    if (ml_timedout) fprintf(stderr, "ml_timedout\n");
    if (mp_timedout) fprintf(stderr, "mp_timedout\n");
    fprintf(stderr, "ABORTING TEST, since it seems "
            "that it would have run forever.\n");
    ret = TEST_ERR_RUNS_FOREVER;
  }

  curl_multi_remove_handle(m, c);
  curl_easy_cleanup(c);
  curl_multi_cleanup(m);
  curl_global_cleanup();

  return ret;
}
Example #16
0
static int
testExternalGet ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  int max;
  int running;
  time_t start;
  struct timeval tv;
  int i;

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_NO_FLAG /* | MHD_USE_DEBUG */ ,
                        11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
  if (d == NULL)
    return 256;
  multi = curl_multi_init ();
  if (multi == NULL)
    {
      MHD_stop_daemon (d);
      return 512;
    }
  zzuf_socat_start ();
  for (i = 0; i < LOOP_COUNT; i++)
    {
      fprintf (stderr, ".");
      c = curl_easy_init ();
      curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11081/hello_world");
      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
      curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
      curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
      curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
      curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT);
      curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT);
      // NOTE: use of CONNECTTIMEOUT without also
      //   setting NOSIGNAL results in really weird
      //   crashes on my system!
      curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
      mret = curl_multi_add_handle (multi, c);
      if (mret != CURLM_OK)
        {
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          zzuf_socat_stop ();
          MHD_stop_daemon (d);
          return 1024;
        }
      start = time (NULL);
      while ((time (NULL) - start < 5) && (c != NULL))
        {
          max = 0;
          FD_ZERO (&rs);
          FD_ZERO (&ws);
          FD_ZERO (&es);
          curl_multi_perform (multi, &running);
          mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
          if (mret != CURLM_OK)
            {
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              zzuf_socat_stop ();
              MHD_stop_daemon (d);
              return 2048;
            }
          if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
            {
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              zzuf_socat_stop ();
              MHD_stop_daemon (d);
              return 4096;
            }
          tv.tv_sec = 0;
          tv.tv_usec = 1000;
          select (max + 1, &rs, &ws, &es, &tv);
          curl_multi_perform (multi, &running);
          if (running == 0)
            {
              curl_multi_info_read (multi, &running);
              curl_multi_remove_handle (multi, c);
              curl_easy_cleanup (c);
              c = NULL;
            }
          MHD_run (d);
        }
      if (c != NULL)
        {
          curl_multi_remove_handle (multi, c);
          curl_easy_cleanup (c);
        }
    }
  fprintf (stderr, "\n");
  curl_multi_cleanup (multi);
  zzuf_socat_stop ();
  MHD_stop_daemon (d);
  return 0;
}
Example #17
0
File: lib526.c Project: Aviio/curl
int test(char *URL)
{
  int res = 0;
  CURL *curl[NUM_HANDLES];
  int running;
  char done=FALSE;
  CURLM *m = NULL;
  int current=0;
  int i, j;
  struct timeval ml_start;
  struct timeval mp_start;
  char ml_timedout = FALSE;
  char mp_timedout = FALSE;

  if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    fprintf(stderr, "curl_global_init() failed\n");
    return TEST_ERR_MAJOR_BAD;
  }

  /* get NUM_HANDLES easy handles */
  for(i=0; i < NUM_HANDLES; i++) {
    curl[i] = curl_easy_init();
    if(!curl[i]) {
      fprintf(stderr, "curl_easy_init() failed "
              "on handle #%d\n", i);
      for (j=i-1; j >= 0; j--) {
        curl_easy_cleanup(curl[j]);
      }
      curl_global_cleanup();
      return TEST_ERR_MAJOR_BAD + i;
    }
    res = curl_easy_setopt(curl[i], CURLOPT_URL, URL);
    if(res) {
      fprintf(stderr, "curl_easy_setopt() failed "
              "on handle #%d\n", i);
      for (j=i; j >= 0; j--) {
        curl_easy_cleanup(curl[j]);
      }
      curl_global_cleanup();
      return TEST_ERR_MAJOR_BAD + i;
    }

    /* go verbose */
    res = curl_easy_setopt(curl[i], CURLOPT_VERBOSE, 1L);
    if(res) {
      fprintf(stderr, "curl_easy_setopt() failed "
              "on handle #%d\n", i);
      for (j=i; j >= 0; j--) {
        curl_easy_cleanup(curl[j]);
      }
      curl_global_cleanup();
      return TEST_ERR_MAJOR_BAD + i;
    }
  }

  if ((m = curl_multi_init()) == NULL) {
    fprintf(stderr, "curl_multi_init() failed\n");
    for(i=0; i < NUM_HANDLES; i++) {
      curl_easy_cleanup(curl[i]);
    }
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  if ((res = (int)curl_multi_add_handle(m, curl[current])) != CURLM_OK) {
    fprintf(stderr, "curl_multi_add_handle() failed, "
            "with code %d\n", res);
    curl_multi_cleanup(m);
    for(i=0; i < NUM_HANDLES; i++) {
      curl_easy_cleanup(curl[i]);
    }
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  ml_timedout = FALSE;
  ml_start = tutil_tvnow();

  fprintf(stderr, "Start at URL 0\n");

  while (!done) {
    fd_set rd, wr, exc;
    int max_fd;
    struct timeval interval;

    interval.tv_sec = 1;
    interval.tv_usec = 0;

    if (tutil_tvdiff(tutil_tvnow(), ml_start) >
        MAIN_LOOP_HANG_TIMEOUT) {
      ml_timedout = TRUE;
      break;
    }
    mp_timedout = FALSE;
    mp_start = tutil_tvnow();

    res = (int)curl_multi_perform(m, &running);
    if (tutil_tvdiff(tutil_tvnow(), mp_start) >
        MULTI_PERFORM_HANG_TIMEOUT) {
      mp_timedout = TRUE;
      break;
    }
    if (running <= 0) {
#ifdef LIB527
      /* NOTE: this code does not remove the handle from the multi handle
         here, which would be the nice, sane and documented way of working.
         This however tests that the API survives this abuse gracefully. */
      curl_easy_cleanup(curl[current]);
#endif
      if(++current < NUM_HANDLES) {
        fprintf(stderr, "Advancing to URL %d\n", current);
#ifdef LIB532
        /* first remove the only handle we use */
        curl_multi_remove_handle(m, curl[0]);

        /* make us re-use the same handle all the time, and try resetting
           the handle first too */
        curl_easy_reset(curl[0]);
        test_setopt(curl[0], CURLOPT_URL, URL);
        test_setopt(curl[0], CURLOPT_VERBOSE, 1L);

        /* re-add it */
        res = (int)curl_multi_add_handle(m, curl[0]);
#else
        res = (int)curl_multi_add_handle(m, curl[current]);
#endif
        if(res) {
          fprintf(stderr, "add handle failed: %d.\n", res);
          res = 243;
          break;
        }
      }
      else {
        done = TRUE; /* bail out */
        break;
      }
    }

    if (res != CURLM_OK) {
      fprintf(stderr, "not okay???\n");
      break;
    }

    FD_ZERO(&rd);
    FD_ZERO(&wr);
    FD_ZERO(&exc);
    max_fd = 0;

    if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
      fprintf(stderr, "unexpected failured of fdset.\n");
      res = 189;
      break;
    }

    if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
      fprintf(stderr, "bad select??\n");
      res = 195;
      break;
    }
  }

  if (ml_timedout || mp_timedout) {
    if (ml_timedout) fprintf(stderr, "ml_timedout\n");
    if (mp_timedout) fprintf(stderr, "mp_timedout\n");
    fprintf(stderr, "ABORTING TEST, since it seems "
            "that it would have run forever.\n");
    res = TEST_ERR_RUNS_FOREVER;
  }

#ifdef LIB532
test_cleanup:
#endif

#ifndef LIB527
  /* get NUM_HANDLES easy handles */
  for(i=0; i < NUM_HANDLES; i++) {
#ifdef LIB526
    if(m)
      curl_multi_remove_handle(m, curl[i]);
#endif
    curl_easy_cleanup(curl[i]);
  }
#endif
  if(m)
    curl_multi_cleanup(m);

  curl_global_cleanup();
  return res;
}
Example #18
0
File: lib525.c Project: Aviio/curl
int test(char *URL)
{
  int res = 0;
  CURL *curl;
  FILE *hd_src ;
  int hd ;
  int error;
  struct_stat file_info;
  int running;
  char done=FALSE;
  CURLM *m = NULL;
  struct timeval ml_start;
  struct timeval mp_start;
  char ml_timedout = FALSE;
  char mp_timedout = FALSE;

  if (!libtest_arg2) {
    fprintf(stderr, "Usage: lib525 [url] [uploadfile]\n");
    return -1;
  }

  hd_src = fopen(libtest_arg2, "rb");
  if(NULL == hd_src) {
    error = ERRNO;
    fprintf(stderr, "fopen() failed with error: %d %s\n",
            error, strerror(error));
    fprintf(stderr, "Error opening file: %s\n", libtest_arg2);
    return TEST_ERR_MAJOR_BAD;
  }

  /* get the file size of the local file */
  hd = fstat(fileno(hd_src), &file_info);
  if(hd == -1) {
    /* can't open file, bail out */
    error = ERRNO;
    fprintf(stderr, "fstat() failed with error: %d %s\n",
            error, strerror(error));
    fprintf(stderr, "ERROR: cannot open file %s\n", libtest_arg2);
    fclose(hd_src);
    return -1;
  }

  if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    fprintf(stderr, "curl_global_init() failed\n");
    fclose(hd_src);
    return TEST_ERR_MAJOR_BAD;
  }

  if ((curl = curl_easy_init()) == NULL) {
    fprintf(stderr, "curl_easy_init() failed\n");
    fclose(hd_src);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  /* enable uploading */
  test_setopt(curl, CURLOPT_UPLOAD, 1L);

  /* specify target */
  test_setopt(curl,CURLOPT_URL, URL);

  /* go verbose */
  test_setopt(curl, CURLOPT_VERBOSE, 1L);

  /* use active FTP */
  test_setopt(curl, CURLOPT_FTPPORT, "-");

  /* now specify which file to upload */
  test_setopt(curl, CURLOPT_READDATA, hd_src);

  /* NOTE: if you want this code to work on Windows with libcurl as a DLL, you
     MUST also provide a read callback with CURLOPT_READFUNCTION. Failing to
     do so will give you a crash since a DLL may not use the variable's memory
     when passed in to it from an app like this. */

  /* Set the size of the file to upload (optional).  If you give a *_LARGE
     option you MUST make sure that the type of the passed-in argument is a
     curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
     make sure that to pass in a type 'long' argument. */
  test_setopt(curl, CURLOPT_INFILESIZE_LARGE,
                   (curl_off_t)file_info.st_size);

  if ((m = curl_multi_init()) == NULL) {
    fprintf(stderr, "curl_multi_init() failed\n");
    curl_easy_cleanup(curl);
    curl_global_cleanup();
    fclose(hd_src);
    return TEST_ERR_MAJOR_BAD;
  }

  if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
    fprintf(stderr, "curl_multi_add_handle() failed, "
            "with code %d\n", res);
    curl_multi_cleanup(m);
    curl_easy_cleanup(curl);
    curl_global_cleanup();
    fclose(hd_src);
    return TEST_ERR_MAJOR_BAD;
  }

  ml_timedout = FALSE;
  ml_start = tutil_tvnow();

  while (!done) {
    fd_set rd, wr, exc;
    int max_fd;
    struct timeval interval;

    interval.tv_sec = 1;
    interval.tv_usec = 0;

    if (tutil_tvdiff(tutil_tvnow(), ml_start) >
        MAIN_LOOP_HANG_TIMEOUT) {
      ml_timedout = TRUE;
      break;
    }
    mp_timedout = FALSE;
    mp_start = tutil_tvnow();

    res = (int)curl_multi_perform(m, &running);
    if (tutil_tvdiff(tutil_tvnow(), mp_start) >
        MULTI_PERFORM_HANG_TIMEOUT) {
      mp_timedout = TRUE;
      break;
    }
    if (running <= 0) {
      done = TRUE;
      break;
    }

    if (res != CURLM_OK) {
      fprintf(stderr, "not okay???\n");
      break;
    }

    FD_ZERO(&rd);
    FD_ZERO(&wr);
    FD_ZERO(&exc);
    max_fd = 0;

    if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
      fprintf(stderr, "unexpected failured of fdset.\n");
      res = 189;
      break;
    }

    if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
      fprintf(stderr, "bad select??\n");
      res = 195;
      break;
    }

    res = CURLM_CALL_MULTI_PERFORM;
  }

  if (ml_timedout || mp_timedout) {
    if (ml_timedout) fprintf(stderr, "ml_timedout\n");
    if (mp_timedout) fprintf(stderr, "mp_timedout\n");
    fprintf(stderr, "ABORTING TEST, since it seems "
            "that it would have run forever.\n");
    res = TEST_ERR_RUNS_FOREVER;
  }

test_cleanup:

#ifdef LIB529
  /* test 529 */
  if(m) {
    curl_multi_remove_handle(m, curl);
    curl_multi_cleanup(m);
  }
  curl_easy_cleanup(curl);
#else
  /* test 525 */
  if(m)
    curl_multi_remove_handle(m, curl);
  curl_easy_cleanup(curl);
  if(m)
    curl_multi_cleanup(m);
#endif

  fclose(hd_src); /* close the local file */

  curl_global_cleanup();
  return res;
}
Example #19
0
/*
 * 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();

  /* set the options (I left out a few, you'll get the point anyway) */
  curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/");

  curl_easy_setopt(http_handle, CURLOPT_DEBUGFUNCTION, my_trace);
  curl_easy_setopt(http_handle, CURLOPT_VERBOSE, 1L);

  /* init a multi stack */
  multi_handle = curl_multi_init();

  /* add the individual transfers */
  curl_multi_add_handle(multi_handle, http_handle);

  /* we start some action by calling perform right away */
  curl_multi_perform(multi_handle, &still_running);

  do {
    struct timeval timeout;
    int rc; /* select() return code */
    CURLMcode mc; /* curl_multi_fdset() 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 */
    mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

    if(mc != CURLM_OK)
    {
      fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
      break;
    }

    /* On success the value of maxfd is guaranteed to be >= -1. We call
       select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
       no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
       to sleep 100ms, which is the minimum suggested value in the
       curl_multi_fdset() doc. */

    if(maxfd == -1) {
#ifdef _WIN32
      Sleep(100);
      rc = 0;
#else
      /* Portable sleep for platforms other than Windows. */
      struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
      rc = select(0, NULL, NULL, NULL, &wait);
#endif
    }
    else {
      /* Note that on some platforms 'timeout' may be modified by select().
         If you need access to the original value save a copy beforehand. */
      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 */
      curl_multi_perform(multi_handle, &still_running);
      break;
    }
  } while(still_running);

  curl_multi_cleanup(multi_handle);

  curl_easy_cleanup(http_handle);

  return 0;
}
Example #20
0
int test( char *URL ) {
	CURLM* multi;
	sslctxparm p;

	int i = 0;
	CURLMsg *msg;

	if ( arg2 ) {
		portnum = atoi( arg2 );
	}

	curl_global_init( CURL_GLOBAL_ALL );

	p.curl = curl_easy_init();

	p.accessinfoURL = (unsigned char *) strdup( URL );
	p.accesstype = OBJ_obj2nid( OBJ_txt2obj( "AD_DVCS",0 ) ) ;

	curl_easy_setopt( p.curl, CURLOPT_URL, p.accessinfoURL );

	curl_easy_setopt( p.curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun )  ;
	curl_easy_setopt( p.curl, CURLOPT_SSL_CTX_DATA, &p );

	curl_easy_setopt( p.curl, CURLOPT_SSL_VERIFYPEER, FALSE );
	curl_easy_setopt( p.curl, CURLOPT_SSL_VERIFYHOST, 1 );

	fprintf( stderr, "Going to perform %s\n", (char *)p.accessinfoURL );

	{
		CURLMcode res;
		int running;
		char done = FALSE;

		multi = curl_multi_init();

		res = curl_multi_add_handle( multi, p.curl );

		while ( !done ) {
			fd_set rd, wr, exc;
			int max_fd;
			struct timeval interval;

			interval.tv_sec = 1;
			interval.tv_usec = 0;

			while ( res == CURLM_CALL_MULTI_PERFORM ) {
				res = curl_multi_perform( multi, &running );
				fprintf( stderr, "running=%d res=%d\n",running,res );
				if ( running <= 0 ) {
					done = TRUE;
					break;
				}
			}
			if ( done ) {
				break;
			}

			if ( res != CURLM_OK ) {
				fprintf( stderr, "not okay???\n" );
				i = 80;
				break;
			}

			FD_ZERO( &rd );
			FD_ZERO( &wr );
			FD_ZERO( &exc );
			max_fd = 0;

			if ( curl_multi_fdset( multi, &rd, &wr, &exc, &max_fd ) != CURLM_OK ) {
				fprintf( stderr, "unexpected failured of fdset.\n" );
				i = 89;
				break;
			}

			if ( select( max_fd + 1, &rd, &wr, &exc, &interval ) == -1 ) {
				fprintf( stderr, "bad select??\n" );
				i = 95;
				break;
			}

			res = CURLM_CALL_MULTI_PERFORM;
		}
		msg = curl_multi_info_read( multi, &running );
		/* this should now contain a result code from the easy handle, get it */
		if ( msg ) {
			i = msg->data.result;
		}
	}

	fprintf( stderr, "all done\n" );

	curl_multi_remove_handle( multi, p.curl );
	curl_easy_cleanup( p.curl );
	curl_multi_cleanup( multi );

	curl_global_cleanup();
	free( p.accessinfoURL );

	return i;
}
Example #21
0
static int
testExternalGet ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  MHD_socket maxsock;
#ifdef MHD_WINSOCK_SOCKETS
  int maxposixs; /* Max socket number unused on W32 */
#else  /* MHD_POSIX_SOCKETS */
#define maxposixs maxsock
#endif /* MHD_POSIX_SOCKETS */
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;
  int i;
  MHD_socket fd;

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_DEBUG,
                        11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
  if (d == NULL)
    return 256;
  c = setupCURL(&cbc);

  multi = curl_multi_init ();
  if (multi == NULL)
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 512;
    }
  mret = curl_multi_add_handle (multi, c);
  if (mret != CURLM_OK)
    {
      curl_multi_cleanup (multi);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 1024;
    }

  for (i = 0; i < 2; i++) {
    start = time (NULL);
    while ((time (NULL) - start < 5) && (multi != NULL))
      {
        maxsock = MHD_INVALID_SOCKET;
        maxposixs = -1;
        FD_ZERO (&rs);
        FD_ZERO (&ws);
        FD_ZERO (&es);
        curl_multi_perform (multi, &running);
        mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
        if (mret != CURLM_OK)
          {
            curl_multi_remove_handle (multi, c);
            curl_multi_cleanup (multi);
            curl_easy_cleanup (c);
            MHD_stop_daemon (d);
            return 2048;
          }
        if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
          {
            curl_multi_remove_handle (multi, c);
            curl_multi_cleanup (multi);
            curl_easy_cleanup (c);
            MHD_stop_daemon (d);
            return 4096;
          }
        tv.tv_sec = 0;
        tv.tv_usec = 1000;
        select (maxposixs + 1, &rs, &ws, &es, &tv);
        curl_multi_perform (multi, &running);
        if (running == 0)
          {
            msg = curl_multi_info_read (multi, &running);
            if (msg == NULL)
              break;
            if (msg->msg == CURLMSG_DONE)
              {
                if (i == 0 && msg->data.result != CURLE_OK)
                  printf ("%s failed at %s:%d: `%s'\n",
                          "curl_multi_perform",
                          __FILE__,
                          __LINE__, curl_easy_strerror (msg->data.result));
                else if (i == 1 && msg->data.result == CURLE_OK)
                  printf ("%s should have failed at %s:%d\n",
                          "curl_multi_perform",
                          __FILE__,
                          __LINE__);
                curl_multi_remove_handle (multi, c);
                curl_multi_cleanup (multi);
                curl_easy_cleanup (c);
                c = NULL;
                multi = NULL;
              }
          }
        MHD_run (d);
      }

      if (i == 0) {
        /* quiesce the daemon on the 1st iteration, so the 2nd should fail */
        fd = MHD_quiesce_daemon(d);
        if (MHD_INVALID_SOCKET == fd)
          {
            fprintf (stderr,
                     "MHD_quiesce_daemon failed.\n");
            curl_multi_remove_handle (multi, c);
            curl_multi_cleanup (multi);
            curl_easy_cleanup (c);
            MHD_stop_daemon (d);
            return 2;
          }
        c = setupCURL (&cbc);
        multi = curl_multi_init ();
        mret = curl_multi_add_handle (multi, c);
        if (mret != CURLM_OK)
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 32768;
        }
      }
    }
  if (multi != NULL)
    {
      curl_multi_remove_handle (multi, c);
      curl_easy_cleanup (c);
      curl_multi_cleanup (multi);
    }
  MHD_stop_daemon (d);
  MHD_socket_close_ (fd);
  if (cbc.pos != strlen ("/hello_world"))
    return 8192;
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 16384;
  return 0;
}
Example #22
0
int test(char *URL)
{
  CURLM *multi;
  CURL *easy;
  int res = 0;

  if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    fprintf(stderr, "curl_global_init() failed\n");
    return TEST_ERR_MAJOR_BAD;
  }

  if ((multi = curl_multi_init()) == NULL) {
    fprintf(stderr, "curl_multi_init() failed\n");
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  if ((easy = curl_easy_init()) == NULL) {
    fprintf(stderr, "curl_easy_init() failed\n");
    curl_multi_cleanup(multi);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  curl_multi_setopt(multi, CURLMOPT_PIPELINING, 1L);

  test_setopt(easy, CURLOPT_WRITEFUNCTION, fwrite);
  test_setopt(easy, CURLOPT_FAILONERROR, 1L);
  test_setopt(easy, CURLOPT_URL, URL);

  if (curl_multi_add_handle(multi, easy) != CURLM_OK) {
    printf("curl_multi_add_handle() failed\n");
    res = TEST_ERR_MAJOR_BAD;
  } else {
    if (perform(multi) != CURLM_OK)
      printf("retrieve 1 failed\n");

    curl_multi_remove_handle(multi, easy);
  }
  curl_easy_reset(easy);

  test_setopt(easy, CURLOPT_FAILONERROR, 1L);
  test_setopt(easy, CURLOPT_URL, libtest_arg2);

  if (curl_multi_add_handle(multi, easy) != CURLM_OK) {
    printf("curl_multi_add_handle() 2 failed\n");
    res = TEST_ERR_MAJOR_BAD;
  } else {
    if (perform(multi) != CURLM_OK)
      printf("retrieve 2 failed\n");

    curl_multi_remove_handle(multi, easy);
  }

test_cleanup:

  curl_easy_cleanup(easy);
  curl_multi_cleanup(multi);
  curl_global_cleanup();

  printf("Finished!\n");

  return res;
}
Example #23
0
File: lib575.c Project: dims/curl
int test(char *URL)
{
    CURLMcode m;
    CURL *handle = NULL, *duphandle;
    CURLM *mhandle = NULL;
    int res = 0;
    int still_running = 0;

    if(curl_global_init(CURL_GLOBAL_ALL)) {
        fprintf(stderr, "curl_global_init() failed\n");
        goto test_cleanup;
    }

    handle = curl_easy_init();
    if(!handle) {
        res = CURLE_OUT_OF_MEMORY;
        goto test_cleanup;
    }

    test_setopt(handle, CURLOPT_URL, URL);
    test_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
    test_setopt(handle, CURLOPT_VERBOSE, 1L);

    res = curl_easy_perform(handle);
    if(res)
        goto test_cleanup;

    res = curl_easy_perform(handle);
    if(res)
        goto test_cleanup;

    duphandle = curl_easy_duphandle(handle);
    if(!duphandle)
        goto test_cleanup;
    curl_easy_cleanup(handle);
    handle = duphandle;

    mhandle = curl_multi_init();
    if(!mhandle) {
        fprintf(stderr, "curl_multi_init() failed\n");
        goto test_cleanup;
    }

    curl_multi_add_handle(mhandle, handle);

    curl_multi_perform(mhandle, &still_running);

    while(still_running) {
        static struct timeval timeout = { /* 100 ms */
            0, 100000L
        };
        int rc;
        fd_set fdread;
        fd_set fdwrite;
        fd_set fdexcep;
        int max_fdset = -1;
        FD_ZERO(&fdread);
        FD_ZERO(&fdwrite);
        FD_ZERO(&fdexcep);

        m = curl_multi_fdset(mhandle, &fdread, &fdwrite, &fdexcep, &max_fdset);
        if(m != CURLM_OK) {
            fprintf(stderr, "curl_multi_fdset() error\n");
            goto test_cleanup;
        }
        /* We call select(max_fdset + 1, ...), specially in case of (maxfd == -1),
         * we call select(0, ...), which is basically equal to sleep. */
        rc = select(max_fdset + 1, &fdread, &fdwrite, &fdexcep, &timeout);
        if(rc == -1) {
            fprintf(stderr, "select() error\n");
            goto test_cleanup;
        }
        else {
            curl_multi_perform(mhandle, &still_running);
        }
    }

test_cleanup:
    if(mhandle)
        curl_multi_cleanup(mhandle);
    if(handle)
        curl_easy_cleanup(handle);
    curl_global_cleanup();
    return res;
}
Example #24
0
int test(char *URL)
{
  CURLM* multi;
  sslctxparm p;
  CURLMcode res;
  int running;
  char done = FALSE;
  int i = 0;
  CURLMsg *msg;

  struct timeval ml_start;
  struct timeval mp_start;
  char ml_timedout = FALSE;
  char mp_timedout = FALSE;

  if(libtest_arg2) {
    portnum = atoi(libtest_arg2);
  }

  if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    fprintf(stderr, "curl_global_init() failed\n");
    return TEST_ERR_MAJOR_BAD;
  }

  if ((p.curl = curl_easy_init()) == NULL) {
    fprintf(stderr, "curl_easy_init() failed\n");
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  p.accessinfoURL = (unsigned char *) strdup(URL);
  p.accesstype = OBJ_obj2nid(OBJ_txt2obj("AD_DVCS",0)) ;

  curl_easy_setopt(p.curl, CURLOPT_URL, p.accessinfoURL);

  curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun)  ;
  curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_DATA, &p);

  curl_easy_setopt(p.curl, CURLOPT_SSL_VERIFYPEER, FALSE);
  curl_easy_setopt(p.curl, CURLOPT_SSL_VERIFYHOST, 1);

  if ((multi = curl_multi_init()) == NULL) {
    fprintf(stderr, "curl_multi_init() failed\n");
    curl_easy_cleanup(p.curl);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  if ((res = curl_multi_add_handle(multi, p.curl)) != CURLM_OK) {
    fprintf(stderr, "curl_multi_add_handle() failed, "
            "with code %d\n", res);
    curl_multi_cleanup(multi);
    curl_easy_cleanup(p.curl);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  fprintf(stderr, "Going to perform %s\n", (char *)p.accessinfoURL);

  ml_timedout = FALSE;
  ml_start = tutil_tvnow();

  while (!done) {
    fd_set rd, wr, exc;
    int max_fd;
    struct timeval interval;

    interval.tv_sec = 1;
    interval.tv_usec = 0;

    if (tutil_tvdiff(tutil_tvnow(), ml_start) >
        MAIN_LOOP_HANG_TIMEOUT) {
      ml_timedout = TRUE;
      break;
    }
    mp_timedout = FALSE;
    mp_start = tutil_tvnow();

    while (res == CURLM_CALL_MULTI_PERFORM) {
      res = curl_multi_perform(multi, &running);
      if (tutil_tvdiff(tutil_tvnow(), mp_start) >
          MULTI_PERFORM_HANG_TIMEOUT) {
        mp_timedout = TRUE;
        break;
      }
      fprintf(stderr, "running=%d res=%d\n",running,res);
      if (running <= 0) {
        done = TRUE;
        break;
      }
    }
    if (mp_timedout || done)
      break;

    if (res != CURLM_OK) {
      fprintf(stderr, "not okay???\n");
      i = 80;
      break;
    }

    FD_ZERO(&rd);
    FD_ZERO(&wr);
    FD_ZERO(&exc);
    max_fd = 0;

    if (curl_multi_fdset(multi, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
      fprintf(stderr, "unexpected failured of fdset.\n");
      i = 89;
      break;
    }

    if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
      fprintf(stderr, "bad select??\n");
      i =95;
      break;
    }

    res = CURLM_CALL_MULTI_PERFORM;
  }

  if (ml_timedout || mp_timedout) {
    if (ml_timedout) fprintf(stderr, "ml_timedout\n");
    if (mp_timedout) fprintf(stderr, "mp_timedout\n");
    fprintf(stderr, "ABORTING TEST, since it seems "
            "that it would have run forever.\n");
    i = TEST_ERR_RUNS_FOREVER;
  }
  else {
    msg = curl_multi_info_read(multi, &running);
    /* this should now contain a result code from the easy handle, get it */
    if(msg)
      i = msg->data.result;
    fprintf(stderr, "all done\n");
  }

  curl_multi_remove_handle(multi, p.curl);
  curl_easy_cleanup(p.curl);
  curl_multi_cleanup(multi);

  curl_global_cleanup();
  free(p.accessinfoURL);

  return i;
}
Example #25
0
File: lib564.c Project: dims/curl
int test(char *URL)
{
  int res = 0;
  CURL *curl;
  int running;
  char done=FALSE;
  CURLM *m = NULL;
  struct timeval ml_start;
  struct timeval mp_start;
  char ml_timedout = FALSE;
  char mp_timedout = FALSE;

  if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    fprintf(stderr, "curl_global_init() failed\n");
    return TEST_ERR_MAJOR_BAD;
  }

  if ((curl = curl_easy_init()) == NULL) {
    fprintf(stderr, "curl_easy_init() failed\n");
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  test_setopt(curl, CURLOPT_URL, URL);
  test_setopt(curl, CURLOPT_VERBOSE, 1);
  test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
  test_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);

  if ((m = curl_multi_init()) == NULL) {
    fprintf(stderr, "curl_multi_init() failed\n");
    curl_easy_cleanup(curl);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
    fprintf(stderr, "curl_multi_add_handle() failed, "
            "with code %d\n", res);
    curl_multi_cleanup(m);
    curl_easy_cleanup(curl);
    curl_global_cleanup();
    return TEST_ERR_MAJOR_BAD;
  }

  ml_timedout = FALSE;
  ml_start = tutil_tvnow();

  fprintf(stderr, "Start at URL 0\n");

  while (!done) {
    fd_set rd, wr, exc;
    int max_fd;
    struct timeval interval;

    interval.tv_sec = 1;
    interval.tv_usec = 0;

    if (tutil_tvdiff(tutil_tvnow(), ml_start) >
        MAIN_LOOP_HANG_TIMEOUT) {
      ml_timedout = TRUE;
      break;
    }
    mp_timedout = FALSE;
    mp_start = tutil_tvnow();

    res = (int)curl_multi_perform(m, &running);
    if (tutil_tvdiff(tutil_tvnow(), mp_start) >
        MULTI_PERFORM_HANG_TIMEOUT) {
      mp_timedout = TRUE;
      break;
    }
    if (running <= 0) {
      done = TRUE; /* bail out */
      break;
    }

    if (res != CURLM_OK) {
      fprintf(stderr, "not okay???\n");
      break;
    }

    FD_ZERO(&rd);
    FD_ZERO(&wr);
    FD_ZERO(&exc);
    max_fd = 0;

    if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
      fprintf(stderr, "unexpected failured of fdset.\n");
      res = 189;
      break;
    }

    if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
      fprintf(stderr, "bad select??\n");
      res = 195;
      break;
    }
  }

  if (ml_timedout || mp_timedout) {
    if (ml_timedout) fprintf(stderr, "ml_timedout\n");
    if (mp_timedout) fprintf(stderr, "mp_timedout\n");
    fprintf(stderr, "ABORTING TEST, since it seems "
            "that it would have run forever.\n");
    res = TEST_ERR_RUNS_FOREVER;
  }

test_cleanup:

  curl_easy_cleanup(curl);
  if(m)
    curl_multi_cleanup(m);
  curl_global_cleanup();

  return res;
}
/*
 * Simply download two HTTP files!
 */
int main(int argc, char **argv)
{
  CURL *http_handle;
  CURL *http_handle2;
  CURLM *multi_handle;

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

  http_handle = curl_easy_init();
  http_handle2 = curl_easy_init();

  /* set options */
  curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.haxx.se/");

  /* set options */
  curl_easy_setopt(http_handle2, CURLOPT_URL, "http://localhost/");

  /* init a multi stack */
  multi_handle = curl_multi_init();

  /* add the individual transfers */
  curl_multi_add_handle(multi_handle, http_handle);
  curl_multi_add_handle(multi_handle, http_handle2);

  /* we start some action by calling perform right away */
  while(CURLM_CALL_MULTI_PERFORM ==
        curl_multi_perform(multi_handle, &still_running));

  while(still_running) {
    struct timeval timeout;
    int rc; /* select() return code */

    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int maxfd;

    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;

    /* get file descriptors from the transfers */
    curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

    /* In a real-world program you OF COURSE check the return code of the
       function calls, *and* you make sure that maxfd is bigger than -1 so
       that the call to select() below makes sense! */

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

    switch(rc) {
    case -1:
      /* select error */
      break;
    case 0:
    default:
      /* timeout or readable/writable sockets */
      while(CURLM_CALL_MULTI_PERFORM ==
            curl_multi_perform(multi_handle, &still_running));
      break;
    }
  }

  curl_multi_cleanup(multi_handle);

  curl_easy_cleanup(http_handle);
  curl_easy_cleanup(http_handle2);

  return 0;
}
Example #27
0
static int
testExternalPut ()
{
  struct MHD_Daemon *d;
  CURL *c;
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  MHD_socket maxsock;
#ifdef MHD_WINSOCK_SOCKETS
  int maxposixs; /* Max socket number unused on W32 */
#else  /* MHD_POSIX_SOCKETS */
#define maxposixs maxsock
#endif /* MHD_POSIX_SOCKETS */
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;
  unsigned int pos = 0;
  int done_flag = 0;
  char buf[2048];

  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  multi = NULL;
  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
                        1082,
                        NULL, NULL, &ahc_echo, &done_flag,
                        MHD_OPTION_CONNECTION_MEMORY_LIMIT,
                        (size_t) (PUT_SIZE * 4), MHD_OPTION_END);
  if (d == NULL)
    return 256;
  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
  curl_easy_setopt (c, CURLOPT_READDATA, &pos);
  curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
  curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  if (oneone)
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  else
    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
  // NOTE: use of CONNECTTIMEOUT without also
  //   setting NOSIGNAL results in really weird
  //   crashes on my system!
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);


  multi = curl_multi_init ();
  if (multi == NULL)
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 512;
    }
  mret = curl_multi_add_handle (multi, c);
  if (mret != CURLM_OK)
    {
      curl_multi_cleanup (multi);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 1024;
    }
  start = time (NULL);
  while ((time (NULL) - start < 5) && (multi != NULL))
    {
      maxsock = MHD_INVALID_SOCKET;
      maxposixs = -1;
      FD_ZERO (&rs);
      FD_ZERO (&ws);
      FD_ZERO (&es);
      curl_multi_perform (multi, &running);
      mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
      if (mret != CURLM_OK)
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 2048;
        }
      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 4096;
        }
      tv.tv_sec = 0;
      tv.tv_usec = 1000;
      if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
        {
          if (EINTR != errno)
            abort ();
        }
      curl_multi_perform (multi, &running);
      if (running == 0)
        {
          msg = curl_multi_info_read (multi, &running);
          if (msg == NULL)
            break;
          if (msg->msg == CURLMSG_DONE)
            {
              if (msg->data.result != CURLE_OK)
                printf ("%s failed at %s:%d: `%s'\n",
                        "curl_multi_perform",
                        __FILE__,
                        __LINE__, curl_easy_strerror (msg->data.result));
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              c = NULL;
              multi = NULL;
            }
        }
      MHD_run (d);
    }
  if (multi != NULL)
    {
      curl_multi_remove_handle (multi, c);
      curl_easy_cleanup (c);
      curl_multi_cleanup (multi);
    }
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello_world"))
    {
      fprintf (stderr, "Got invalid response `%.*s'\n", (int)cbc.pos, cbc.buf);
      return 8192;
    }
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 16384;
  return 0;
}
Example #28
0
/***************************************************************************
 * This function is still only for testing purposes. It makes a great way
 * to run the full test suite on the multi interface instead of the easy one.
 ***************************************************************************
 *
 * The *new* curl_easy_perform() is the external interface that performs a
 * transfer previously setup.
 *
 * Wrapper-function that: creates a multi handle, adds the easy handle to it,
 * runs curl_multi_perform() until the transfer is done, then detaches the
 * easy handle, destroys the multi handle and returns the easy handle's return
 * code. This will make everything internally use and assume multi interface.
 */
CURLcode curl_easy_perform(CURL *easy)
{
  CURLM *multi;
  CURLMcode mcode;
  CURLcode code = CURLE_OK;
  int still_running;
  struct timeval timeout;
  int rc;
  CURLMsg *msg;
  fd_set fdread;
  fd_set fdwrite;
  fd_set fdexcep;
  int maxfd;

  if(!easy)
    return CURLE_BAD_FUNCTION_ARGUMENT;

  multi = curl_multi_init();
  if(!multi)
    return CURLE_OUT_OF_MEMORY;

  mcode = curl_multi_add_handle(multi, easy);
  if(mcode) {
    curl_multi_cleanup(multi);
    if(mcode == CURLM_OUT_OF_MEMORY)
      return CURLE_OUT_OF_MEMORY;
    else
      return CURLE_FAILED_INIT;
  }

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

  do {
    while(CURLM_CALL_MULTI_PERFORM ==
          curl_multi_perform(multi, &still_running));

    if(!still_running)
      break;

    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    /* timeout once per second */
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    /* Old deprecated style: get file descriptors from the transfers */
    curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
    rc = Curl_select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

    /* The way is to extract the sockets and wait for them without using
       select. This whole alternative version should probably rather use the
       curl_multi_socket() approach. */

    if(rc == -1)
      /* select error */
      break;

    /* timeout or data to send/receive => loop! */
  } while(still_running);

  msg = curl_multi_info_read(multi, &rc);
  if(msg)
    code = msg->data.result;

  mcode = curl_multi_remove_handle(multi, easy);
  /* what to do if it fails? */

  mcode = curl_multi_cleanup(multi);
  /* what to do if it fails? */

  return code;
}
Example #29
0
int test(char *URL)
{
  CURLM *cm = NULL;
  CURLSH *sh = NULL;
  CURL *ch = NULL;
  int unfinished;

  cm = curl_multi_init();
  if(!cm)
    return 1;
  sh = curl_share_init();
  if(!sh)
    goto cleanup;

  curl_share_setopt(sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
  curl_share_setopt(sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);

  ch = curl_easy_init();
  if(!ch)
    goto cleanup;

  curl_easy_setopt(ch, CURLOPT_SHARE, sh);
  curl_easy_setopt(ch, CURLOPT_URL, URL);
  curl_easy_setopt(ch, CURLOPT_COOKIEFILE, "log/cookies1905");
  curl_easy_setopt(ch, CURLOPT_COOKIEJAR, "log/cookies1905");

  curl_multi_add_handle(cm, ch);

  unfinished = 1;
  while(unfinished) {
    int MAX = 0;
    long max_tout;
    fd_set R, W, E;
    struct timeval timeout;

    FD_ZERO(&R);
    FD_ZERO(&W);
    FD_ZERO(&E);
    curl_multi_perform(cm, &unfinished);

    curl_multi_fdset(cm, &R, &W, &E, &MAX);
    curl_multi_timeout(cm, &max_tout);

    if(max_tout > 0) {
      timeout.tv_sec = max_tout / 1000;
      timeout.tv_usec = (max_tout % 1000) * 1000;
    }
    else {
      timeout.tv_sec = 0;
      timeout.tv_usec = 1000;
    }

    select(MAX + 1, &R, &W, &E, &timeout);
  }

  curl_easy_setopt(ch, CURLOPT_COOKIELIST, "FLUSH");
  curl_easy_setopt(ch, CURLOPT_SHARE, NULL);

  curl_multi_remove_handle(cm, ch);
  cleanup:
  curl_easy_cleanup(ch);
  curl_share_cleanup(sh);
  curl_multi_cleanup(cm);

  return 0;
}
Example #30
0
/* 
  FIXME dont run every time, only if dlqueue is full!!!
 */
int curlFetch(struct url *ptr, int dlnum)
{

  CURLM *cm;
  CURLMsg *msg;
  long L=100;
  unsigned int C=0;
  int M, Q, U = -1;
  fd_set R, W, E;
  struct timeval T;
  CURLMcode	ret;
  qboolean got404=false;

  if (!cls.downloadServer)
	  return 0;

  curl_global_init(CURL_GLOBAL_ALL);

  cm = curl_multi_init();
  
  curl_easy_setopt(cm, CURLMOPT_MAXCONNECTS, (long)MAX);

  for (C = 0; C < dlnum; ++C)
      init(cm, C);
  

  while (U) 
  {
      ret = curl_multi_perform(cm, &U);

      if (U)
	  {
        FD_ZERO(&R);
        FD_ZERO(&W);
        FD_ZERO(&E);

		if (ret != CURLM_OK)
		{
			Com_Printf ("curl_multi_perform error, Aborting HTTP downloads.\n");
			return 1;
		}

      if (curl_multi_fdset(cm, &R, &W, &E, &M)) {
        Com_Printf("E: curl_multi_fdset\n");
        return 1;
      }
      if (L == -1)
        L = 100;

      if (M == -1) {
		  /* obviously we need to sleep a 
		  short while so we DO NOT RUN OUT OF FDs! */
#ifdef WIN32
        Sleep(L);
#else
        sleep(L / 1000);
#endif
      } else {
        T.tv_sec = L/1000;
        T.tv_usec = (L%1000)*1000;
		//T.tv_sec = 5;
        //T.tv_usec = 0;
        if (0 > select(M+1, &R, &W, &E, &T)) {
          Com_Printf("E: select(%i,,,,%li): %i: %s\n",
              M+1, L, errno, strerror(errno));
          return 1;
        }
	  }
      
    }

    while ((msg = curl_multi_info_read(cm, &Q))) {

	  // allow user to use console
	  CL_SendCommand ();

      if (msg->msg == CURLMSG_DONE)
	  {
		long responseCode;
        extern struct MemoryStruct *memPtr;
		char *url;
		double recvsize;
		double totaltime;
		char *localfile;
		char *fullurl;
		int remainingFiles;
		static int finishcnt;
		
        CURL *e = msg->easy_handle;
		curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &responseCode);
        curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
		curl_easy_getinfo(msg->easy_handle, CURLINFO_SIZE_DOWNLOAD, &recvsize);
		curl_easy_getinfo(msg->easy_handle, CURLINFO_TOTAL_TIME, &totaltime);
		curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &localfile);
		curl_easy_getinfo(msg->easy_handle, CURLINFO_EFFECTIVE_URL, &fullurl);

		remainingFiles=0;

		if (responseCode == 404)
		{
			//Com_Printf("[HTTP] %s [404 Not Found] [x remaining files]\n", 
				//localfile, recvsize/1000,recvsize/(1000*totaltime),remainingFiles);

			// dont show 404 error in some cases, prettier console...
			#if HTTP404ERROR
			Com_Printf("[HTTP] %s [404 Not Found]\n", 
				localfile, recvsize/1000,recvsize/(1000*totaltime),remainingFiles);
				got404=true;
				cls.downloadnow=false; // dont download over http again...
			#endif
		}
		else if (responseCode == 200)
		{
			/*
			Com_Printf("[HTTP] %s [%.f kB, %.0f kB/sec] [x remaining files]\n", 
				localfile, recvsize/1000,recvsize/(1000*totaltime),remainingFiles);
			*/
			Com_Printf("[HTTP] %s [%.f kB, %.0f kB/sec]\n", 
				localfile, recvsize/1000,recvsize/(1000*totaltime),remainingFiles);
			binaryWrite(localfile, memPtr->memory, memPtr->size);
		}
		
		finishcnt++;

		if (memPtr && memPtr->memory)
		free(memPtr->memory);

        curl_multi_remove_handle(cm, e);
        curl_easy_cleanup(e);
      }
      else {
        Com_Printf("E: CURLMsg (%d)\n", msg->msg);
		return 1;
      }

      if (C < dlnum) 
	  {
        init(cm, C++);
        U++; 
      }
    }
  }

  curl_multi_cleanup(cm);
  curl_global_cleanup();

  return got404 ? 1:0;  
}