mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
[svn] Use the CONNECT method to establish passthrough over SSL traffic
over proxies.
This commit is contained in:
parent
7c063c3175
commit
76b59b1ad7
@ -1,3 +1,8 @@
|
|||||||
|
2003-11-28 Hrvoje Niksic <hniksic@xemacs.org>
|
||||||
|
|
||||||
|
* http.c (gethttp): Use the CONNECT handle to establish SSL
|
||||||
|
passthrough through non-SSL proxies.
|
||||||
|
|
||||||
2003-11-28 Hrvoje Niksic <hniksic@xemacs.org>
|
2003-11-28 Hrvoje Niksic <hniksic@xemacs.org>
|
||||||
|
|
||||||
* init.c: Don't #include netinet/Winsock stuff.
|
* init.c: Don't #include netinet/Winsock stuff.
|
||||||
|
189
src/http.c
189
src/http.c
@ -804,7 +804,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
|||||||
authenticate_h = NULL;
|
authenticate_h = NULL;
|
||||||
auth_tried_already = 0;
|
auth_tried_already = 0;
|
||||||
|
|
||||||
inhibit_keep_alive = !opt.http_keep_alive || proxy != NULL;
|
inhibit_keep_alive = !opt.http_keep_alive;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
/* We need to come back here when the initial attempt to retrieve
|
/* We need to come back here when the initial attempt to retrieve
|
||||||
@ -825,21 +825,72 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
|||||||
hs->remote_time = NULL;
|
hs->remote_time = NULL;
|
||||||
hs->error = NULL;
|
hs->error = NULL;
|
||||||
|
|
||||||
/* If we're using a proxy, we will be connecting to the proxy
|
conn = u;
|
||||||
server. */
|
|
||||||
conn = proxy ? proxy : u;
|
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");
|
||||||
|
|
||||||
|
/* If we're using a proxy, we will be connecting to the proxy
|
||||||
|
server. */
|
||||||
|
conn = proxy;
|
||||||
|
}
|
||||||
|
|
||||||
host_lookup_failed = 0;
|
host_lookup_failed = 0;
|
||||||
|
sock = -1;
|
||||||
|
|
||||||
/* First: establish the connection. */
|
/* First: establish the connection. */
|
||||||
if (inhibit_keep_alive
|
|
||||||
|| !persistent_available_p (conn->host, conn->port,
|
if (!inhibit_keep_alive)
|
||||||
|
{
|
||||||
|
/* Look for a persistent connection to target host, unless a
|
||||||
|
proxy is used. The exception is when SSL is in use, in which
|
||||||
|
case the proxy is nothing but a passthrough to the target
|
||||||
|
host, registered as a connection to the latter. */
|
||||||
|
struct url *relevant = conn;
|
||||||
#ifdef HAVE_SSL
|
#ifdef HAVE_SSL
|
||||||
u->scheme == SCHEME_HTTPS
|
if (u->scheme == SCHEME_HTTPS)
|
||||||
#else
|
relevant = u;
|
||||||
0
|
|
||||||
#endif
|
#endif
|
||||||
, &host_lookup_failed))
|
|
||||||
|
if (persistent_available_p (relevant->host, relevant->port,
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
relevant->scheme == SCHEME_HTTPS,
|
||||||
|
#else
|
||||||
|
0,
|
||||||
|
#endif
|
||||||
|
&host_lookup_failed))
|
||||||
|
{
|
||||||
|
sock = pconn.socket;
|
||||||
|
using_ssl = pconn.ssl;
|
||||||
|
logprintf (LOG_VERBOSE, _("Reusing existing connection to %s:%d.\n"),
|
||||||
|
pconn.host, pconn.port);
|
||||||
|
DEBUGP (("Reusing fd %d.\n", sock));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock < 0)
|
||||||
{
|
{
|
||||||
/* In its current implementation, persistent_available_p will
|
/* In its current implementation, persistent_available_p will
|
||||||
look up conn->host in some cases. If that lookup failed, we
|
look up conn->host in some cases. If that lookup failed, we
|
||||||
@ -855,28 +906,75 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
|||||||
? CONERROR : CONIMPOSSIBLE);
|
? CONERROR : CONIMPOSSIBLE);
|
||||||
|
|
||||||
#ifdef HAVE_SSL
|
#ifdef HAVE_SSL
|
||||||
if (conn->scheme == SCHEME_HTTPS)
|
if (proxy && u->scheme == SCHEME_HTTPS)
|
||||||
{
|
{
|
||||||
if (!ssl_connect (sock))
|
/* When requesting SSL URLs through proxies, use the
|
||||||
{
|
CONNECT method to request passthrough. */
|
||||||
logputs (LOG_VERBOSE, "\n");
|
char *connect =
|
||||||
logprintf (LOG_NOTQUIET,
|
(char *) alloca (64
|
||||||
_("Unable to establish SSL connection.\n"));
|
+ strlen (u->host)
|
||||||
fd_close (sock);
|
+ (proxyauth ? strlen (proxyauth) : 0));
|
||||||
return CONSSLERR;
|
sprintf (connect, "CONNECT %s:%d HTTP/1.0\r\n%s\r\n",
|
||||||
}
|
u->host, u->port, proxyauth ? proxyauth : "");
|
||||||
using_ssl = 1;
|
DEBUGP (("Writing to proxy: [%s]\n", connect));
|
||||||
}
|
write_error = fd_write (sock, connect, strlen (connect), -1);
|
||||||
|
if (write_error < 0)
|
||||||
|
{
|
||||||
|
xfree_null (proxyauth);
|
||||||
|
logprintf (LOG_VERBOSE, _("Failed writing to proxy: %s.\n"),
|
||||||
|
strerror (errno));
|
||||||
|
CLOSE_INVALIDATE (sock);
|
||||||
|
return WRITEFAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
head = fd_read_http_head (sock);
|
||||||
|
if (!head)
|
||||||
|
{
|
||||||
|
xfree_null (proxyauth);
|
||||||
|
logprintf (LOG_VERBOSE, _("Failed reading proxy response: %s\n"),
|
||||||
|
strerror (errno));
|
||||||
|
CLOSE_INVALIDATE (sock);
|
||||||
|
return HERR;
|
||||||
|
}
|
||||||
|
message = NULL;
|
||||||
|
if (!*head)
|
||||||
|
{
|
||||||
|
xfree (head);
|
||||||
|
goto failed_tunnel;
|
||||||
|
}
|
||||||
|
DEBUGP (("proxy responded with: [%s]\n", head));
|
||||||
|
|
||||||
|
resp = response_new (head);
|
||||||
|
statcode = response_status (resp, &message);
|
||||||
|
response_free (resp);
|
||||||
|
if (statcode != 200)
|
||||||
|
{
|
||||||
|
failed_tunnel:
|
||||||
|
xfree_null (proxyauth);
|
||||||
|
logprintf (LOG_NOTQUIET, _("Proxy tunneling failed: %s"),
|
||||||
|
message ? message : "?");
|
||||||
|
xfree_null (message);
|
||||||
|
return CONSSLERR;
|
||||||
|
}
|
||||||
|
xfree (message);
|
||||||
|
|
||||||
|
/* SOCK is now *really* connected to u->host, so update CONN
|
||||||
|
to reflect this. That way register_persistent will
|
||||||
|
register SOCK as being connected to u->host:u->port. */
|
||||||
|
conn = u;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn->scheme == SCHEME_HTTPS)
|
||||||
|
{
|
||||||
|
if (!ssl_connect (sock))
|
||||||
|
{
|
||||||
|
fd_close (sock);
|
||||||
|
return CONSSLERR;
|
||||||
|
}
|
||||||
|
using_ssl = 1;
|
||||||
|
}
|
||||||
#endif /* HAVE_SSL */
|
#endif /* HAVE_SSL */
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
logprintf (LOG_VERBOSE, _("Reusing existing connection to %s:%d.\n"),
|
|
||||||
pconn.host, pconn.port);
|
|
||||||
sock = pconn.socket;
|
|
||||||
using_ssl = pconn.ssl;
|
|
||||||
DEBUGP (("Reusing fd %d.\n", sock));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*dt & HEAD_ONLY)
|
if (*dt & HEAD_ONLY)
|
||||||
command = "HEAD";
|
command = "HEAD";
|
||||||
@ -964,32 +1062,6 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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. */
|
/* String of the form :PORT. Used only for non-standard ports. */
|
||||||
port_maybe = NULL;
|
port_maybe = NULL;
|
||||||
if (u->port != scheme_default_port (u->scheme))
|
if (u->port != scheme_default_port (u->scheme))
|
||||||
@ -1141,10 +1213,7 @@ Accept: %s\r\n\
|
|||||||
return HERR;
|
return HERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DEBUGP (("\n---response begin---\n%s---response end---\n", head));
|
||||||
DEBUGP (("\n---response begin---\n"));
|
|
||||||
DEBUGP (("%s", head));
|
|
||||||
DEBUGP (("---response end---\n"));
|
|
||||||
|
|
||||||
resp = response_new (head);
|
resp = response_new (head);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user