Mercurial > pidgin
changeset 30187:a414593d0a78
Attempt to improve handling of HTTP requests on port 80 when there is a HTTP
proxy that requires authentication involved.
This also has a fix to make sure that we continue to use the same proxy when
we are redirected to an alternative URL.
I'm tempted to create a purple_proxy_append_proxy_auth_headers(), but that
would have to wait until 2.8.0.
Refs #11986.
Refs #11908.
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Mon, 14 Jun 2010 22:09:12 +0000 |
parents | 670ab0006c61 |
children | 3a627563ca71 |
files | libpurple/util.c |
diffstat | 1 files changed, 61 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/util.c Mon Jun 14 00:08:25 2010 +0000 +++ b/libpurple/util.c Mon Jun 14 22:09:12 2010 +0000 @@ -28,6 +28,7 @@ #include "core.h" #include "debug.h" #include "notify.h" +#include "ntlm.h" #include "prpl.h" #include "prefs.h" #include "util.h" @@ -69,6 +70,7 @@ unsigned long data_len; gssize max_len; gboolean chunked; + PurpleAccount *account; }; static char *custom_user_dir = NULL; @@ -3619,11 +3621,11 @@ if (purple_strcasestr(new_url, "https://") != NULL) { gfud->is_ssl = TRUE; - gfud->ssl_connection = purple_ssl_connect(NULL, + gfud->ssl_connection = purple_ssl_connect(gfud->account, gfud->website.address, gfud->website.port, ssl_url_fetch_connect_cb, ssl_url_fetch_error_cb, gfud); } else { - gfud->connect_data = purple_proxy_connect(NULL, NULL, + gfud->connect_data = purple_proxy_connect(NULL, gfud->account, gfud->website.address, gfud->website.port, url_fetch_connect_cb, gfud); } @@ -3915,36 +3917,68 @@ gfud = data; - if (gfud->request == NULL) - { + if (gfud->request == NULL) { + + PurpleProxyInfo *gpi = purple_proxy_get_setup(gfud->account); + GString *request_str = g_string_new(NULL); + + g_string_append_printf(request_str, "GET %s%s HTTP/%s\r\n" + "Connection: close\r\n", + (gfud->full ? "" : "/"), + (gfud->full ? (gfud->url ? gfud->url : "") : (gfud->website.page ? gfud->website.page : "")), + (gfud->http11 ? "1.1" : "1.0")); + + if (gfud->user_agent) + g_string_append_printf(request_str, "User-Agent: %s\r\n", gfud->user_agent); + /* Host header is not forbidden in HTTP/1.0 requests, and HTTP/1.1 * clients must know how to handle the "chunked" transfer encoding. * Purple doesn't know how to handle "chunked", so should always send * the Host header regardless, to get around some observed problems */ - if (gfud->user_agent) { - gfud->request = g_strdup_printf( - "GET %s%s HTTP/%s\r\n" - "Connection: close\r\n" - "User-Agent: %s\r\n" - "Accept: */*\r\n" - "Host: %s\r\n\r\n", - (gfud->full ? "" : "/"), - (gfud->full ? (gfud->url ? gfud->url : "") : (gfud->website.page ? gfud->website.page : "")), - (gfud->http11 ? "1.1" : "1.0"), - (gfud->user_agent ? gfud->user_agent : ""), - (gfud->website.address ? gfud->website.address : "")); - } else { - gfud->request = g_strdup_printf( - "GET %s%s HTTP/%s\r\n" - "Connection: close\r\n" - "Accept: */*\r\n" - "Host: %s\r\n\r\n", - (gfud->full ? "" : "/"), - (gfud->full ? (gfud->url ? gfud->url : "") : (gfud->website.page ? gfud->website.page : "")), - (gfud->http11 ? "1.1" : "1.0"), - (gfud->website.address ? gfud->website.address : "")); + g_string_append_printf(request_str, "Accept: */*\r\n" + "Host: %s\r\n", + (gfud->website.address ? gfud->website.address : "")); + + if (purple_proxy_info_get_username(gpi) != NULL + && (purple_proxy_info_get_type(gpi) == PURPLE_PROXY_USE_ENVVAR + || purple_proxy_info_get_type(gpi) == PURPLE_PROXY_HTTP)) { + /* This chunk of code was copied from proxy.c http_start_connect_tunneling() + * This is really a temporary hack - we need a more complete proxy handling solution, + * so I didn't think it was worthwhile to refactor for reuse + */ + char *t1, *t2, *ntlm_type1; + char hostname[256]; + int ret; + + ret = gethostname(hostname, sizeof(hostname)); + hostname[sizeof(hostname) - 1] = '\0'; + if (ret < 0 || hostname[0] == '\0') { + purple_debug_warning("util", "proxy - gethostname() failed -- is your hostname set?"); + strcpy(hostname, "localhost"); + } + + t1 = g_strdup_printf("%s:%s", + purple_proxy_info_get_username(gpi), + purple_proxy_info_get_password(gpi) ? + purple_proxy_info_get_password(gpi) : ""); + t2 = purple_base64_encode((const guchar *)t1, strlen(t1)); + g_free(t1); + + ntlm_type1 = purple_ntlm_gen_type1(hostname, ""); + + g_string_append_printf(request_str, + "Proxy-Authorization: Basic %s\r\n" + "Proxy-Authorization: NTLM %s\r\n" + "Proxy-Connection: Keep-Alive\r\n", + t2, ntlm_type1); + g_free(ntlm_type1); + g_free(t2); } + + g_string_append(request_str, "\r\n"); + + gfud->request = g_string_free(request_str, FALSE); } if(purple_debug_is_unsafe()) @@ -4083,6 +4117,7 @@ gfud->include_headers = include_headers; gfud->fd = -1; gfud->max_len = max_len; + gfud->account = account; purple_url_parse(url, &gfud->website.address, &gfud->website.port, &gfud->website.page, &gfud->website.user, &gfud->website.passwd);