[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)