From 0da7057591609d98f3e0820a13730d97abb2083a Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 15 Sep 2000 06:10:52 +0000
Subject: [PATCH] more "anything through http proxy tunnel" fixes

---
 lib/ftp.c  | 37 ++++++++++++++++++++++++++++---------
 lib/http.c |  8 +++++---
 lib/http.h |  3 ++-
 3 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/lib/ftp.c b/lib/ftp.c
index 3d98efa58..905512993 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -390,7 +390,8 @@ CURLcode ftp_connect(struct connectdata *conn)
 
   if (data->bits.tunnel_thru_httpproxy) {
     /* We want "seamless" FTP operations through HTTP proxy tunnel */
-    result = GetHTTPProxyTunnel(data, data->firstsocket);
+    result = GetHTTPProxyTunnel(data, data->firstsocket,
+                                data->hostname, data->remote_port);
     if(CURLE_OK != result)
       return result;
   }
@@ -769,13 +770,24 @@ CURLcode _ftp(struct connectdata *conn)
 	 failf(data, "Couldn't interpret this 227-reply: %s", buf);
 	 return CURLE_FTP_WEIRD_227_FORMAT;
       }
-      sprintf(newhost, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
-      he = GetHost(data, newhost, hostent_buf, sizeof(hostent_buf));
-      if(!he) {
-        failf(data, "Can't resolve new host %s", newhost);
-        return CURLE_FTP_CANT_GET_HOST;
-      }
 
+      if(data->bits.httpproxy) {
+        /*
+         * This is a tunnel through a http proxy and we need to connect to the
+         * proxy again here. We already have the name info for it since the
+         * previous lookup.
+         */
+        he = conn->hp;
+      }
+      else {
+        /* normal, direct, ftp connection */
+        sprintf(newhost, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+        he = GetHost(data, newhost, hostent_buf, sizeof(hostent_buf));
+        if(!he) {
+          failf(data, "Can't resolve new host %s", newhost);
+          return CURLE_FTP_CANT_GET_HOST;
+        }
+      }
 	
       newport = (port[0]<<8) + port[1];
       data->secondarysocket = socket(AF_INET, SOCK_STREAM, 0);
@@ -783,7 +795,13 @@ CURLcode _ftp(struct connectdata *conn)
       memset((char *) &serv_addr, '\0', sizeof(serv_addr));
       memcpy((char *)&(serv_addr.sin_addr), he->h_addr, he->h_length);
       serv_addr.sin_family = he->h_addrtype;
-      serv_addr.sin_port = htons(newport);
+
+      if(data->bits.httpproxy)
+        /* connect to the http proxy's port number */
+        serv_addr.sin_port = htons(data->port);
+      else
+        /* direct connection to remote host's PASV port */
+        serv_addr.sin_port = htons(newport);
 
       if(data->bits.verbose) {
         struct in_addr in;
@@ -871,7 +889,8 @@ CURLcode _ftp(struct connectdata *conn)
 
       if (data->bits.tunnel_thru_httpproxy) {
         /* We want "seamless" FTP operations through HTTP proxy tunnel */
-        result = GetHTTPProxyTunnel(data, data->secondarysocket);
+        result = GetHTTPProxyTunnel(data, data->secondarysocket,
+                                    newhost, newport);
         if(CURLE_OK != result)
           return result;
       }
diff --git a/lib/http.c b/lib/http.c
index 7d3507ce4..fba4b80cb 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -140,7 +140,8 @@ bool static checkheaders(struct UrlData *data, char *thisheader)
  * this proxy. After that, the socket can be used just as a normal socket.
  */
 
-CURLcode GetHTTPProxyTunnel(struct UrlData *data, int tunnelsocket)
+CURLcode GetHTTPProxyTunnel(struct UrlData *data, int tunnelsocket,
+                            char *hostname, int remote_port)
 {
   int httperror=0;
   int subversion=0;
@@ -153,7 +154,7 @@ CURLcode GetHTTPProxyTunnel(struct UrlData *data, int tunnelsocket)
         "%s"
         "%s"
         "\r\n",
-        data->hostname, data->remote_port,
+        hostname, remote_port,
         (data->bits.proxy_user_passwd)?data->ptr_proxyuserpwd:"",
         (data->useragent?data->ptr_uagent:"")
         );
@@ -197,7 +198,8 @@ CURLcode http_connect(struct connectdata *conn)
   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);
+      result = GetHTTPProxyTunnel(data, data->firstsocket,
+                                  data->hostname, data->remote_port);
       if(CURLE_OK != result)
         return result;
     }
diff --git a/lib/http.h b/lib/http.h
index 4653f6e14..a36366fb2 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -42,7 +42,8 @@
  ****************************************************************************/
 
 /* ftp can use this as well */
-CURLcode GetHTTPProxyTunnel(struct UrlData *data, int tunnelsocket);
+CURLcode GetHTTPProxyTunnel(struct UrlData *data, int tunnelsocket,
+                            char *hostname, int remote_port);
 
 /* protocol-specific functions set up to be called by the main engine */
 CURLcode http(struct connectdata *conn);