diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/IO/Url.h | 2 | ||||
-rw-r--r-- | src/IO/http.c | 51 | ||||
-rw-r--r-- | src/capi.c | 15 |
3 files changed, 65 insertions, 3 deletions
diff --git a/src/IO/Url.h b/src/IO/Url.h index d57e9251..f144bfad 100644 --- a/src/IO/Url.h +++ b/src/IO/Url.h @@ -16,6 +16,8 @@ extern void a_Http_freeall(void); int a_Http_init(void); int a_Http_proxy_auth(void); void a_Http_set_proxy_passwd(const char *str); +char *a_Http_make_connect_str(const DilloUrl *url); +const char *a_Http_get_proxy_urlstr(); Dstr *a_Http_make_query_str(const DilloUrl *url, bool_t use_proxy); void a_Http_ccc (int Op, int Branch, int Dir, ChainLink *Info, diff --git a/src/IO/http.c b/src/IO/http.c index 55ba3502..ae87c8d0 100644 --- a/src/IO/http.c +++ b/src/IO/http.c @@ -16,6 +16,7 @@ #include <config.h> +#include <ctype.h> /* isdigit */ #include <unistd.h> #include <errno.h> /* for errno */ #include <stdlib.h> @@ -415,6 +416,56 @@ static int Http_must_use_proxy(const DilloUrl *url) } /* + * Return a new string for the request used to tunnel HTTPS through a proxy. + * As of 2009, the best reference appears to be section 5 of RFC 2817. + */ +char *a_Http_make_connect_str(const DilloUrl *url) +{ + Dstr *dstr; + const char *auth1; + int auth_len; + char *auth2, *proxy_auth, *retstr; + + dReturn_val_if_fail(Http_must_use_proxy(url), NULL); + + dstr = dStr_new(""); + auth1 = URL_AUTHORITY(url); + auth_len = strlen(auth1); + if (auth_len > 0 && !isdigit(auth1[auth_len - 1])) + /* if no port number, add HTTPS port */ + auth2 = dStrconcat(auth1, ":443", NULL); + else + auth2 = dStrdup(auth1); + proxy_auth = HTTP_Proxy_Auth_base64 ? + dStrconcat ("Proxy-Authorization: Basic ", + HTTP_Proxy_Auth_base64, "\r\n", NULL) : + dStrdup(""); + dStr_sprintfa( + dstr, + "CONNECT %s HTTP/1.1\r\n" + "Host: %s\r\n" + "%s" + "\r\n", + auth2, + auth2, + proxy_auth); + + dFree(auth2); + dFree(proxy_auth); + retstr = dstr->str; + dStr_free(dstr, 0); + return retstr; +} + +/* + * Return URL string of HTTP proxy, if any + */ +const char *a_Http_get_proxy_urlstr() +{ + return HTTP_Proxy ? URL_STR(HTTP_Proxy) : NULL; +} + +/* * Callback function for the DNS resolver. * Continue connecting the socket, or abort upon error condition. * S->web is checked to assert the operation wasn't aborted while waiting. @@ -265,7 +265,6 @@ static int Capi_url_uses_dpi(DilloUrl *url, char **server_ptr) /* * Build the dpip command tag, according to URL and server. - * TODO: make it PROXY-aware (AFAIS, it should be easy) */ static char *Capi_dpi_build_cmd(DilloWeb *web, char *server) { @@ -273,10 +272,20 @@ static char *Capi_dpi_build_cmd(DilloWeb *web, char *server) if (strcmp(server, "proto.https") == 0) { /* Let's be kind and make the HTTP query string for the dpi */ + char *proxy_connect = a_Http_make_connect_str(web->url); Dstr *http_query = a_Http_make_query_str(web->url, FALSE); /* BUG: embedded NULLs in query data will truncate message */ - cmd = a_Dpip_build_cmd("cmd=%s url=%s query=%s", - "open_url", URL_STR(web->url), http_query->str); + if (proxy_connect) { + const char *proxy_urlstr = a_Http_get_proxy_urlstr(); + cmd = a_Dpip_build_cmd("cmd=%s proxy_url=%s proxy_connect=%s " + "url=%s query=%s", "open_url", proxy_urlstr, + proxy_connect, URL_STR(web->url), + http_query->str); + } else { + cmd = a_Dpip_build_cmd("cmd=%s url=%s query=%s", + "open_url", URL_STR(web->url),http_query->str); + } + dFree(proxy_connect); dStr_free(http_query, 1); } else if (strcmp(server, "downloads") == 0) { |