/cpw/tomkiewicz/http: 9919d10ee405: Make old http-related code o...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Fri Oct 12 16:53:00 EDT 2012


Changeset: 9919d10ee405fbcfdd5063d33a120d48d48b08e2
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-10-12 22:52 +0200
Branch:	 default
URL: http://hg.pidgin.im/cpw/tomkiewicz/http/rev/9919d10ee405

Description:

Make old http-related code obsolete

diffstat:

 finch/plugins/gnttinyurl.c                  |    1 +
 libpurple/Makefile.am                       |    2 +
 libpurple/obsolete.c                        |  707 ++++++++++++++++++++++++++++
 libpurple/obsolete.h                        |  110 ++++
 libpurple/protocols/gg/avatar.c             |    1 +
 libpurple/protocols/gg/oauth/oauth-purple.c |    1 +
 libpurple/protocols/gg/pubdir-prpl.c        |    1 +
 libpurple/protocols/jabber/google/relay.c   |    1 +
 libpurple/protocols/jabber/jabber.c         |    1 +
 libpurple/protocols/jabber/useravatar.c     |    1 +
 libpurple/protocols/msn/msn.c               |    1 +
 libpurple/protocols/msn/session.c           |    1 +
 libpurple/protocols/msn/slp.c               |    1 +
 libpurple/protocols/mxit/formcmds.c         |    1 +
 libpurple/protocols/mxit/login.c            |    1 +
 libpurple/protocols/mxit/markup.c           |    1 +
 libpurple/protocols/mxit/protocol.c         |    1 +
 libpurple/protocols/myspace/user.h          |    2 +
 libpurple/protocols/oscar/oscar.h           |    1 +
 libpurple/protocols/yahoo/libymsg.c         |    1 +
 libpurple/protocols/yahoo/yahoo_aliases.c   |    1 +
 libpurple/protocols/yahoo/yahoo_picture.c   |    1 +
 libpurple/protocols/yahoo/yahoo_profile.c   |    1 +
 libpurple/upnp.c                            |    1 +
 libpurple/util.c                            |  681 --------------------------
 libpurple/util.h                            |   70 --
 pidgin/gtkprefs.c                           |    1 +
 pidgin/gtksmiley.c                          |    1 +
 pidgin/gtkstatusbox.c                       |    1 +
 pidgin/plugins/relnot.c                     |    1 +
 30 files changed, 845 insertions(+), 751 deletions(-)

diffs (truncated from 1911 to 300 lines):

diff --git a/finch/plugins/gnttinyurl.c b/finch/plugins/gnttinyurl.c
--- a/finch/plugins/gnttinyurl.c
+++ b/finch/plugins/gnttinyurl.c
@@ -21,6 +21,7 @@
 
 #include "internal.h"
 #include <glib.h>
+#include "obsolete.h"
 
 #define PLUGIN_STATIC_NAME	TinyURL
 #define PREFS_BASE          "/plugins/gnt/tinyurl"
diff --git a/libpurple/Makefile.am b/libpurple/Makefile.am
--- a/libpurple/Makefile.am
+++ b/libpurple/Makefile.am
@@ -65,6 +65,7 @@ purple_coresources = \
 	network.c \
 	ntlm.c \
 	notify.c \
+	obsolete.c \
 	plugin.c \
 	pluginpref.c \
 	pounce.c \
@@ -283,6 +284,7 @@ libpurple_la_SOURCES = \
 
 noinst_HEADERS= \
 	internal.h \
+	obsolete.h \
 	media/backend-fs2.h \
 	valgrind.h
 
diff --git a/libpurple/obsolete.c b/libpurple/obsolete.c
new file mode 100644
--- /dev/null
+++ b/libpurple/obsolete.c
@@ -0,0 +1,707 @@
+/* purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301 USA
+ */
+
+#include "obsolete.h"
+
+#include "internal.h"
+#include "debug.h"
+#include "ntlm.h"
+
+struct _PurpleUtilFetchUrlData
+{
+	PurpleUtilFetchUrlCallback callback;
+	void *user_data;
+
+	struct
+	{
+		char *user;
+		char *passwd;
+		char *address;
+		int port;
+		char *page;
+
+	} website;
+
+	char *url;
+	int num_times_redirected;
+	gboolean full;
+	char *user_agent;
+	gboolean http11;
+	char *request;
+	gsize request_written;
+	gboolean include_headers;
+
+	gboolean is_ssl;
+	PurpleSslConnection *ssl_connection;
+	PurpleProxyConnectData *connect_data;
+	int fd;
+	guint inpa;
+
+	gboolean got_headers;
+	gboolean has_explicit_data_len;
+	char *webdata;
+	gsize len;
+	unsigned long data_len;
+	gssize max_len;
+	gboolean chunked;
+	PurpleAccount *account;
+};
+
+/**
+ * The arguments to this function are similar to printf.
+ */
+static void
+purple_util_fetch_url_error(PurpleUtilFetchUrlData *gfud, const char *format, ...)
+{
+	gchar *error_message;
+	va_list args;
+
+	va_start(args, format);
+	error_message = g_strdup_vprintf(format, args);
+	va_end(args);
+
+	gfud->callback(gfud, gfud->user_data, NULL, 0, error_message);
+	g_free(error_message);
+	purple_util_fetch_url_cancel(gfud);
+}
+
+static void url_fetch_connect_cb(gpointer url_data, gint source, const gchar *error_message);
+static void ssl_url_fetch_connect_cb(gpointer data, PurpleSslConnection *ssl_connection, PurpleInputCondition cond);
+static void ssl_url_fetch_error_cb(PurpleSslConnection *ssl_connection, PurpleSslErrorType error, gpointer data);
+
+static gboolean
+parse_redirect(const char *data, size_t data_len,
+			   PurpleUtilFetchUrlData *gfud)
+{
+	gchar *s;
+	gchar *new_url, *temp_url, *end;
+	gboolean full;
+	int len;
+
+	if ((s = g_strstr_len(data, data_len, "\nLocation: ")) == NULL)
+		/* We're not being redirected */
+		return FALSE;
+
+	s += strlen("Location: ");
+	end = strchr(s, '\r');
+
+	/* Just in case :) */
+	if (end == NULL)
+		end = strchr(s, '\n');
+
+	if (end == NULL)
+		return FALSE;
+
+	len = end - s;
+
+	new_url = g_malloc(len + 1);
+	strncpy(new_url, s, len);
+	new_url[len] = '\0';
+
+	full = gfud->full;
+
+	if (*new_url == '/' || g_strstr_len(new_url, len, "://") == NULL)
+	{
+		temp_url = new_url;
+
+		new_url = g_strdup_printf("%s:%d%s", gfud->website.address,
+								  gfud->website.port, temp_url);
+
+		g_free(temp_url);
+
+		full = FALSE;
+	}
+
+	purple_debug_info("util", "Redirecting to %s\n", new_url);
+
+	gfud->num_times_redirected++;
+	if (gfud->num_times_redirected >= 5)
+	{
+		purple_util_fetch_url_error(gfud,
+				_("Could not open %s: Redirected too many times"),
+				gfud->url);
+		return TRUE;
+	}
+
+	/*
+	 * Try again, with this new location.  This code is somewhat
+	 * ugly, but we need to reuse the gfud because whoever called
+	 * us is holding a reference to it.
+	 */
+	g_free(gfud->url);
+	gfud->url = new_url;
+	gfud->full = full;
+	g_free(gfud->request);
+	gfud->request = NULL;
+
+	if (gfud->is_ssl) {
+		gfud->is_ssl = FALSE;
+		purple_ssl_close(gfud->ssl_connection);
+		gfud->ssl_connection = NULL;
+	} else {
+		purple_input_remove(gfud->inpa);
+		gfud->inpa = 0;
+		close(gfud->fd);
+		gfud->fd = -1;
+	}
+	gfud->request_written = 0;
+	gfud->len = 0;
+	gfud->data_len = 0;
+
+	g_free(gfud->website.user);
+	g_free(gfud->website.passwd);
+	g_free(gfud->website.address);
+	g_free(gfud->website.page);
+	purple_url_parse(new_url, &gfud->website.address, &gfud->website.port,
+				   &gfud->website.page, &gfud->website.user, &gfud->website.passwd);
+
+	if (purple_strcasestr(new_url, "https://") != NULL) {
+		gfud->is_ssl = TRUE;
+		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, gfud->account,
+				gfud->website.address, gfud->website.port,
+				url_fetch_connect_cb, gfud);
+	}
+
+	if (gfud->ssl_connection == NULL && gfud->connect_data == NULL)
+	{
+		purple_util_fetch_url_error(gfud, _("Unable to connect to %s"),
+				gfud->website.address);
+	}
+
+	return TRUE;
+}
+
+static const char *
+find_header_content(const char *data, size_t data_len, const char *header, size_t header_len)
+{
+	const char *p = NULL;
+
+	if (header_len <= 0)
+		header_len = strlen(header);
+
+	/* Note: data is _not_ nul-terminated.  */
+	if (data_len > header_len) {
+		if (header[0] == '\n')
+			p = (g_ascii_strncasecmp(data, header + 1, header_len - 1) == 0) ? data : NULL;
+		if (!p)
+			p = purple_strcasestr(data, header);
+		if (p)
+			p += header_len;
+	}
+
+	/* If we can find the header at all, try to sscanf it.
+	 * Response headers should end with at least \r\n, so sscanf is safe,
+	 * if we make sure that there is indeed a \n in our header.
+	 */
+	if (p && g_strstr_len(p, data_len - (p - data), "\n")) {
+		return p;
+	}
+
+	return NULL;
+}
+
+static size_t
+parse_content_len(const char *data, size_t data_len)
+{
+	size_t content_len = 0;
+	const char *p = NULL;
+
+	p = find_header_content(data, data_len, "\nContent-Length: ", sizeof("\nContent-Length: ") - 1);
+	if (p) {
+		sscanf(p, "%" G_GSIZE_FORMAT, &content_len);
+		purple_debug_misc("util", "parsed %" G_GSIZE_FORMAT "\n", content_len);
+	}
+
+	return content_len;
+}
+
+static gboolean
+content_is_chunked(const char *data, size_t data_len)
+{
+	const char *p = find_header_content(data, data_len, "\nTransfer-Encoding: ", sizeof("\nTransfer-Encoding: ") - 1);
+	if (p && g_ascii_strncasecmp(p, "chunked", 7) == 0)
+		return TRUE;
+
+	return FALSE;
+}
+
+/* Process in-place */
+static void
+process_chunked_data(char *data, gsize *len)
+{
+	gsize sz;
+	gsize newlen = 0;
+	char *p = data;
+	char *s = data;
+
+	while (*s) {
+		/* Read the size of this chunk */
+		if (sscanf(s, "%" G_GSIZE_MODIFIER "x", &sz) != 1)
+		{
+			purple_debug_error("util", "Error processing chunked data: "
+					"Expected data length, found: %s\n", s);
+			break;



More information about the Commits mailing list