changeset 25995:e995540378f0

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.
author Paul Aurich <paul@darkrain42.org>
date Mon, 16 Mar 2009 06:32:55 +0000
parents a94b28023bf6
children 349e411da2ce
files libpurple/protocols/jabber/bosh.c
diffstat 1 files changed, 38 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/bosh.c	Mon Mar 16 02:45:53 2009 +0000
+++ b/libpurple/protocols/jabber/bosh.c	Mon Mar 16 06:32:55 2009 +0000
@@ -58,6 +58,8 @@
     gboolean pipelining;
 	PurpleHTTPConnection *connections[MAX_HTTP_CONNECTIONS];
 
+	unsigned int inactivity_timer;
+
 	int max_inactivity;
 	int max_requests;
 	int requests;
@@ -190,6 +192,9 @@
 	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 @@
 	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 @@
 		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 @@
 	--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 @@
 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);
-
-	packet = g_string_append(packet, req->str);
+	                       req->len, 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");