pidgin: 88aea2f7: jabber: Handle the connection: close hea...

darkrain42 at pidgin.im darkrain42 at pidgin.im
Mon Jan 10 00:25:43 EST 2011


----------------------------------------------------------------------
Revision: 88aea2f701d6cff5efc151d40ef06257da67cf3d
Parent:   d193c88637acb911483fc65a94ba352d61e64de3
Author:   darkrain42 at pidgin.im
Date:     01/10/11 00:19:11
Branch:   im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/88aea2f701d6cff5efc151d40ef06257da67cf3d

Changelog: 

jabber: Handle the connection: close header.  Closes #13008

We should also look for HTTP/1.0.

Changes against parent d193c88637acb911483fc65a94ba352d61e64de3

  patched  ChangeLog
  patched  libpurple/protocols/jabber/bosh.c

-------------- next part --------------
============================================================
--- ChangeLog	92b08030df6113f4b2da511e55091cc704d88c6c
+++ ChangeLog	06afffe8e7f1c7eb7c5e25e3f7005def54979795
@@ -43,6 +43,8 @@ version 2.7.10 (??/??/????):
 	XMPP:
 	* Don't crash when receiving an unexpected/invalid jingle transport type.
 	  (Nikita Kozlov) (#13136)
+	* Handle Connection: Close headers for BOSH, when the server does not
+	  terminate the connection itself. (#13008)
 
 	Yahoo!/Yahoo! JAPAN:
 	* Fix a crash when an account disconnects before a p2p session is
============================================================
--- libpurple/protocols/jabber/bosh.c	0a4594a451a6060b07bef8d97fffbea050956105
+++ libpurple/protocols/jabber/bosh.c	a748bd8ba14dc895052aae71ab42e4800895980c
@@ -108,7 +108,7 @@ struct _PurpleHTTPConnection {
 	int requests; /* number of outstanding HTTP requests */
 
 	gboolean headers_done;
-
+	gboolean close;
 };
 
 static void
@@ -454,6 +454,25 @@ jabber_bosh_connection_send_keepalive(Pu
 	send_timer_cb(bosh);
 }
 
+static void
+jabber_bosh_disable_pipelining(PurpleBOSHConnection *bosh)
+{
+	/* Do nothing if it's already disabled */
+	if (!bosh->pipelining)
+		return;
+
+	bosh->pipelining = FALSE;
+	if (bosh->connections[1] == NULL) {
+		bosh->connections[1] = jabber_bosh_http_connection_init(bosh);
+		http_connection_connect(bosh->connections[1]);
+	} else {
+		/* Shouldn't happen; this should be the only place pipelining
+		 * is turned off.
+		 */
+		g_warn_if_reached();
+	}
+}
+
 static void jabber_bosh_connection_received(PurpleBOSHConnection *conn, xmlnode *node) {
 	xmlnode *child;
 	JabberStream *js = conn->js;
@@ -634,6 +653,7 @@ connection_common_established_cb(PurpleH
 		g_string_free(conn->read_buf, TRUE);
 		conn->read_buf = NULL;
 	}
+	conn->close = FALSE;
 	conn->headers_done = FALSE;
 	conn->handled_len = conn->body_len = 0;
 
@@ -686,16 +706,7 @@ static void http_connection_disconnected
 
 	if (conn->bosh->pipelining) {
 		/* Hmmmm, fall back to multiple connections */
-		conn->bosh->pipelining = FALSE;
-		if (conn->bosh->connections[1] == NULL) {
-			conn->bosh->connections[1] = jabber_bosh_http_connection_init(conn->bosh);
-			http_connection_connect(conn->bosh->connections[1]);
-		} else {
-			/* Shouldn't happen; this should be the only place pipelining
-			 * is turned off.
-			 */
-			g_warn_if_reached();
-		}
+		jabber_bosh_disable_pipelining(conn->bosh);
 	}
 
 	if (++conn->bosh->failed_connections == MAX_FAILED_CONNECTIONS) {
@@ -724,9 +735,13 @@ jabber_bosh_http_connection_process(Purp
 
 	cursor = conn->read_buf->str + conn->handled_len;
 
-	/* TODO: Chunked encoding :/ */
+	if (purple_debug_is_verbose())
+		purple_debug_misc("jabber", "BOSH server sent: %s\n", cursor);
+
+	/* TODO: Chunked encoding and check response version :/ */
 	if (!conn->headers_done) {
 		const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length:");
+		const char *connection = purple_strcasestr(cursor, "\r\nConnection:");
 		const char *end_of_headers = strstr(cursor, "\r\n\r\n");
 
 		/* Make sure Content-Length is in headers, not body */
@@ -747,6 +762,22 @@ jabber_bosh_http_connection_process(Purp
 			conn->body_len = len;
 		}
 
+		if (connection && (!end_of_headers || content_length < end_of_headers)) {
+			const char *tmp;
+			if (strstr(connection, "\r\n") == NULL)
+				return;
+
+
+			tmp = connection + strlen("\r\nConnection:");
+			while (*tmp && (*tmp == ' ' || *tmp == '\t'))
+				++tmp;
+
+			if (!g_ascii_strncasecmp(tmp, "close", strlen("close"))) {
+				conn->close = TRUE;
+				jabber_bosh_disable_pipelining(conn->bosh);
+			}
+		}
+
 		if (end_of_headers) {
 			conn->headers_done = TRUE;
 			conn->handled_len = end_of_headers - conn->read_buf->str + 4;
@@ -771,6 +802,14 @@ jabber_bosh_http_connection_process(Purp
 	http_received_cb(conn->read_buf->str + conn->handled_len, conn->body_len,
 	                 conn->bosh);
 
+	/* Connection: Close? */
+	if (conn->close && conn->state == HTTP_CONN_CONNECTED) {
+		if (purple_debug_is_verbose())
+			purple_debug_misc("jabber", "bosh (%p), server sent Connection: "
+			                            "close\n", conn);
+		http_connection_disconnected(conn);
+	}
+
 	if (conn->bosh->state == BOSH_CONN_ONLINE &&
 			(conn->bosh->requests == 0 || conn->bosh->pending->bufused > 0)) {
 		purple_debug_misc("jabber", "BOSH: Sending an empty request\n");


More information about the Commits mailing list