[Sent this to wget-patches a while ago, but I'm not sure if it got through]

Right now, wget doesn't support HTTPS through proxies, as to do this it
needs to do a CONNECT method and pass through the actual request, 
rather then just depending on the proxy to do the right thing.

I've attached a patch (against the latest CVS tree) that will add support 
for this under wget.  It works for me.  (It's not as clean as it could be 
because it duplicates a little bit of code, but I'm not sure of any way 
around this without majorly rewriting http.c)  


? patchthis
? src/patch
Index: src/http.c
===================================================================
RCS file: /pack/anoncvs/wget/src/http.c,v
retrieving revision 1.94
diff -u -r1.94 http.c
--- src/http.c  2002/05/18 02:16:22     1.94
+++ src/http.c  2002/11/11 22:54:33
@@ -766,19 +766,128 @@
 
       if (sock < 0)
        return errno == ECONNREFUSED ? CONREFUSED : CONERROR;
+ 
+/* I moved this up here since we may need to provde this to the proxy even
+for a CONNECT */
+      proxyauth = NULL;
+      if (proxy)
+        {
+          char *proxy_user, *proxy_passwd;
+          /* For normal username and password, URL components override
+            command-line/wgetrc parameters.  With proxy authentication,
+            it's the reverse, because proxy URLs are normally the
+            "permanent" ones, so command-line args should take
+            precedence.  */
+          if (opt.proxy_user && opt.proxy_passwd)
+           {
+             proxy_user = opt.proxy_user;
+             proxy_passwd = opt.proxy_passwd;
+           }
+          else
+           {
+             proxy_user = proxy->user;
+             proxy_passwd = proxy->passwd;
+           }
+      /* #### This does not appear right.  Can't the proxy request,
+         say, `Digest' authentication?  */
+          if (proxy_user && proxy_passwd)
+           proxyauth = basic_authentication_encode (proxy_user, proxy_passwd,
+                                                    "Proxy-Authorization");
+       }
 
 #ifdef HAVE_SSL
-     if (conn->scheme == SCHEME_HTTPS)
-       if (connect_ssl (&ssl, ssl_ctx,sock) != 0)
-        {
-          logputs (LOG_VERBOSE, "\n");
-          logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n"));
-          ssl_printerrors ();
-          CLOSE (sock);
-          return CONSSLERR;
-        }
+     if (u->scheme==SCHEME_HTTPS) 
+       {
+         conn=u;  /* at this point, we will be passing through, so the
+                    important connection is u */
+         if(proxy)
+          {
+/* If we have a proxy and SSL, we need to use CONNECT, which basically is
+passthru mode, and THEN we need to initialise an SSL connection.  So, I've
+put a request here...
+Note that this scheme will NOT support using https:// proxies.  Does anyone
+use such a thing?  */
+             request= (char *)xmalloc(32+strlen(u->host)+
+                                        +(proxyauth ? strlen(proxyauth) : 0));
+ /* we don't use port_maybe as it is not always set.  We always need to 
+    supply the port to the CONNECT.  */
+             sprintf (request, "CONNECT %s:%d HTTP/1.0\r\n%s\r\n",
+                     u->host,u->port, proxyauth ? proxyauth : "");
+             write_error = iwrite (sock, request, strlen (request));
+            if (write_error < 0)
+               {
+                 logprintf (LOG_VERBOSE,_("Failed writing HTTP request: %s.\n"),
+                strerror (errno));
+                 CLOSE_INVALIDATE (sock);
+                 return WRITEFAILED;
+                }
+             logprintf (LOG_VERBOSE,_("%s request sent, awaiting response... "),
+            proxy ? "Connect" : "HTTP");
+             xfree(request);
+            rbuf_initialize (&rbuf, sock);
+            /* Go through the results.  Even though proxies send legit
+               responses, We really only care about the HTTP/1.0 200 Ok
+              */
+            while(1) 
+              {
+                char *hdr;
+                int hcount;
+                int status;
+                hcount++;
+                status = header_get (&rbuf, &hdr,
+                             (hcount == 1 ? HG_NO_CONTINUATIONS : HG_NONE));
+                 if ((status == HG_ERROR)||(status==HG_EOF))
+                  {
+                    logputs (LOG_VERBOSE, "\n");
+                    logprintf (LOG_NOTQUIET,_("Read error (%s) in headers.\n"),
+                               strerror (errno));
+                    xfree (hdr);
+                    CLOSE_INVALIDATE (sock);
+                    return HERR;
+                  } 
+                else
+                  /* Check for status line.  */
+                   if (hcount == 1)
+                    {
+                      const char *error;
+                       /* Parse the first line of server response.  */
+                      statcode = parse_http_status_line (hdr, &error);
+                      hs->statcode = statcode;
+                      /* Store the descriptive response.  */
+                      if (statcode == -1) /* malformed response */
+                        {
+                          if (!*hdr)
+                            hs->error = xstrdup (_("No data received"));
+                          else
+                            hs->error = xstrdup (_("Malformed status line"));
+                          xfree (hdr);
+                            break;
+                        }
+                      else if (!*error)
+                        hs->error = xstrdup (_("(no description)"));
+                      else
+                        hs->error = xstrdup (error);
+      /* Exit on empty header.  */
+                  }
+                if (!*hdr)
+                  {
+                     xfree (hdr);
+                     break;
+                  }
+               }
+           }
+        if (connect_ssl (&ssl, ssl_ctx,sock) != 0)
+          {
+            logputs (LOG_VERBOSE, "\n");
+            logprintf (LOG_NOTQUIET,  
+                       _("Unable to establish SSL connection.\n"));
+            ssl_printerrors ();
+            CLOSE (sock);
+            return CONSSLERR;
+          }
+       }
 #endif /* HAVE_SSL */
-    }
+  }
   else
     {
       logprintf (LOG_VERBOSE, _("Reusing connection to %s:%hu.\n"),
@@ -878,32 +987,6 @@
        }
     }
 
-  proxyauth = NULL;
-  if (proxy)
-    {
-      char *proxy_user, *proxy_passwd;
-      /* For normal username and password, URL components override
-        command-line/wgetrc parameters.  With proxy authentication,
-        it's the reverse, because proxy URLs are normally the
-        "permanent" ones, so command-line args should take
-        precedence.  */
-      if (opt.proxy_user && opt.proxy_passwd)
-       {
-         proxy_user = opt.proxy_user;
-         proxy_passwd = opt.proxy_passwd;
-       }
-      else
-       {
-         proxy_user = proxy->user;
-         proxy_passwd = proxy->passwd;
-       }
-      /* #### This does not appear right.  Can't the proxy request,
-         say, `Digest' authentication?  */
-      if (proxy_user && proxy_passwd)
-       proxyauth = basic_authentication_encode (proxy_user, proxy_passwd,
-                                                "Proxy-Authorization");
-    }
-
   /* String of the form :PORT.  Used only for non-standard ports. */
   port_maybe = NULL;
   if (u->port != scheme_default_port (u->scheme))
@@ -957,6 +1040,7 @@
 
   if (strchr (u->host, ':'))
     squares_around_host = 1;
+
 
   /* Allocate the memory for the request.  */
   request = (char *)alloca (strlen (command)

Reply via email to