/pidgin/main: 3b8ce83bac96: HTTP: get rid of one (of two) msn's ...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Mon Jul 22 12:37:41 EDT 2013


Changeset: 3b8ce83bac9646c8a8756656b62cbf4d0acc74c1
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2013-07-22 18:37 +0200
Branch:	 default
URL: https://hg.pidgin.im/pidgin/main/rev/3b8ce83bac96

Description:

HTTP: get rid of one (of two) msn's own http implementations

diffstat:

 libpurple/http.c                   |   34 +-
 libpurple/protocols/msn/httpconn.c |  947 +++++++++++-------------------------
 libpurple/protocols/msn/httpconn.h |   87 +--
 libpurple/protocols/msn/servconn.c |    5 +-
 libpurple/protocols/msn/servconn.h |    2 +
 libpurple/sslconn.c                |   11 +
 libpurple/sslconn.h                |   10 +
 7 files changed, 391 insertions(+), 705 deletions(-)

diffs (truncated from 1349 to 300 lines):

diff --git a/libpurple/http.c b/libpurple/http.c
--- a/libpurple/http.c
+++ b/libpurple/http.c
@@ -216,6 +216,12 @@ static GList *purple_http_hc_list;
 static GHashTable *purple_http_hc_by_gc;
 
 /**
+ * Keys: pointers to PurpleConnection.
+ * Values: gboolean TRUE.
+ */
+static GHashTable *purple_http_cancelling_gc;
+
+/**
  * Keys: pointers to PurpleHttpConnection.
  * Values: pointers to links in purple_http_hc_list.
  */
@@ -448,6 +454,8 @@ purple_http_socket_dontwatch(PurpleHttpS
 	if (hs->inpa > 0)
 		purple_input_remove(hs->inpa);
 	hs->inpa = 0;
+	if (hs->ssl_connection)
+		purple_ssl_input_remove(hs->ssl_connection);
 }
 
 static void
@@ -1451,6 +1459,13 @@ PurpleHttpConnection * purple_http_reque
 		return NULL;
 	}
 
+	if (g_hash_table_lookup(purple_http_cancelling_gc, gc)) {
+		purple_debug_warning("http", "Cannot perform another HTTP "
+			"request while cancelling all related with this "
+			"PurpleConnection\n");
+		return NULL;
+	}
+
 	hc = purple_http_connection_new(request, gc);
 	hc->callback = callback;
 	hc->user_data = user_data;
@@ -1589,15 +1604,19 @@ void purple_http_conn_cancel_all(PurpleC
 {
 	GList *gc_list = g_hash_table_lookup(purple_http_hc_by_gc, gc);
 
+	g_hash_table_insert(purple_http_cancelling_gc, gc, GINT_TO_POINTER(TRUE));
+
 	while (gc_list) {
 		PurpleHttpConnection *hc = gc_list->data;
 		gc_list = g_list_next(gc_list);
 		purple_http_conn_cancel(hc);
 	}
 
+	g_hash_table_remove(purple_http_cancelling_gc, gc);
+
 	if (NULL != g_hash_table_lookup(purple_http_hc_by_gc, gc))
-		purple_debug_error("http", "Couldn't cancel all connections "
-			"related to gc=%p\n", gc);
+		purple_debug_fatal("http", "Couldn't cancel all connections "
+			"related to gc=%p (it shouldn't happen)\n", gc);
 }
 
 gboolean purple_http_conn_is_running(PurpleHttpConnection *http_conn)
@@ -2011,6 +2030,9 @@ purple_http_keepalive_pool_request(Purpl
 
 	g_free(hash);
 
+	if (purple_debug_is_verbose())
+		purple_debug_misc("http", "locking a socket: %p\n", hs);
+
 	return hs;
 }
 
@@ -2025,6 +2047,9 @@ purple_http_keepalive_pool_release(Purpl
 		return;
 	}
 
+	if (purple_debug_is_verbose())
+		purple_debug_misc("http", "releasing a socket: %p\n", hs);
+
 	purple_http_socket_dontwatch(hs);
 	hs->is_busy = FALSE;
 
@@ -2386,6 +2411,8 @@ gboolean purple_http_response_is_success
 	if (code <= 0)
 		return FALSE;
 
+	/* TODO: HTTP/1.1 100 Continue */
+
 	if (code / 100 == 2)
 		return TRUE;
 
@@ -2797,6 +2824,7 @@ void purple_http_init(void)
 	purple_http_hc_by_ptr = g_hash_table_new(g_direct_hash, g_direct_equal);
 	purple_http_hc_by_gc = g_hash_table_new_full(g_direct_hash,
 		g_direct_equal, NULL, (GDestroyNotify)g_list_free);
+	purple_http_cancelling_gc = g_hash_table_new(g_direct_hash, g_direct_equal);
 }
 
 static void purple_http_foreach_conn_cancel(gpointer _hc, gpointer user_data)
@@ -2829,4 +2857,6 @@ void purple_http_uninit(void)
 	purple_http_hc_by_gc = NULL;
 	g_hash_table_destroy(purple_http_hc_by_ptr);
 	purple_http_hc_by_ptr = NULL;
+	g_hash_table_destroy(purple_http_cancelling_gc);
+	purple_http_cancelling_gc = NULL;
 }
diff --git a/libpurple/protocols/msn/httpconn.c b/libpurple/protocols/msn/httpconn.c
--- a/libpurple/protocols/msn/httpconn.c
+++ b/libpurple/protocols/msn/httpconn.c
@@ -1,5 +1,5 @@
 /**
- * @file httpconn.c HTTP connection method
+ * @file httpconn.h HTTP-tunnelled connections
  *
  * purple
  *
@@ -19,581 +19,88 @@
  *
  * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
  */
-#include "msn.h"
-#include "debug.h"
+
 #include "httpconn.h"
 
-typedef struct
+#include "debug.h"
+#include "http.h"
+
+#include "msn.h"
+
+typedef struct _MsnHttpConnWriteQueueElement MsnHttpConnWriteQueueElement;
+
+struct _MsnHttpConn
 {
-	MsnHttpConn *httpconn;
-	char *body;
-	size_t body_len;
-} MsnHttpQueueData;
+	MsnServConn *servconn;
 
-static void
-msn_httpconn_process_queue(MsnHttpConn *httpconn)
+	gboolean connected;
+	gboolean is_disconnecting;
+	gboolean is_externally_disconnected;
+
+	gchar *host_dest;
+	gchar *host_gw;
+	int port;
+
+	gchar *session_id; /* changes after every request */
+
+	PurpleHttpConnection *current_request;
+	int polling_timer;
+	int finish_timer;
+	PurpleHttpKeepalivePool *keepalive_pool;
+	GSList *write_queue;
+};
+
+struct _MsnHttpConnWriteQueueElement
 {
-	httpconn->waiting_response = FALSE;
+	gchar *data;
+	size_t len;
+};
 
-	if (httpconn->queue != NULL)
-	{
-		MsnHttpQueueData *queue_data;
+static MsnHttpConnWriteQueueElement *
+msn_httpconn_writequeueelement_new(const gchar *data, size_t len)
+{
+	MsnHttpConnWriteQueueElement *wqe;
 
-		queue_data = (MsnHttpQueueData *)httpconn->queue->data;
+	g_return_val_if_fail(!(len > 0 && data == NULL), NULL);
 
-		httpconn->queue = g_list_remove(httpconn->queue, queue_data);
+	wqe = g_new(MsnHttpConnWriteQueueElement, 1);
+	wqe->data = g_memdup(data, len);
+	wqe->len = len;
 
-		msn_httpconn_write(queue_data->httpconn,
-						   queue_data->body,
-						   queue_data->body_len);
-
-		g_free(queue_data->body);
-		g_free(queue_data);
-	}
-}
-
-static gboolean
-msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf,
-						size_t size, char **ret_buf, size_t *ret_size,
-						gboolean *error)
-{
-	const char *s, *c;
-	char *header, *body;
-	const char *body_start;
-	char *tmp;
-	size_t body_len = 0;
-
-	g_return_val_if_fail(httpconn != NULL, FALSE);
-	g_return_val_if_fail(buf      != NULL, FALSE);
-	g_return_val_if_fail(size      > 0,    FALSE);
-	g_return_val_if_fail(ret_buf  != NULL, FALSE);
-	g_return_val_if_fail(ret_size != NULL, FALSE);
-	g_return_val_if_fail(error    != NULL, FALSE);
-
-#if 0
-	purple_debug_info("msn", "HTTP: parsing data {%s}\n", buf);
-#endif
-
-	/* Healthy defaults. */
-	body = NULL;
-
-	*ret_buf  = NULL;
-	*ret_size = 0;
-	*error    = FALSE;
-
-	/* First, some tests to see if we have a full block of stuff. */
-	if (((strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) &&
-		 (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) != 0)) &&
-		((strncmp(buf, "HTTP/1.0 200 OK\r\n", 17) != 0) &&
-		 (strncmp(buf, "HTTP/1.0 100 Continue\r\n", 23) != 0)))
-	{
-		*error = TRUE;
-
-		return FALSE;
-	}
-
-	if (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) == 0)
-	{
-		if ((s = strstr(buf, "\r\n\r\n")) == NULL)
-			return FALSE;
-
-		s += 4;
-
-		if (*s == '\0')
-		{
-			*ret_buf = g_strdup("");
-			*ret_size = 0;
-
-			msn_httpconn_process_queue(httpconn);
-
-			return TRUE;
-		}
-
-		size -= (s - buf);
-		buf = s;
-	}
-
-	if ((s = strstr(buf, "\r\n\r\n")) == NULL)
-		/* Need to wait for the full HTTP header to arrive */
-		return FALSE;
-
-	s += 4; /* Skip \r\n\r\n */
-	header = g_strndup(buf, s - buf);
-	body_start = s;
-	body_len = size - (body_start - buf);
-
-	if ((s = purple_strcasestr(header, "Content-Length: ")) != NULL)
-	{
-		int tmp_len;
-
-		s += strlen("Content-Length: ");
-
-		if ((c = strchr(s, '\r')) == NULL)
-		{
-			g_free(header);
-
-			return FALSE;
-		}
-
-		tmp = g_strndup(s, c - s);
-		tmp_len = atoi(tmp);
-		g_free(tmp);
-
-		if (body_len != tmp_len)
-		{
-			/* Need to wait for the full packet to arrive */
-
-			g_free(header);
-
-#if 0
-			purple_debug_warning("msn",
-							   "body length (%d) != content length (%d)\n",
-							   body_len, tmp_len);
-#endif
-
-			return FALSE;
-		}
-	}
-
-	body = g_malloc(body_len + 1);
-	memcpy(body, body_start, body_len);
-	body[body_len] = '\0';



More information about the Commits mailing list