Commit 86ff2c46 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

introduced 'tunnel through http proxy' for ftp

parent be8b2a1e
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -372,6 +372,7 @@ CURLcode ftp_connect(struct connectdata *conn)
  struct UrlData *data=conn->data;
  char *buf = data->buffer; /* this is our buffer */
  struct FTP *ftp;
  CURLcode result;

  myalarm(0); /* switch off the alarm stuff */

@@ -387,6 +388,13 @@ CURLcode ftp_connect(struct connectdata *conn)
  ftp->user = data->user;
  ftp->passwd = data->passwd;

  if (data->bits.tunnel_thru_httpproxy) {
    /* We want "seamless" FTP operations through HTTP proxy tunnel */
    result = GetHTTPProxyTunnel(data, data->firstsocket);
    if(CURLE_OK != result)
      return result;
  }

  /* The first thing we do is wait for the "220*" line: */
  nread = GetLastResponse(data->firstsocket, buf, conn);
  if(nread < 0)
@@ -860,11 +868,17 @@ CURLcode _ftp(struct connectdata *conn)
        }
        return CURLE_FTP_CANT_RECONNECT;
      }
    }

      if (data->bits.tunnel_thru_httpproxy) {
        /* We want "seamless" FTP operations through HTTP proxy tunnel */
        result = GetHTTPProxyTunnel(data, data->secondarysocket);
        if(CURLE_OK != result)
          return result;
      }
    }
  }
  /* we have the (new) data connection ready */
  infof(data, "Connected!\n");
  infof(data, "Connected the data stream!\n");

  if(data->bits.upload) {

+65 −49
Original line number Diff line number Diff line
@@ -134,23 +134,21 @@ bool static checkheaders(struct UrlData *data, char *thisheader)
  return FALSE;
}

CURLcode http_connect(struct connectdata *conn)
{
  struct UrlData *data;
/*
 * GetHTTPProxyTunnel() requires that we're connected to a HTTP proxy. This
 * function will issue the necessary commands to get a seamless tunnel through
 * this proxy. After that, the socket can be used just as a normal socket.
 */

  data=conn->data;
CURLcode GetHTTPProxyTunnel(struct UrlData *data, int tunnelsocket)
{
  int httperror=0;
  int subversion=0;

  /* 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 (conn->protocol & PROT_HTTPS) {
     if (data->bits.httpproxy) {
  infof(data, "Establish HTTP proxy tunnel\n");

  /* OK, now send the connect statment */
        sendf(data->firstsocket, data,
  sendf(tunnelsocket, data,
        "CONNECT %s:%d HTTP/1.0\015\012"
        "%s"
        "%s"
@@ -161,11 +159,7 @@ CURLcode http_connect(struct connectdata *conn)
        );

  /* 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)) {
  while(GetLine(tunnelsocket, data->buffer, data)) {
    if('\r' == data->buffer[0])
      break; /* end of headers */
    if(2 == sscanf(data->buffer, "HTTP/1.%d %d",
@@ -182,8 +176,30 @@ CURLcode http_connect(struct connectdata *conn)
      failf(data, "Received error code %d from proxy", httperror);
    return CURLE_READ_ERROR;
  }

  infof (data, "Proxy replied to CONNECT request\n");
  return CURLE_OK;
}
        infof (data, "Proxy has replied to CONNECT request\n");

CURLcode http_connect(struct connectdata *conn)
{
  struct UrlData *data;
  CURLcode result;

  data=conn->data;

  /* 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 (conn->protocol & PROT_HTTPS) {
    if (data->bits.httpproxy) {
      /* HTTPS through a proxy can only be done with a tunnel */
      result = GetHTTPProxyTunnel(data, data->firstsocket);
      if(CURLE_OK != result)
        return result;
    }

    /* now, perform the SSL initialization for this socket */
+3 −1
Original line number Diff line number Diff line
@@ -41,8 +41,10 @@
 * ------------------------------------------------------------
 ****************************************************************************/

/* protocol-specific functions set up to be called by the main engine */
/* ftp can use this as well */
CURLcode GetHTTPProxyTunnel(struct UrlData *data, int tunnelsocket);

/* protocol-specific functions set up to be called by the main engine */
CURLcode http(struct connectdata *conn);
CURLcode http_done(struct connectdata *conn);
CURLcode http_connect(struct connectdata *conn);
+8 −1
Original line number Diff line number Diff line
@@ -437,6 +437,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
    data->proxy = va_arg(param, char *);
    data->bits.httpproxy = data->proxy?1:0;
    break;
  case CURLOPT_HTTPPROXYTUNNEL:
    data->bits.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
    break;
  case CURLOPT_PROXYPORT:
    data->proxyport = va_arg(param, long);
    break;
@@ -619,6 +622,7 @@ CURLcode curl_disconnect(CURLconnect *c_connect)
  return CURLE_OK;
}


/*
 * NAME curl_connect()
 *
@@ -948,7 +952,10 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
    data->remote_port = PORT_FTP;
    conn->protocol |= PROT_FTP;

    if(data->bits.httpproxy) {
    if(data->bits.httpproxy &&
       !data->bits.tunnel_thru_httpproxy) {
      /* Unless we have asked to tunnel ftp operations through the proxy, we
         switch and use HTTP operations only */
      conn->curl_do = http;
      conn->curl_done = http_done;
      conn->curl_close = http_close;
+1 −0
Original line number Diff line number Diff line
@@ -245,6 +245,7 @@ struct FTP {
};

struct Configbits {
  bool tunnel_thru_httpproxy;
  bool ftp_append;
  bool ftp_ascii;
  bool ftp_list_only;