Skip to content
Snippets Groups Projects
url.c 35.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • Daniel Stenberg's avatar
    Daniel Stenberg committed
        data->remote_port = PORT_TELNET;
    
    
        conn->curl_do = telnet;
        conn->curl_done = telnet_done;
    
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
      else if (strequal(conn->proto, "DICT")) {
        conn->protocol |= PROT_DICT;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if(!data->port)
          data->port = PORT_DICT;
        data->remote_port = PORT_DICT;
    
        conn->curl_do = dict;
        conn->curl_done = dict_done;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
      else if (strequal(conn->proto, "LDAP")) {
        conn->protocol |= PROT_LDAP;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if(!data->port)
          data->port = PORT_LDAP;
        data->remote_port = PORT_LDAP;
    
        conn->curl_do = ldap;
        conn->curl_done = ldap_done;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
      else if (strequal(conn->proto, "FILE")) {
        conn->protocol |= PROT_FILE;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
    
        conn->curl_do = file;
        /* no done() function */
    
    
        result = Transfer(conn, -1, -1, FALSE, NULL, /* no download */
                          -1, NULL); /* no upload */
    
        return CURLE_OK;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
      else {
    
        failf(data, "Unsupported protocol: %s", conn->proto);
        return CURLE_UNSUPPORTED_PROTOCOL;
    
      if(data->bits.use_netrc) {
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if(ParseNetrc(data->hostname, data->user, data->passwd)) {
          infof(data, "Couldn't find host %s in the .netrc file, using defaults",
                data->hostname);
        }
        /* weather we failed or not, we don't know which fields that were filled
           in anyway */
        if(!data->user[0])
          strcpy(data->user, CURL_DEFAULT_USER);
        if(!data->passwd[0])
          strcpy(data->passwd, CURL_DEFAULT_PASSWORD);
    
        if(conn->protocol&PROT_HTTP) {
          data->bits.user_passwd = 1; /* enable user+password */
    
      else if(!(data->bits.user_passwd) &&
    	  (conn->protocol & (PROT_FTP|PROT_HTTP)) ) {
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        /* This is a FTP or HTTP URL, and we haven't got the user+password in
           the extra parameter, we will now try to extract the possible
           user+password pair in a string like:
           ftp://user:password@ftp.my.site:8021/README */
        char *ptr=NULL; /* assign to remove possible warnings */
    
        if(':' == *conn->name) {
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
          failf(data, "URL malformat: user can't be zero length");
    
          return CURLE_URL_MALFORMAT_USER;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        }
    
    #endif
        if(ptr=strchr(conn->name, '@')) {
          /* there's a user+password given here, to the left of the @ */
    
          data->user[0] =0;
          data->passwd[0]=0;
    
          if(*conn->name != ':') {
            /* the name is given, get user+password */
            sscanf(conn->name, "%127[^:]:%127[^@]",
                   data->user, data->passwd);
          }
          else
            /* no name given, get the password only */
            sscanf(conn->name+1, "%127[^@]", data->passwd);
    
          /* check for password, if no ask for one */
          if( !data->passwd[0] ) {
            strncpy(data->passwd, getpass("password: "), sizeof(data->passwd));
          }
    
    
          conn->name = ++ptr;
          data->bits.user_passwd=1; /* enable user+password */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        }
        else {
          strcpy(data->user, CURL_DEFAULT_USER);
          strcpy(data->passwd, CURL_DEFAULT_PASSWORD);
        }
      }
    
    
      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. */
    
        tmp = strchr(conn->name, ':');
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if (tmp) {
          *tmp++ = '\0';
          data->port = atoi(tmp);
        }
        
        /* Connect to target host right on */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if(!(conn->hp = GetHost(data, conn->name, hostent_buf, sizeof(hostent_buf)))) {
    
          failf(data, "Couldn't resolv host '%s'", conn->name);
          return CURLE_COULDNT_RESOLVE_HOST;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        }
      }
      else {
        char *prox_portno;
        char *endofprot;
    
    
        /* We need to make a duplicate of the proxy so that we can modify the
           string safely. */
        char *proxydup=strdup(data->proxy);
    
        /* We use 'proxyptr' to point to the proxy name from now on... */
        char *proxyptr=proxydup;
    
        if(NULL == proxydup) {
          failf(data, "memory shortage");
    
          return CURLE_OUT_OF_MEMORY;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        /* we use proxy all right, but we wanna know the remote port for SSL
           reasons */
    
        tmp = strchr(conn->name, ':');
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if (tmp) {
          *tmp++ = '\0'; /* cut off the name there */
          data->remote_port = atoi(tmp);
        }
    
        /* Daniel Dec 10, 1998:
           We do the proxy host string parsing here. We want the host name and the
           port name. Accept a protocol:// prefix, even though it should just be
           ignored. */
    
        /* 1. skip the protocol part if present */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if(endofprot) {
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        }
    
        /* allow user to specify proxy.server.com:1080 if desired */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if (prox_portno) {
          *prox_portno = 0x0; /* cut off number from host name */
          prox_portno ++;
          /* now set the local port number */
          data->port = atoi(prox_portno);
        }
    
        else if(data->proxyport) {
          /* None given in the proxy string, then get the default one if it is
             given */
          data->port = data->proxyport;
        }
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
        /* connect to proxy */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if(!(conn->hp = GetHost(data, proxyptr, hostent_buf, sizeof(hostent_buf)))) {
    
          failf(data, "Couldn't resolv proxy '%s'", proxyptr);
    
          return CURLE_COULDNT_RESOLVE_PROXY;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        }
    
    
        free(proxydup); /* free the duplicate pointer and not the modified */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
      pgrsTime(data, TIMER_NAMELOOKUP);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
      data->firstsocket = socket(AF_INET, SOCK_STREAM, 0);
    
    
      memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
      memcpy((char *)&(conn->serv_addr.sin_addr),
             conn->hp->h_addr, conn->hp->h_length);
      conn->serv_addr.sin_family = conn->hp->h_addrtype;
      conn->serv_addr.sin_port = htons(data->port);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
    
      if (connect(data->firstsocket,
                  (struct sockaddr *) &(conn->serv_addr),
                  sizeof(conn->serv_addr)
                  ) < 0) {
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        switch(errno) {
    #ifdef ECONNREFUSED
          /* this should be made nicer */
        case ECONNREFUSED:
          failf(data, "Connection refused");
          break;
    #endif
    #ifdef EINTR
        case EINTR:
          failf(data, "Connection timeouted");
          break;
    #endif
        default:
          failf(data, "Can't connect to server: %d", errno);
          break;
        }
    
        return CURLE_COULDNT_CONNECT;
    
      if(data->bits.proxy_user_passwd) {
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        char authorization[512];
        sprintf(data->buffer, "%s:%s", data->proxyuser, data->proxypasswd);
        base64Encode(data->buffer, authorization);
    
        data->ptr_proxyuserpwd = maprintf("Proxy-authorization: Basic %s\015\012",
    				      authorization);
      }
    
      if((conn->protocol&PROT_HTTP) || data->bits.httpproxy) {
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if(data->useragent) {
          data->ptr_uagent = maprintf("User-Agent: %s\015\012", data->useragent);
        }
      }
    
    
      if(conn->curl_connect) {
    
        /* is there a connect() procedure? */
        conn->now = tvnow(); /* set this here for timeout purposes in the
                                connect procedure, it is later set again for the
                                progress meter purpose */
    
        result = conn->curl_connect(conn);
    
        if(result != CURLE_OK)
          return result; /* pass back errors */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
      pgrsTime(data, TIMER_CONNECT); /* we're connected */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
    
      conn->now = tvnow(); /* time this *after* the connect is done */
      conn->bytecount = 0;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      
      /* Figure out the ip-number and the first host name it shows: */
      {
        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));
    
    #if 0 /* Kerberos experiements! Beware! Take cover! */
      kerberos_connect(data, name);
    #endif
    
    
    #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
    
    
      return CURLE_OK;
    }
    
    CURLcode curl_done(CURLconnect *c_connect)
    {
      struct connectdata *conn = c_connect;
      struct UrlData *data;
      CURLcode result;
    
      if(!conn || (conn->handle!= STRUCT_CONNECT)) {
        return CURLE_BAD_FUNCTION_ARGUMENT;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
      if(conn->state != CONN_DO) {
        /* This can only be called after a curl_do() */
        return CURLE_BAD_CALLING_ORDER;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
      data = conn->data;
    
      /* this calls the protocol-specific function pointer previously set */
      if(conn->curl_done)
        result = conn->curl_done(conn);
      else
        result = CURLE_OK;
    
      pgrsDone(data); /* done with the operation */
    
      conn->state = CONN_DONE;
    
      return result;
    }
    
    CURLcode curl_do(CURLconnect *in_conn)
    {
      struct connectdata *conn = in_conn;
      CURLcode result;
    
      if(!conn || (conn->handle!= STRUCT_CONNECT)) {
        return CURLE_BAD_FUNCTION_ARGUMENT;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
      if(conn->state != CONN_INIT) {
        return CURLE_BAD_CALLING_ORDER;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
    
      if(conn->curl_do) {
        /* generic protocol-specific function pointer set in curl_connect() */
        result = conn->curl_do(conn);
        if(result) {
          conn->state = CONN_ERROR;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
          return result;
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
    
      conn->state = CONN_DO; /* we have entered this state */
    
    #if 0
      if(conn->bytecount) {
        double ittook = tvdiff (tvnow(), conn->now);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        infof(data, "%i bytes transfered in %.3lf seconds (%.0lf bytes/sec).\n",
    
              conn->bytecount, ittook, (double)conn->bytecount/(ittook!=0.0?ittook:1));
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      }
    
    #endif
      return CURLE_OK;