Skip to content
Snippets Groups Projects
url.c 66.9 KiB
Newer Older
  • Learn to ignore specific revisions
  •     free(proxydup); /* free the duplicate pointer and not the modified */
      }
    
    
      /*************************************************************
       * Check the current list of connections to see if we can
       * re-use an already existing one or if we have to create a
       * new one.
       *************************************************************/
    
    
      /* reuse_fresh is set TRUE if we are told to use a fresh connection
         by force */
      if(!data->bits.reuse_fresh &&
         ConnectionExists(data, conn, &conn_temp)) {
    
        /*
         * We already have a connection for this, we got the former connection
         * in the conn_temp variable and thus we need to cleanup the one we
         * just allocated before we can move along and use the previously
         * existing one.
         */
    
        struct connectdata *old_conn = conn;
        char *path = old_conn->path; /* setup the current path pointer properly */
        if(old_conn->proxyhost)
          free(old_conn->proxyhost);
    
        conn = conn_temp;        /* use this connection from now on */
    
    
        /* we need these pointers if we speak over a proxy */
    
        conn->name = conn->gname;
        conn->hostname = old_conn->gname;
    
        conn->path = path;       /* use this one */
    
    
        /* The 'ppath' may have been advanced a few steps from the 'path' start
           point. We must also advance our new pointer as many steps as the
           previous one was! This was the cause of the multiple ftp file bug
           found on May 9 2001 libcurl 7.7.3 */
        conn->ppath = (old_conn->ppath - old_conn->path)+path;
    
        free(old_conn->path);    /* free the previous path pointer */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        conn->bits.reuse = TRUE; /* yes, we're re-using here */
    
        conn->bits.chunk = FALSE; /* always assume not chunked unless told otherwise */
    
        conn->maxdownload = -1;  /* might have been used previously! */
    
        free(old_conn);          /* we don't need this anymore */
    
    
        *in_connect = conn;      /* return this instead! */
    
    
        infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex);
    
      }
      else {
        /*
         * This is a brand new connection, so let's store it in the connection
         * cache of ours!
         */
        ConnectionStore(data, conn);
      }
    
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      /*************************************************************
       * Resolve the name of the server or proxy
       *************************************************************/
    
      if(!data->bits.httpproxy) {
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        /* If not connecting via a proxy, extract the port from the URL, if it is
         * there, thus overriding any defaults that might have been set above. */
    
        conn->port =  conn->remote_port; /* it is the same port */
    
        /* Resolve target host right on */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if(!conn->hp) {
    
    #ifdef ENABLE_IPV6
    
          /* it might already be set if reusing a connection */
    
          conn->hp = Curl_getaddrinfo(data, conn->name, conn->port);
    
          /* it might already be set if reusing a connection */
          conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        }
        if(!conn->hp)
    
          failf(data, "Couldn't resolve host '%s'", conn->name);
    
          return CURLE_COULDNT_RESOLVE_HOST;
    
      else if(!conn->hp) {
        /* This is a proxy that hasn't been resolved yet. It may be resolved
           if we're reusing an existing connection. */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
    
        /* resolve proxy */
    
    #ifdef ENABLE_IPV6
          /* it might already be set if reusing a connection */
        conn->hp = Curl_getaddrinfo(data, conn->proxyhost, conn->port);
    #else
    
        conn->hp = Curl_gethost(data, conn->proxyhost, &conn->hostent_buf);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if(!conn->hp) {
    
          failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost);
    
          return CURLE_COULDNT_RESOLVE_PROXY;
    
      Curl_pgrsTime(data, TIMER_NAMELOOKUP);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      /*************************************************************
       * Proxy authentication
       *************************************************************/
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        char *authorization;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        snprintf(data->buffer, BUFSIZE, "%s:%s",
                 data->proxyuser, data->proxypasswd);
    
        if(Curl_base64_encode(data->buffer, strlen(data->buffer),
                              &authorization) >= 0) {
    
          if(conn->allocptr.proxyuserpwd)
            free(conn->allocptr.proxyuserpwd);
          conn->allocptr.proxyuserpwd =
    
            aprintf("Proxy-authorization: Basic %s\015\012", authorization);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
          free(authorization);
        }
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
      /*************************************************************
       * Send user-agent to HTTP proxies even if the target protocol
       * isn't HTTP.
       *************************************************************/
    
      if((conn->protocol&PROT_HTTP) || data->bits.httpproxy) {
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if(data->useragent) {
    
          if(conn->allocptr.uagent)
            free(conn->allocptr.uagent);
          conn->allocptr.uagent =
    
            aprintf("User-Agent: %s\015\012", data->useragent);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      if(-1 == conn->firstsocket) {
        /* Connect only if not already connected! */
        result = ConnectPlease(data, conn);
        if(CURLE_OK != result)
          return result;
    
        if(conn->curl_connect) {
          /* is there a connect() procedure? */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
          /* set start time here for timeout purposes in the
           * connect procedure, it is later set again for the
           * progress meter purpose */
          conn->now = Curl_tvnow();
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
          /* Call the protocol-specific connect function */
          result = conn->curl_connect(conn);
          if(result != CURLE_OK)
            return result; /* pass back errors */
        }
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
      Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
    
      conn->now = Curl_tvnow(); /* time this *after* the connect is done */
    
      conn->bytecount = 0;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      /* Figure out the ip-number and display the first host name it shows: */
    
    #ifdef ENABLE_IPV6
      {
        char hbuf[NI_MAXHOST];
    #ifdef NI_WITHSCOPEID
        const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
    #else
        const int niflags = NI_NUMERICHOST;
    #endif
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        struct addrinfo *ai = conn->ai;
    
    
        if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0,
    	niflags)) {
          snprintf(hbuf, sizeof(hbuf), "?");
        }
        if (ai->ai_canonname) {
          infof(data, "Connected to %s (%s)\n", ai->ai_canonname, hbuf);
        } else {
          infof(data, "Connected to %s\n", hbuf);
        }
      }
    #else
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      {
        struct in_addr in;
    
        (void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr));
        infof(data, "Connected to %s (%s)\n", conn->hp->h_name, inet_ntoa(in));
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
    
    #ifdef __EMX__
      /* 20000330 mgs
       * the check is quite a hack...
       * we're calling _fsetmode to fix the problem with fwrite converting newline
       * characters (you get mangled text files, and corrupted binary files when
       * you download to stdout and redirect it to a file). */
    
      if ((data->out)->_handle == NULL) {
        _fsetmode(stdout, "b");
      }
    #endif
    
    
    CURLcode Curl_connect(struct UrlData *data,
                          struct connectdata **in_connect,
    
    {
      CURLcode code;
      struct connectdata *conn;
    
      /* call the stuff that needs to be called */
    
      code = Connect(data, in_connect, allow_port);
    
    
      if(CURLE_OK != code) {
        /* We're not allowed to return failure with memory left allocated
           in the connectdata struct, free those here */
        conn = (struct connectdata *)*in_connect;
    
          Curl_disconnect(conn);      /* close the connection */
    
    CURLcode Curl_done(struct connectdata *conn)
    
      CURLcode result;
    
    
      /* cleanups done even if the connection is re-used */
    
      if(conn->bits.rangestringalloc) {
        free(conn->range);
        conn->bits.rangestringalloc = FALSE;
      }
    
    
      /* this calls the protocol-specific function pointer previously set */
      if(conn->curl_done)
        result = conn->curl_done(conn);
      else
        result = CURLE_OK;
    
    
      Curl_pgrsDone(conn); /* done with the operation */
    
      /* if data->bits.reuse_forbid is TRUE, it means the libcurl client has
         forced us to close this no matter what we think.
        
         if conn->bits.close is TRUE, it means that the connection should be
         closed in spite of all our efforts to be nice, due to protocol
         restrictions in our or the server's end */
      if(data->bits.reuse_forbid ||
         ((CURLE_OK == result) && conn->bits.close))
    
        result = Curl_disconnect(conn); /* close the connection */
    
      else
        infof(data, "Connection (#%d) left alive\n", conn->connectindex);
    
    CURLcode Curl_do(struct connectdata *conn)
    
      CURLcode result=CURLE_OK;
    
        /* generic protocol-specific function pointer set in curl_connect() */
        result = conn->curl_do(conn);