Ejemplo n.º 1
0
static CURL *
createEasy (tr_session * s, struct tr_web * web, struct tr_web_task * task)
{
  bool is_default_value;
  const tr_address * addr;
  CURL * e = task->curl_easy = curl_easy_init ();

  task->timeout_secs = getTimeoutFromURL (task);

  curl_easy_setopt (e, CURLOPT_AUTOREFERER, 1L);
  curl_easy_setopt (e, CURLOPT_ENCODING, "gzip;q=1.0, deflate, identity");
  curl_easy_setopt (e, CURLOPT_FOLLOWLOCATION, 1L);
  curl_easy_setopt (e, CURLOPT_MAXREDIRS, -1L);
  curl_easy_setopt (e, CURLOPT_NOSIGNAL, 1L);
  curl_easy_setopt (e, CURLOPT_PRIVATE, task);
#ifdef USE_LIBCURL_SOCKOPT
  curl_easy_setopt (e, CURLOPT_SOCKOPTFUNCTION, sockoptfunction);
  curl_easy_setopt (e, CURLOPT_SOCKOPTDATA, task);
#endif
  if (web->curl_ssl_verify)
    {
      curl_easy_setopt (e, CURLOPT_CAINFO, web->curl_ca_bundle);
    }
  else
    {
      curl_easy_setopt (e, CURLOPT_SSL_VERIFYHOST, 0L);
      curl_easy_setopt (e, CURLOPT_SSL_VERIFYPEER, 0L);
    }
  curl_easy_setopt (e, CURLOPT_TIMEOUT, task->timeout_secs);
  curl_easy_setopt (e, CURLOPT_URL, task->url);
  curl_easy_setopt (e, CURLOPT_USERAGENT, TR_NAME "/" SHORT_VERSION_STRING);
  curl_easy_setopt (e, CURLOPT_VERBOSE, (long)(web->curl_verbose?1:0));
  curl_easy_setopt (e, CURLOPT_WRITEDATA, task);
  curl_easy_setopt (e, CURLOPT_WRITEFUNCTION, writeFunc);

  if (((addr = tr_sessionGetPublicAddress (s, TR_AF_INET, &is_default_value))) && !is_default_value)
    curl_easy_setopt (e, CURLOPT_INTERFACE, tr_address_to_string (addr));
  else if (((addr = tr_sessionGetPublicAddress (s, TR_AF_INET6, &is_default_value))) && !is_default_value)
    curl_easy_setopt (e, CURLOPT_INTERFACE, tr_address_to_string (addr));

  if (task->cookies != NULL)
    curl_easy_setopt (e, CURLOPT_COOKIE, task->cookies);

  if (web->cookie_filename != NULL)
    curl_easy_setopt (e, CURLOPT_COOKIEFILE, web->cookie_filename);

  if (task->range != NULL)
    {
      curl_easy_setopt (e, CURLOPT_RANGE, task->range);
      /* don't bother asking the server to compress webseed fragments */
      curl_easy_setopt (e, CURLOPT_ENCODING, "identity");
    }

  return e;
}
Ejemplo n.º 2
0
static CURL *
createEasy( tr_session * s, struct tr_web_task * task )
{
    const tr_address * addr;
    CURL * e = curl_easy_init( );
    const long verbose = getenv( "TR_CURL_VERBOSE" ) != NULL;

    if( !task->range && s->isProxyEnabled ) {
        const long proxyType = getCurlProxyType( s->proxyType );
        curl_easy_setopt( e, CURLOPT_PROXY, s->proxy );
        curl_easy_setopt( e, CURLOPT_PROXYAUTH, CURLAUTH_ANY );
        curl_easy_setopt( e, CURLOPT_PROXYPORT, s->proxyPort );
        curl_easy_setopt( e, CURLOPT_PROXYTYPE, proxyType );
    }

    if( !task->range && s->isProxyAuthEnabled ) {
        char * str = tr_strdup_printf( "%s:%s", s->proxyUsername,
                                                s->proxyPassword );
        curl_easy_setopt( e, CURLOPT_PROXYUSERPWD, str );
        tr_free( str );
    }

    curl_easy_setopt( e, CURLOPT_AUTOREFERER, 1L );
    curl_easy_setopt( e, CURLOPT_ENCODING, "gzip;q=1.0, deflate, identity" );
    curl_easy_setopt( e, CURLOPT_FOLLOWLOCATION, 1L );
    curl_easy_setopt( e, CURLOPT_MAXREDIRS, -1L );
    curl_easy_setopt( e, CURLOPT_NOSIGNAL, 1L );
    curl_easy_setopt( e, CURLOPT_PRIVATE, task );
#ifdef USE_LIBCURL_SOCKOPT
    curl_easy_setopt( e, CURLOPT_SOCKOPTFUNCTION, sockoptfunction );
    curl_easy_setopt( e, CURLOPT_SOCKOPTDATA, task );
#endif
    curl_easy_setopt( e, CURLOPT_SSL_VERIFYHOST, 0L );
    curl_easy_setopt( e, CURLOPT_SSL_VERIFYPEER, 0L );
    curl_easy_setopt( e, CURLOPT_TIMEOUT, getTimeoutFromURL( task->url ) );
    curl_easy_setopt( e, CURLOPT_URL, task->url );
    curl_easy_setopt( e, CURLOPT_USERAGENT, TR_NAME "/" SHORT_VERSION_STRING );
    curl_easy_setopt( e, CURLOPT_VERBOSE, verbose );
    curl_easy_setopt( e, CURLOPT_WRITEDATA, task );
    curl_easy_setopt( e, CURLOPT_WRITEFUNCTION, writeFunc );

    if(( addr = tr_sessionGetPublicAddress( s, TR_AF_INET )))
        curl_easy_setopt( e, CURLOPT_INTERFACE, tr_ntop_non_ts( addr ) );

    if( task->range )
        curl_easy_setopt( e, CURLOPT_RANGE, task->range );

    return e;
}
Ejemplo n.º 3
0
static CURL *
createEasy( tr_session * s, struct tr_web_task * task )
{
    const tr_address * addr;
    tr_bool is_default_value;
    CURL * e = curl_easy_init( );
    const long verbose = getenv( "TR_CURL_VERBOSE" ) != NULL;
    char * cookie_filename = tr_buildPath( s->configDir, "cookies.txt", NULL );

    task->timeout_secs = getTimeoutFromURL( task );

    curl_easy_setopt( e, CURLOPT_AUTOREFERER, 1L );
    curl_easy_setopt( e, CURLOPT_COOKIEFILE, cookie_filename );
    curl_easy_setopt( e, CURLOPT_ENCODING, "gzip;q=1.0, deflate, identity" );
    curl_easy_setopt( e, CURLOPT_FOLLOWLOCATION, 1L );
    curl_easy_setopt( e, CURLOPT_MAXREDIRS, -1L );
    curl_easy_setopt( e, CURLOPT_NOSIGNAL, 1L );
    curl_easy_setopt( e, CURLOPT_PRIVATE, task );
#ifdef USE_LIBCURL_SOCKOPT
    curl_easy_setopt( e, CURLOPT_SOCKOPTFUNCTION, sockoptfunction );
    curl_easy_setopt( e, CURLOPT_SOCKOPTDATA, task );
#endif
    curl_easy_setopt( e, CURLOPT_SSL_VERIFYHOST, 0L );
    curl_easy_setopt( e, CURLOPT_SSL_VERIFYPEER, 0L );
    curl_easy_setopt( e, CURLOPT_TIMEOUT, task->timeout_secs );
    curl_easy_setopt( e, CURLOPT_URL, task->url );
    curl_easy_setopt( e, CURLOPT_USERAGENT, TR_NAME "/" SHORT_VERSION_STRING );
    curl_easy_setopt( e, CURLOPT_VERBOSE, verbose );
    curl_easy_setopt( e, CURLOPT_WRITEDATA, task );
    curl_easy_setopt( e, CURLOPT_WRITEFUNCTION, writeFunc );

    if((( addr = tr_sessionGetPublicAddress( s, TR_AF_INET, &is_default_value ))) && !is_default_value )
        curl_easy_setopt( e, CURLOPT_INTERFACE, tr_ntop_non_ts( addr ) );
    else if ((( addr = tr_sessionGetPublicAddress( s, TR_AF_INET6, &is_default_value ))) && !is_default_value )
        curl_easy_setopt( e, CURLOPT_INTERFACE, tr_ntop_non_ts( addr ) );

    if( task->range )
        curl_easy_setopt( e, CURLOPT_RANGE, task->range );

    if( s->curl_easy_config_func != NULL )
        s->curl_easy_config_func( s, e, task->url );

    tr_free( cookie_filename );
    return e;
}
Ejemplo n.º 4
0
static void
addTask( void * vtask )
{
    struct tr_web_task * task = vtask;
    const tr_session * session = task->session;

    if( ( session == NULL ) || ( session->web == NULL ) )
        return;

    if( !task->resolved_host )
    {
        dbgmsg( "couldn't resolve host for \"%s\"... task failed", task->url );
        task_finish( task, 0 );
    }
    else
    {
        CURL * e = curl_easy_init( );
        struct tr_web * web = session->web;
        const int timeout = getTimeoutFromURL( task->url );
        const long verbose = getenv( "TR_CURL_VERBOSE" ) != NULL;
        const char * user_agent = TR_NAME "/" SHORT_VERSION_STRING;

        /* insert the resolved host into the URL s.t. curl's DNS won't block
         * even if -- like on most OSes -- it wasn't built with C-Ares :(
         * "http://www.craptrackular.org/announce?key=val&key2=..." becomes
         * "http://127.0.0.1/announce?key=val&key2=..." */
        {
            char * host;
            struct evbuffer * buf = evbuffer_new( );
            char * pch = strstr( task->url, task->host );
            char * tail = pch + strlen( task->host );
            evbuffer_add( buf, task->url, pch - task->url );
            evbuffer_add_printf( buf, "%s", task->resolved_host );
            evbuffer_add_printf( buf, "%s", tail );
            task->resolved_url = tr_strndup( EVBUFFER_DATA( buf ), EVBUFFER_LENGTH( buf ) );
            dbgmsg( "old url: \"%s\" -- new url: \"%s\"", task->url, task->resolved_url );
            evbuffer_free( buf );

            /* Manually add a Host: argument that refers to the true URL */
            if( ( ( task->port <= 0 ) ) ||
                ( ( task->port == 80 ) && !strncmp( task->url, "http://", 7 ) ) ||
                ( ( task->port == 443 ) && !strncmp( task->url, "https://", 8 ) ) )
                host = tr_strdup_printf( "Host: %s", task->host );
            else
                host = tr_strdup_printf( "Host: %s:%d", task->host, task->port );

            task->slist = curl_slist_append( NULL, host );
            task->slist = curl_slist_append( task->slist, "Accept:" );
            curl_easy_setopt( e, CURLOPT_HTTPHEADER, task->slist );
            tr_free( host );
        }

        dbgmsg( "adding task #%lu [%s]", task->tag, task->resolved_url ? task->resolved_url : task->url );

        if( !task->range && session->isProxyEnabled ) {
            curl_easy_setopt( e, CURLOPT_PROXY, session->proxy );
            curl_easy_setopt( e, CURLOPT_PROXYAUTH, CURLAUTH_ANY );
            curl_easy_setopt( e, CURLOPT_PROXYPORT, session->proxyPort );
            curl_easy_setopt( e, CURLOPT_PROXYTYPE,
                                      getCurlProxyType( session->proxyType ) );
        }
        if( !task->range && session->isProxyAuthEnabled ) {
            char * str = tr_strdup_printf( "%s:%s", session->proxyUsername,
                                                    session->proxyPassword );
            curl_easy_setopt( e, CURLOPT_PROXYUSERPWD, str );
            tr_free( str );
        }

        task->easy = e;
        task->multi = web->multi;

        /* use our own timeout instead of CURLOPT_TIMEOUT because the latter
         * doesn't play nicely with curl_multi.  See curl bug #2501457 */
        task->timer_event_isSet = TRUE;
        evtimer_set( &task->timer_event, task_timeout_cb, task );
        tr_timerAdd( &task->timer_event, timeout, 0 );

        curl_easy_setopt( e, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
        curl_easy_setopt( e, CURLOPT_SOCKOPTFUNCTION, sockoptfunction );
        curl_easy_setopt( e, CURLOPT_SOCKOPTDATA, task );
        curl_easy_setopt( e, CURLOPT_WRITEDATA, task );
        curl_easy_setopt( e, CURLOPT_WRITEFUNCTION, writeFunc );
        curl_easy_setopt( e, CURLOPT_DNS_CACHE_TIMEOUT, MIN_DNS_CACHE_TIME );
        curl_easy_setopt( e, CURLOPT_FOLLOWLOCATION, 1L );
        curl_easy_setopt( e, CURLOPT_AUTOREFERER, 1L );
        curl_easy_setopt( e, CURLOPT_FORBID_REUSE, 1L );
        curl_easy_setopt( e, CURLOPT_MAXREDIRS, -1L );
        curl_easy_setopt( e, CURLOPT_PRIVATE, task );
        curl_easy_setopt( e, CURLOPT_SSL_VERIFYHOST, 0L );
        curl_easy_setopt( e, CURLOPT_SSL_VERIFYPEER, 0L );
        curl_easy_setopt( e, CURLOPT_URL, task->resolved_url ? task->resolved_url : task->url );
        curl_easy_setopt( e, CURLOPT_USERAGENT, user_agent );
        curl_easy_setopt( e, CURLOPT_VERBOSE, verbose );
        if( web->haveAddr )
            curl_easy_setopt( e, CURLOPT_INTERFACE, tr_ntop_non_ts( &web->addr ) );
        if( task->range )
            curl_easy_setopt( e, CURLOPT_RANGE, task->range );

        if( curl_multi_add_handle( web->multi, e ) == CURLM_OK )
            ++web->taskCount;
    }
}