cpw.darkrain42.xmpp.bosh: 9900ca1c: Obey the 'inactivity' attribute and send...

paul at darkrain42.org paul at darkrain42.org
Sun Mar 22 23:11:06 EDT 2009


-----------------------------------------------------------------
Revision: 9900ca1ceb2075d4056575e40cfe7317e2e7eee9
Ancestor: 30bb050ab53b27773ea02b00208843265f0487a9
Author: paul at darkrain42.org
Date: 2009-03-16T06:32:55
Branch: im.pidgin.cpw.darkrain42.xmpp.bosh
URL: http://d.pidgin.im/viewmtn/revision/info/9900ca1ceb2075d4056575e40cfe7317e2e7eee9

Modified files:
        libpurple/protocols/jabber/bosh.c

ChangeLog: 

Obey the 'inactivity' attribute and send blank updates often enough. Also,
when receiving a reply from the server, if we have data to send, send it.

This is pretty clunky, as it currently triggers about two seconds before
the keepalive ping. Left a TODO in the code regarding that.

-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/bosh.c	9c2f61a237f834bc23317b1dc3d5ff91963ac392
+++ libpurple/protocols/jabber/bosh.c	76a639109ba11a3f1ae217a0020c1632ef64388e
@@ -58,6 +58,8 @@ struct _PurpleBOSHConnection {
     gboolean pipelining;
 	PurpleHTTPConnection *connections[MAX_HTTP_CONNECTIONS];
 
+	unsigned int inactivity_timer;
+
 	int max_inactivity;
 	int max_requests;
 	int requests;
@@ -190,6 +192,9 @@ jabber_bosh_connection_destroy(PurpleBOS
 	g_free(conn->host);
 	g_free(conn->path);
 
+	if (conn->inactivity_timer)
+		purple_timeout_remove(conn->inactivity_timer);
+
 	if (conn->pending)
 		g_string_free(conn->pending, TRUE);
 
@@ -225,6 +230,15 @@ static gboolean jabber_bosh_connection_e
 	return FALSE;
 }
 
+static gboolean
+bosh_inactivity_cb(gpointer data)
+{
+	PurpleBOSHConnection *bosh = data;
+
+	jabber_bosh_connection_send(bosh, NULL);
+	return TRUE;
+}
+
 static void jabber_bosh_connection_received(PurpleBOSHConnection *conn, xmlnode *node) {
 	xmlnode *child;
 	JabberStream *js = conn->js;
@@ -319,8 +333,19 @@ static void boot_response_cb(PurpleBOSHC
 		purple_debug_info("jabber", "Missing version in BOSH initiation\n");
 	}
 
-	if (inactivity)
+	if (inactivity) {
 		conn->max_inactivity = atoi(inactivity);
+		if (conn->max_inactivity <= 2) {
+			purple_debug_warning("jabber", "Ignoring bogusly small inactivity: %s\n",
+			                     inactivity);
+			conn->max_inactivity = 0;
+		} else {
+			/* TODO: Integrate this with jabber.c keepalive checks... */
+			conn->inactivity_timer = purple_timeout_add_seconds(
+					conn->max_inactivity - 2 /* rounding */, bosh_inactivity_cb,
+					conn);
+		}
+	}
 
 	if (requests)
 		conn->max_requests = atoi(requests);
@@ -594,15 +619,15 @@ jabber_bosh_http_connection_process(Purp
 	--conn->requests;
 	--conn->bosh->requests;
 
-#warning For a pure HTTP 1.1 stack, this would need to be handled elsewhere.
-	if (conn->bosh->ready && conn->bosh->requests == 0) {
+	http_received_cb(conn->buf->str + conn->handled_len, conn->body_len,
+	                 conn->bosh);
+
+	if (conn->bosh->ready &&
+			(conn->bosh->requests == 0 || conn->bosh->pending->len)) {
 		jabber_bosh_connection_send(conn->bosh, NULL);
 		purple_debug_misc("jabber", "BOSH: Sending an empty request\n");
 	}
 
-	http_received_cb(conn->buf->str + conn->handled_len, conn->body_len,
-	                 conn->bosh);
-
 	g_string_free(conn->buf, TRUE);
 	conn->buf = NULL;
 	conn->headers_done = FALSE;
@@ -682,26 +707,25 @@ http_connection_send_request(PurpleHTTPC
 static void
 http_connection_send_request(PurpleHTTPConnection *conn, const GString *req)
 {
-	GString *packet = g_string_new("");
+	char *packet;
 	int ret;
 
-	g_string_printf(packet, "POST %s HTTP/1.1\r\n"
+	packet = g_strdup_printf("POST %s HTTP/1.1\r\n"
 	                       "Host: %s\r\n"
 	                       "User-Agent: %s\r\n"
 	                       "Content-Encoding: text/xml; charset=utf-8\r\n"
-	                       "Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n",
+	                       "Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n"
+	                       "%s",
 	                       conn->bosh->path, conn->bosh->host, bosh_useragent,
-	                       req->len);
+	                       req->len, req->str);
 
-	packet = g_string_append(packet, req->str);
-
 	/* TODO: Better error handling, circbuffer or possible integration with
 	 * low-level code in jabber.c */
-	ret = write(conn->fd, packet->str, packet->len);
+	ret = write(conn->fd, packet, strlen(packet));
 
 	++conn->requests;
 	++conn->bosh->requests;
-	g_string_free(packet, TRUE);
+	g_free(packet);
 
 	if (ret < 0 && errno == EAGAIN)
 		purple_debug_error("jabber", "BOSH write would have blocked\n");


More information about the Commits mailing list