/cpw/tomkiewicz/http: b890f231e15f: Request headers support, wra...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Tue Oct 16 13:37:21 EDT 2012


Changeset: b890f231e15f810be52e1616e4ad1be8d70c3d97
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-10-16 19:37 +0200
Branch:	 default
URL: http://hg.pidgin.im/cpw/tomkiewicz/http/rev/b890f231e15f

Description:

Request headers support, wrapping new API with legacy purple_util_fetch_url

diffstat:

 libpurple/http.c            |  81 ++++++++++++++++++++++++++++++++++++++++-----
 libpurple/obsolete.c        |  62 ++++++++++++++++++++++++++++++++++
 libpurple/obsolete.h        |   6 +-
 libpurple/protocols/gg/gg.c |  13 +++---
 4 files changed, 144 insertions(+), 18 deletions(-)

diffs (299 lines):

diff --git a/libpurple/http.c b/libpurple/http.c
--- a/libpurple/http.c
+++ b/libpurple/http.c
@@ -54,6 +54,7 @@ struct _PurpleHttpRequest
 	int ref_count;
 
 	gchar *url;
+	PurpleHttpHeaders *headers;
 
 	int max_redirects;
 	gboolean http11;
@@ -174,21 +175,50 @@ static void purple_http_headers_add(Purp
 {
 	PurpleKeyValuePair *kvp;
 	GList *named_values, *new_values;
+	gchar *key_low;
 
 	g_return_if_fail(hdrs != NULL);
 	g_return_if_fail(key != NULL);
 	g_return_if_fail(value != NULL);
 
 	kvp = g_new0(PurpleKeyValuePair, 1);
-	kvp->key = g_ascii_strdown(key, -1);
-	key = kvp->key;
+	kvp->key = g_strdup(key);
 	kvp->value = g_strdup(value);
 	hdrs->list = g_list_append(hdrs->list, kvp);
 
-	named_values = g_hash_table_lookup(hdrs->by_name, key);
+	key_low = g_ascii_strdown(key, -1);
+	named_values = g_hash_table_lookup(hdrs->by_name, key_low);
 	new_values = g_list_append(named_values, kvp->value);
-	if (!named_values)
-		g_hash_table_insert(hdrs->by_name, g_strdup(key), new_values);
+	if (named_values)
+		g_free(key_low);
+	else
+		g_hash_table_insert(hdrs->by_name, key_low, new_values);
+}
+
+static void purple_http_headers_remove(PurpleHttpHeaders *hdrs,
+	const gchar *key)
+{
+	GList *it, *curr;
+
+	g_return_if_fail(hdrs != NULL);
+	g_return_if_fail(key != NULL);
+
+	if (!g_hash_table_remove(hdrs->by_name, key))
+		return;
+
+	/* Could be optimized to O(1). */
+	it = g_list_first(hdrs->list);
+	while (it)
+	{
+		PurpleKeyValuePair *kvp = it->data;
+		curr = it;
+		it = g_list_next(it);
+		if (g_ascii_strcasecmp(kvp->key, key) != 0)
+			continue;
+
+		hdrs->list = g_list_delete_link(hdrs->list, curr);
+		purple_http_headers_free_kvp(kvp);
+	}
 }
 
 static const GList * purple_http_headers_get_all(PurpleHttpHeaders *hdrs)
@@ -303,6 +333,7 @@ static void _purple_http_gen_headers(Pur
 	GString *h;
 	PurpleHttpURL *url;
 	PurpleProxyInfo *proxy;
+	const GList *hdr;
 
 	g_return_if_fail(hc != NULL);
 
@@ -318,12 +349,22 @@ static void _purple_http_gen_headers(Pur
 
 	g_string_append_printf(h, "GET %s HTTP/%s\r\n", url->path,
 		hc->request->http11 ? "1.1" : "1.0");
-	g_string_append_printf(h, "Host: %s\r\n", url->host);
-	g_string_append_printf(h, "Connection: close\r\n");
 
-	/* TODO: don't put here, if exists */
-	g_string_append_printf(h, "Accept: */*\r\n");
+	if (!purple_http_headers_get(hc->request->headers, "host"))
+		g_string_append_printf(h, "Host: %s\r\n", url->host);
+	if (!purple_http_headers_get(hc->request->headers, "connection"))
+		g_string_append_printf(h, "Connection: close\r\n");
+	if (!purple_http_headers_get(hc->request->headers, "accept"))
+		g_string_append_printf(h, "Accept: */*\r\n");
 
+	hdr = purple_http_headers_get_all(hc->request->headers);
+	while (hdr) {
+		PurpleKeyValuePair *kvp = hdr->data;
+		hdr = g_list_next(hdr);
+
+		g_string_append_printf(h, "%s: %s\r\n",
+			kvp->key, (gchar*)kvp->value);
+	}
 
 	if (purple_proxy_info_get_username(proxy) != NULL &&
 		(purple_proxy_info_get_type(proxy) == PURPLE_PROXY_USE_ENVVAR ||
@@ -971,6 +1012,7 @@ PurpleHttpRequest * purple_http_request_
 
 	request->ref_count = 1;
 	request->url = g_strdup(url);
+	request->headers = purple_http_headers_new();
 
 	request->max_redirects = PURPLE_HTTP_REQUEST_DEFAULT_MAX_REDIRECTS;
 	request->http11 = TRUE;
@@ -980,6 +1022,7 @@ PurpleHttpRequest * purple_http_request_
 
 static void purple_http_request_free(PurpleHttpRequest *request)
 {
+	purple_http_headers_free(request->headers);
 	g_free(request->url);
 	g_free(request);
 }
@@ -1055,6 +1098,26 @@ int purple_http_request_get_max_len(Purp
 	return request->max_length;
 }
 
+void purple_http_request_header_set(PurpleHttpRequest *request,
+	const gchar *key, const gchar *value)
+{
+	g_return_if_fail(request != NULL);
+	g_return_if_fail(key != NULL);
+
+	purple_http_headers_remove(request->headers, key);
+	if (value)
+		purple_http_headers_add(request->headers, key, value);
+}
+
+void purple_http_request_header_add(PurpleHttpRequest *request,
+	const gchar *key, const gchar *value)
+{
+	g_return_if_fail(request != NULL);
+	g_return_if_fail(key != NULL);
+
+	purple_http_headers_add(request->headers, key, value);
+}
+
 /*** HTTP response API ********************************************************/
 
 static PurpleHttpResponse * purple_http_response_new(void)
diff --git a/libpurple/obsolete.c b/libpurple/obsolete.c
--- a/libpurple/obsolete.c
+++ b/libpurple/obsolete.c
@@ -23,6 +23,7 @@
 
 #include "internal.h"
 #include "debug.h"
+#include "http.h"
 #include "ntlm.h"
 
 struct _PurpleUtilFetchUrlData
@@ -63,8 +64,63 @@ struct _PurpleUtilFetchUrlData
 	gssize max_len;
 	gboolean chunked;
 	PurpleAccount *account;
+
+	PurpleHttpConnection *wrapped_request;
+	gboolean cancelled;
 };
 
+typedef struct
+{
+	PurpleUtilFetchUrlData *url_data;
+	PurpleUtilFetchUrlCallback cb;
+	gpointer user_data;
+} PurpleUtilLegacyWrapData;
+
+static void purple_util_fetch_url_cb(PurpleHttpConnection *http_conn,
+	PurpleHttpResponse *response, gpointer _wrap_data)
+{
+	PurpleUtilLegacyWrapData *wrap_data = _wrap_data;
+
+	if (wrap_data->cb && !wrap_data->url_data->cancelled)
+		wrap_data->cb(wrap_data->url_data, wrap_data->user_data,
+			purple_http_response_get_data(response),
+			purple_http_response_get_data_len(response),
+			purple_http_response_get_error(response));
+
+	g_free(wrap_data->url_data);
+	g_free(wrap_data);
+}
+
+PurpleUtilFetchUrlData * purple_util_fetch_url(const gchar *url, gboolean full,
+	const gchar *user_agent, gboolean http11, gssize max_len,
+	PurpleUtilFetchUrlCallback cb, gpointer data)
+{
+	PurpleHttpRequest *request;
+	PurpleUtilFetchUrlData *url_data;
+	PurpleUtilLegacyWrapData *wrap_data;
+
+	wrap_data = g_new0(PurpleUtilLegacyWrapData, 1);
+	url_data = g_new0(PurpleUtilFetchUrlData, 1);
+	request = purple_http_request_new(url);
+
+	wrap_data->url_data = url_data;
+	wrap_data->cb = cb;
+	wrap_data->user_data = data;
+
+	if (user_agent)
+		purple_http_request_header_set(request,
+			"User-Agent", user_agent);
+	purple_http_request_set_http11(request, http11);
+	purple_http_request_set_max_len(request, max_len);
+
+	url_data->wrapped_request = purple_http_request(NULL, request,
+		purple_util_fetch_url_cb, wrap_data);
+
+	purple_http_request_unref(request);
+
+	return url_data;
+}
+
 /**
  * The arguments to this function are similar to printf.
  */
@@ -682,6 +738,12 @@ purple_util_fetch_url_request(PurpleAcco
 void
 purple_util_fetch_url_cancel(PurpleUtilFetchUrlData *gfud)
 {
+	if (gfud->wrapped_request != NULL) {
+		gfud->cancelled = TRUE;
+		purple_http_conn_cancel(gfud->wrapped_request);
+		return;
+	}
+
 	if (gfud->ssl_connection != NULL)
 		purple_ssl_close(gfud->ssl_connection);
 
diff --git a/libpurple/obsolete.h b/libpurple/obsolete.h
--- a/libpurple/obsolete.h
+++ b/libpurple/obsolete.h
@@ -69,9 +69,9 @@ typedef void (*PurpleUtilFetchUrlCallbac
  * @param cb         The callback function.
  * @param data       The user data to pass to the callback function.
  */
-#define purple_util_fetch_url(url, full, user_agent, http11, max_len, cb, data) \
-	purple_util_fetch_url_request(NULL, url, full, user_agent, http11, NULL, \
-		FALSE, max_len, cb, data);
+PurpleUtilFetchUrlData * purple_util_fetch_url(const gchar *url, gboolean full,
+	const gchar *user_agent, gboolean http11, gssize max_len,
+	PurpleUtilFetchUrlCallback cb, gpointer data);
 
 /**
  * Fetches the data from a URL, and passes it to a callback function.
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
@@ -58,6 +58,7 @@
 #include <http.h>
 #include <obsolete.h>
 
+/*
 static void ggp_test_http_cb(PurpleHttpConnection *http_conn,
 	PurpleHttpResponse *response, gpointer user_data)
 {
@@ -84,8 +85,8 @@ static void ggp_test_http_cb(PurpleHttpC
 		g_free(data_tail);
 	}
 }
+*/
 
-/*
 static void ggp_test_http_cb2(PurpleUtilFetchUrlData *url_data,
 	gpointer user_data, const gchar *url_text, gsize len,
 	const gchar *error_message)
@@ -108,7 +109,6 @@ static void ggp_test_http_cb2(PurpleUtil
 		g_free(data_tail);
 	}
 }
-*/
 
 static void ggp_action_test_http(PurplePluginAction *action)
 {
@@ -141,15 +141,16 @@ static void ggp_action_test_http(PurpleP
 //		ggp_test_http_cb, NULL);
 
 //	purple_util_fetch_url("https://www.google.pl",
-//		TRUE, NULL, TRUE, -1, ggp_test_http_cb2, NULL);
+	purple_util_fetch_url("http://wp.pl",
+		TRUE, "My Browser", TRUE, -1, ggp_test_http_cb2, NULL);
 
 
-	request = purple_http_request_new("http://wp.pl");
+//	request = purple_http_request_new("http://wp.pl");
 //	purple_http_request_set_http11(request, FALSE);
 //	purple_http_request_set_max_redirects(request, 1);
 //	purple_http_request_set_max_len(request, 0);
-	purple_http_request(gc, request, ggp_test_http_cb, NULL);
-	purple_http_request_unref(request);
+//	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