/cpw/tomkiewicz/http: 3cb58ea9667c: HTTP Proxy support

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Wed Oct 17 07:47:32 EDT 2012


Changeset: 3cb58ea9667c0ea4f27755d4288bb88ecf10226b
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-10-17 13:47 +0200
Branch:	 default
URL: http://hg.pidgin.im/cpw/tomkiewicz/http/rev/3cb58ea9667c

Description:

HTTP Proxy support

diffstat:

 libpurple/http.c            |  80 ++++++++++++++++++++++++++++++++++++++------
 libpurple/obsolete.c        |   4 ++
 libpurple/protocols/gg/gg.c |  26 ++++++++++++--
 3 files changed, 94 insertions(+), 16 deletions(-)

diffs (214 lines):

diff --git a/libpurple/http.c b/libpurple/http.c
--- a/libpurple/http.c
+++ b/libpurple/http.c
@@ -27,7 +27,9 @@
 #include "http.h"
 
 #include "internal.h"
+
 #include "debug.h"
+#include "ntlm.h"
 
 #define PURPLE_HTTP_URL_CREDENTIALS_CHARS "a-z0-9.,~_/*!&%?=+\\^-"
 #define PURPLE_HTTP_MAX_RECV_BUFFER_LEN 10240
@@ -367,10 +369,14 @@ static void _purple_http_gen_headers(Pur
 {
 	GString *h;
 	PurpleHttpURL *url;
-	PurpleProxyInfo *proxy;
 	const GList *hdr;
 	PurpleHttpRequest *req;
 	PurpleHttpHeaders *hdrs;
+	gchar *request_url, *tmp_url = NULL;
+
+	PurpleProxyInfo *proxy;
+	gboolean proxy_http = FALSE;
+	const gchar *proxy_username, *proxy_password;
 
 	g_return_if_fail(hc != NULL);
 
@@ -383,20 +389,70 @@ static void _purple_http_gen_headers(Pur
 	proxy = purple_proxy_get_setup(hc->gc ?
 		purple_connection_get_account(hc->gc) : NULL);
 
+	proxy_http = (purple_proxy_info_get_type(proxy) == PURPLE_PROXY_HTTP ||
+		purple_proxy_info_get_type(proxy) == PURPLE_PROXY_USE_ENVVAR);
+
 	hc->request_header = h = g_string_new("");
 	hc->request_header_written = 0;
 
+	if (proxy_http)
+		request_url = tmp_url = purple_http_url_print(url);
+	else
+		request_url = url->path;
+
 	g_string_append_printf(h, "%s %s HTTP/%s\r\n",
 		req->method ? req->method : "GET",
-		url->path,
+		request_url,
 		req->http11 ? "1.1" : "1.0");
 
+	if (tmp_url)
+		g_free(tmp_url);
+
 	if (!purple_http_headers_get(hdrs, "host"))
 		g_string_append_printf(h, "Host: %s\r\n", url->host);
 	if (!purple_http_headers_get(hdrs, "connection"))
-		g_string_append_printf(h, "Connection: close\r\n");
+		g_string_append(h, "Connection: close\r\n");
 	if (!purple_http_headers_get(hdrs, "accept"))
-		g_string_append_printf(h, "Accept: */*\r\n");
+		g_string_append(h, "Accept: */*\r\n");
+
+	if (proxy_http)
+		g_string_append(h, "Proxy-Connection: close\r\n");
+
+	proxy_username = purple_proxy_info_get_username(proxy);
+	if (proxy_http && proxy_username != NULL && proxy_username[0] != '\0') {
+		char hostname[256];
+		gchar *proxy_auth, *ntlm_type1, *tmp;
+		int len;
+
+		if (gethostname(hostname, sizeof(hostname)) < 0 ||
+			hostname[0] == '\0') {
+			purple_debug_warning("http", "gethostname() failed "
+				"- is your hostname set?");
+			strcpy(hostname, "localhost");
+		}
+
+		proxy_password = purple_proxy_info_get_password(proxy);
+		if (proxy_password == NULL)
+			proxy_password = "";
+
+		tmp = g_strdup_printf("%s:%s", proxy_username, proxy_password);
+		len = strlen(tmp);
+		proxy_auth = purple_base64_encode((const guchar *)tmp, len);
+		memset(tmp, 0, len);
+		g_free(tmp);
+
+		ntlm_type1 = purple_ntlm_gen_type1(hostname, "");
+
+		g_string_append_printf(h, "Proxy-Authorization: Basic %s\r\n",
+			proxy_auth);
+		g_string_append_printf(h, "Proxy-Authorization: NTLM %s\r\n",
+			ntlm_type1);
+		g_string_append(h, "Proxy-Connection: Close\r\n");
+
+		memset(proxy_auth, 0, strlen(proxy_auth));
+		g_free(proxy_auth);
+		g_free(ntlm_type1);
+	}
 
 	hdr = purple_http_headers_get_all(hdrs);
 	while (hdr) {
@@ -407,13 +463,6 @@ static void _purple_http_gen_headers(Pur
 			kvp->key, (gchar*)kvp->value);
 	}
 
-	if (purple_proxy_info_get_username(proxy) != NULL &&
-		(purple_proxy_info_get_type(proxy) == PURPLE_PROXY_USE_ENVVAR ||
-		purple_proxy_info_get_type(proxy) == PURPLE_PROXY_HTTP)) {
-		purple_debug_error("http",
-			"Proxy authorization is not yet supported\n");
-	}
-
 	g_string_append_printf(h, "\r\n");
 
 	if (purple_debug_is_unsafe() && purple_debug_is_verbose()) {
@@ -470,7 +519,9 @@ static gboolean _purple_http_recv_header
 				return FALSE;
 			}
 			if (purple_debug_is_verbose())
-				purple_debug_misc("http", "Got main header\n");
+				purple_debug_misc("http",
+					"Got main header with code %d\n",
+					hc->response->code);
 		} else {
 			if (purple_debug_is_verbose() &&
 				purple_debug_is_unsafe())
@@ -705,6 +756,11 @@ static void _purple_http_recv(gpointer _
 			g_free(hdrs);
 		}
 
+		if (hc->response->code == 407) {
+			_purple_http_error(hc, _("Invalid proxy credentials"));
+			return;
+		}
+
 		redirect = purple_http_headers_get(hc->response->headers,
 			"location");
 		if (redirect && (hc->request->max_redirects == -1 ||
diff --git a/libpurple/obsolete.c b/libpurple/obsolete.c
--- a/libpurple/obsolete.c
+++ b/libpurple/obsolete.c
@@ -99,6 +99,10 @@ PurpleUtilFetchUrlData * purple_util_fet
 	PurpleUtilFetchUrlData *url_data;
 	PurpleUtilLegacyWrapData *wrap_data;
 
+	if (FALSE)
+		return purple_util_fetch_url_request(NULL, url, full,
+			user_agent, http11, NULL, FALSE, max_len, cb, data);
+
 	wrap_data = g_new0(PurpleUtilLegacyWrapData, 1);
 	url_data = g_new0(PurpleUtilFetchUrlData, 1);
 	request = purple_http_request_new(url);
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -69,8 +69,10 @@ static void ggp_test_http_cb(PurpleHttpC
 //		"successfully" : "without success");
 //	purple_debug_info("http-test", "Returned http code: %d.\n",
 //		purple_http_response_get_code(response));
-//	purple_debug_info("http-test", "Returned error: %s.\n",
-//		purple_http_response_get_error(response));
+
+	if (purple_http_response_get_error(response))
+		purple_debug_info("http-test", "Returned error: %s.\n",
+			purple_http_response_get_error(response));
 
 	data = purple_http_response_get_data(response);
 	if (strlen(data) < 200)
@@ -114,7 +116,7 @@ static void ggp_action_test_http(PurpleP
 	//PurpleHttpConnection *hc;
 	PurpleConnection *gc = (PurpleConnection *)action->context;
 
-
+/*
 	purple_debug_info("http-test", "Testing http...\n");
 	purple_http_get(gc, "http://www.wasilczyk.pl/x_ip_simple.htm",
 		ggp_test_http_cb, NULL);
@@ -129,9 +131,25 @@ static void ggp_action_test_http(PurpleP
 
 	purple_http_get(gc, "http://google.com",
 		ggp_test_http_cb, NULL);
+
+*/
 	purple_http_get(gc, "http://wp.pl",
 		ggp_test_http_cb, NULL);
 
+/*
+	purple_util_fetch_url_request(
+		purple_connection_get_account(gc),
+		"http://wp.pl/",
+		FALSE, // full
+		NULL, // user_agent
+		TRUE, // http11
+		NULL, // request
+		FALSE, // inc headers
+		-1, // max_len
+		ggp_test_http_cb2, NULL);
+*/
+
+/*
 	purple_http_get(gc, "https://www.google.pl",
 		ggp_test_http_cb, NULL);
 
@@ -147,7 +165,7 @@ static void ggp_action_test_http(PurpleP
 	purple_http_request_set_timeout(request, 3);
 	purple_http_request(gc, request, ggp_test_http_cb, NULL);
 	purple_http_request_unref(request);
-
+*/
 	purple_debug_info("http-test", "Testing http started.\n");
 }
 



More information about the Commits mailing list