/pidgin/main: 5b9619d1dec4: Fix dropping incoming stanzas on BOS...

Mark Doliner mark at kingant.net
Tue Jan 28 10:38:13 EST 2014


Changeset: 5b9619d1dec44026d2ee38ec8e8b657429b3c36f
Author:	 Mark Doliner <mark at kingant.net>
Date:	 2014-01-19 21:35 -0800
Branch:	 release-2.x.y
URL: https://hg.pidgin.im/pidgin/main/rev/5b9619d1dec4

Description:

Fix dropping incoming stanzas on BOSH connections when we receive
multiple HTTP responses at once. (#15684)

I'm not very happy with this code, but I believe it has changed significantly
in 3.0.0 so I think it's not worth cleaning.

diffstat:

 ChangeLog                         |   2 ++
 libpurple/protocols/jabber/bosh.c |  37 ++++++++++++++++++++++++++++---------
 2 files changed, 30 insertions(+), 9 deletions(-)

diffs (124 lines):

diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -107,6 +107,8 @@ version 2.10.8:
 	* Fix login errors when the first two available auth mechanisms fail but
 	  a subsequent mechanism would otherwise work when using Cyrus SASL.
 	  (#15524)
+	* Fix dropping incoming stanzas on BOSH connections when we receive
+	  multiple HTTP responses at once. (#15684)
 
 	Yahoo!:
 	* Fix possible crashes handling incoming strings that are not UTF-8.
diff --git a/libpurple/protocols/jabber/bosh.c b/libpurple/protocols/jabber/bosh.c
--- a/libpurple/protocols/jabber/bosh.c
+++ b/libpurple/protocols/jabber/bosh.c
@@ -628,6 +628,7 @@ static void
 http_received_cb(const char *data, int len, PurpleBOSHConnection *conn)
 {
 	xmlnode *node;
+	gchar *message;
 
 	if (conn->failed_connections)
 		/* We've got some data, so reset the number of failed connections */
@@ -637,8 +638,10 @@ http_received_cb(const char *data, int l
 
 	node = xmlnode_from_str(data, len);
 
+	message = g_strndup(data, len);
 	purple_debug_info("jabber", "RecvBOSH %s(%d): %s\n",
-	                  conn->ssl ? "(ssl)" : "", len, data);
+	                  conn->ssl ? "(ssl)" : "", len, message);
+	g_free(message);
 
 	if (node) {
 		conn->receive_cb(conn, node);
@@ -753,7 +756,12 @@ void jabber_bosh_connection_connect(Purp
 	http_connection_connect(conn);
 }
 
-static void
+/**
+ * @return TRUE if we want to be called again immediately. This happens when
+ *         we parse an HTTP response AND there is more data in read_buf. FALSE
+ *         if we should not be called again unless more data has been read.
+ */
+static gboolean
 jabber_bosh_http_connection_process(PurpleHTTPConnection *conn)
 {
 	const char *cursor;
@@ -778,7 +786,7 @@ jabber_bosh_http_connection_process(Purp
 				 * The packet ends in the middle of the Content-Length line.
 				 * We'll try again later when we have more.
 				 */
-				return;
+				return FALSE;
 
 			len = atoi(content_length + strlen("\r\nContent-Length:"));
 			if (len == 0)
@@ -790,7 +798,7 @@ jabber_bosh_http_connection_process(Purp
 		if (connection && (!end_of_headers || connection < end_of_headers)) {
 			const char *tmp;
 			if (strstr(connection, "\r\n") == NULL)
-				return;
+				return FALSE;
 
 
 			tmp = connection + strlen("\r\nConnection:");
@@ -808,17 +816,17 @@ jabber_bosh_http_connection_process(Purp
 			conn->handled_len = end_of_headers - conn->read_buf->str + 4;
 		} else {
 			conn->handled_len = conn->read_buf->len;
-			return;
+			return FALSE;
 		}
 	}
 
 	/* Have we handled everything in the buffer? */
 	if (conn->handled_len >= conn->read_buf->len)
-		return;
+		return FALSE;
 
 	/* Have we read all that the Content-Length promised us? */
 	if (conn->read_buf->len - conn->handled_len < conn->body_len)
-		return;
+		return FALSE;
 
 	--conn->requests;
 	--conn->bosh->requests;
@@ -826,6 +834,14 @@ jabber_bosh_http_connection_process(Purp
 	http_received_cb(conn->read_buf->str + conn->handled_len, conn->body_len,
 	                 conn->bosh);
 
+	/* Is there another response in the buffer ? */
+	if (conn->read_buf->len > conn->body_len + conn->handled_len) {
+		g_string_erase(conn->read_buf, 0, conn->handled_len + conn->body_len);
+		conn->headers_done = FALSE;
+		conn->handled_len = conn->body_len = 0;
+		return TRUE;
+	}
+
 	/* Connection: Close? */
 	if (conn->close && conn->state == HTTP_CONN_CONNECTED) {
 		if (purple_debug_is_verbose())
@@ -844,6 +860,8 @@ jabber_bosh_http_connection_process(Purp
 	conn->read_buf = NULL;
 	conn->headers_done = FALSE;
 	conn->handled_len = conn->body_len = 0;
+
+	return FALSE;
 }
 
 /*
@@ -887,8 +905,9 @@ http_connection_read(PurpleHTTPConnectio
 		/* Process what we do have */
 	}
 
-	if (conn->read_buf->len > 0)
-		jabber_bosh_http_connection_process(conn);
+	if (conn->read_buf->len > 0) {
+		while (jabber_bosh_http_connection_process(conn));
+	}
 }
 
 static void



More information about the Commits mailing list