Skip to content
Snippets Groups Projects
url.c 32.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • Daniel Stenberg's avatar
    Daniel Stenberg committed
          strcpy(data->user, CURL_DEFAULT_USER);
          strcpy(data->passwd, CURL_DEFAULT_PASSWORD);
        }
      }
    
      if(!(data->conf & CONF_PROXY)) {
        /* 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(name, ':');
        if (tmp) {
          *tmp++ = '\0';
          data->port = atoi(tmp);
        }
        
        /* Connect to target host right on */
        if(!(hp = GetHost(data, name))) {
          failf(data, "Couldn't resolv host '%s'", name);
          return URG_COULDNT_RESOLVE_HOST;
        }
      }
      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 URG_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(name, ':');
        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);
        }
    
        /* connect to proxy */
    
        if(!(hp = GetHost(data, proxyptr))) {
          failf(data, "Couldn't resolv proxy '%s'", proxyptr);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
          return URG_COULDNT_RESOLVE_PROXY;
        }
    
    
        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 *) &serv_addr, '\0', sizeof(serv_addr));
      memcpy((char *)&(serv_addr.sin_addr), hp->h_addr, hp->h_length);
      serv_addr.sin_family = hp->h_addrtype;
    
      serv_addr.sin_port = htons(data->port);
    
      if (connect(data->firstsocket, (struct sockaddr *) &serv_addr,
    	      sizeof(serv_addr)) < 0) {
        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 URG_COULDNT_CONNECT;
      }
    
      if(data->conf & CONF_PROXYUSERPWD) {
        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(data->conf & (CONF_HTTPS|CONF_HTTP|CONF_PROXY)) {
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        if(data->useragent) {
          data->ptr_uagent = maprintf("User-Agent: %s\015\012", data->useragent);
        }
      }
    
    
      /* If we are not using a proxy and we want a secure connection,
       * perform SSL initialization & connection now.
       * If using a proxy with https, then we must tell the proxy to CONNECT
       * us to the host we want to talk to.  Only after the connect
       * has occured, can we start talking SSL
       */
       if (data->conf & CONF_HTTPS) {
         if (data->conf & CONF_PROXY) {
    
            /* OK, now send the connect statment */
            sendf(data->firstsocket, data,
                  "CONNECT %s:%d HTTP/1.0\015\012"
                  "%s"
    	      "%s"
                  "\r\n",
                  data->hostname, data->remote_port,
                  (data->conf&CONF_PROXYUSERPWD)?data->ptr_proxyuserpwd:"",
    	      (data->useragent?data->ptr_uagent:"")
                  );
    
            /* wait for the proxy to send us a HTTP/1.0 200 OK header */
    	/* Daniel rewrote this part Nov 5 1998 to make it more obvious */
    	{
    	  int httperror=0;
    	  int subversion=0;
    	  while(GetLine(data->firstsocket, data->buffer, data)) {
    	    if('\r' == data->buffer[0])
    	      break; /* end of headers */
    	    if(2 == sscanf(data->buffer, "HTTP/1.%d %d",
    			   &subversion,
    			   &httperror)) {
    	      ;
    	    }
    	  }
    	  if(200 != httperror) {
    	    if(407 == httperror)
    	      /* Added Nov 6 1998 */
    	      failf(data, "Proxy requires authorization!");
    	    else 
    	      failf(data, "Received error code %d from proxy", httperror);
    	    return URG_READ_ERROR;
    	  }
    	}
            infof (data, "Proxy has replied to CONNECT request\n");
         }
    
          /* now, perform the SSL initialization for this socket */
         if(UrgSSLConnect (data)) {
           return URG_SSL_CONNECT_ERROR;
         }
      }
    
      pgrsTime(data, TIMER_CONNECT);
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
    
      now = tvnow(); /* time this *after* the connect is done */
      bytecount = 0;
      
      /* Figure out the ip-number and the first host name it shows: */
      {
        struct in_addr in;
        (void) memcpy(&in.s_addr, *hp->h_addr_list, sizeof (in.s_addr));
        infof(data, "Connected to %s (%s)\n", 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
    
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
      if((data->conf&(CONF_FTP|CONF_PROXY)) == CONF_FTP) {
        result = ftp(data, &bytecount, data->user, data->passwd, ppath);
        if(result)
          return result;
      }
      else if(data->conf & CONF_TELNET) {
        result=telnet(data);
        if(result)
          return result;
      }
      else if (data->conf & CONF_LDAP) {
        result = ldap(data, path, &bytecount);
        if (result)
          return result;
      }
      else if (data->conf & CONF_DICT) {
        result = dict(data, path, &bytecount);
        if(result)
          return result;
      }
      else {
        result = http(data, ppath, name, &bytecount);
        if(result)
          return result;
      }
      if(bytecount) {
        double ittook = tvdiff (tvnow(), now);
        infof(data, "%i bytes transfered in %.3lf seconds (%.0lf bytes/sec).\n",
              bytecount, ittook, (double)bytecount/(ittook!=0.0?ittook:1));
      }
      return URG_OK;
    }