changeset 25052:0a8484372312

* sending empty <body> requests if there are not othere requests to be answered to keep a CM -> client channel open * reconnect if HTTP connection is closed
author Tobias Markmann <tfar@soc.pidgin.im>
date Mon, 18 Aug 2008 08:42:37 +0000
parents 5f70e13db5cc
children 84ff003a7d33
files libpurple/protocols/jabber/bosh.c libpurple/protocols/jabber/bosh.h
diffstat 2 files changed, 39 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/bosh.c	Sat Aug 16 21:28:32 2008 +0000
+++ b/libpurple/protocols/jabber/bosh.c	Mon Aug 18 08:42:37 2008 +0000
@@ -50,7 +50,7 @@
 	}
 	conn->js = js;
 	conn->rid = rand() % 100000 + 1728679472;
-	
+	conn->ready = FALSE;
 	conn->conn_a = g_new0(PurpleHTTPConnection, 1);
 	jabber_bosh_http_connection_init(conn->conn_a, conn->account, conn->host, conn->port);
 	conn->conn_a->userdata = conn;
@@ -109,6 +109,7 @@
 		if (!strcmp(child->name, "success")) {
 			jabber_bosh_connection_stream_restart(conn);
 			jabber_process_packet(js, &child);
+			conn->ready = TRUE;
 			conn->receive_cb = jabber_bosh_connection_received;
 		} else {
 			js->state = JABBER_STREAM_AUTHENTICATING;
@@ -187,7 +188,7 @@
 	xmlnode_set_attrib(packet, "rid", tmp);
 	g_free(tmp);
 	
-	xmlnode_insert_child(packet, node);
+	if (node) xmlnode_insert_child(packet, node);
 	
 	jabber_bosh_connection_send_native(conn, packet);
 }
@@ -208,9 +209,22 @@
 
 static void jabber_bosh_connection_connected(PurpleHTTPConnection *conn) {
 	PurpleBOSHConnection *bosh_conn = conn->userdata;
-	bosh_conn->receive_cb = jabber_bosh_connection_received;
-	if (bosh_conn->ready && bosh_conn->connect_cb) bosh_conn->connect_cb(bosh_conn);
-	else jabber_bosh_connection_boot(bosh_conn);
+	if (bosh_conn->ready == TRUE && bosh_conn->connect_cb) {
+		purple_debug_info("jabber", "BOSH session already exists. Trying to reuse it.\n");
+		bosh_conn->receive_cb = jabber_bosh_connection_received;
+		bosh_conn->connect_cb(bosh_conn);
+	} else jabber_bosh_connection_boot(bosh_conn);
+}
+
+static void jabber_bosh_connection_refresh(PurpleHTTPConnection *conn) {
+	PurpleBOSHConnection *bosh_conn = conn->userdata;
+	jabber_bosh_connection_send(bosh_conn, NULL);
+}
+
+static void jabber_bosh_http_connection_disconnected(PurpleHTTPConnection *conn) {
+	PurpleBOSHConnection *bosh_conn = conn->userdata;
+	bosh_conn->conn_a->connect_cb = jabber_bosh_connection_connected;
+	jabber_bosh_http_connection_connect(bosh_conn->conn_a);
 }
 
 void jabber_bosh_connection_connect(PurpleBOSHConnection *conn) {
@@ -257,6 +271,7 @@
 	char buffer[1025];
 	int len;
 	PurpleHTTPConnection *conn = data;
+	PurpleBOSHConnection *bosh_conn = conn->userdata;
 	PurpleHTTPResponse *response = conn->current_response;
 	
 	purple_debug_info("jabber", "jabber_bosh_http_connection_receive\n");
@@ -293,19 +308,31 @@
 		if (response) {
 			if (conn->current_len >= response->data_len) {
 				PurpleHTTPRequest *request = g_queue_pop_head(conn->requests);
+				
+				#warning for a pure HTTP 1.1 stack this would be needed to be handled elsewhereƄ
+				if (bosh_conn->ready == TRUE && g_queue_is_empty(conn->requests) == TRUE) {
+					jabber_bosh_connection_send(bosh_conn, NULL); 
+					printf("\n SEND AN EMPTY REQUEST \n");
+				}
+				
 				if (request) {
 					response->data = g_memdup(conn->current_data, response->data_len);
 					request->cb(request, response, conn->userdata);
 					jabber_bosh_http_request_clean(request);
 					jabber_bosh_http_response_clean(response);
 					conn->current_response = NULL;
+					g_free(request);
+					g_free(response);
 				} else {
 					purple_debug_info("jabber", "received HTTP response but haven't requested anything yet.\n");
 				}
 			}
 		}
+	} else if (len == 0) {
+		purple_input_remove(conn->ie_handle);
+		if (conn->disconnect_cb) conn->disconnect_cb(conn);
 	} else {
-		purple_debug_info("jabber", "jabber_bosh_http_connection_receive: problem receiving data\n");
+		purple_debug_info("jabber", "jabber_bosh_http_connection_receive: problem receiving data (%d)\n", len);
 	}
 }
 
@@ -330,8 +357,9 @@
 		return;
 	}
 	conn->fd = source;
+	if (conn->connect_cb) conn->connect_cb(conn);
+	else purple_debug_info("jabber", "No connect callback for HTTP connection.\n");
 	conn->ie_handle = purple_input_add(conn->fd, PURPLE_INPUT_READ, jabber_bosh_http_connection_receive, conn);
-	if (conn->connect_cb) conn->connect_cb(conn);
 }
 
 void jabber_bosh_http_connection_connect(PurpleHTTPConnection *conn) {
@@ -393,6 +421,6 @@
 
 
 void jabber_bosh_http_response_clean(PurpleHTTPResponse *res) {
-	g_hash_table_destroy(res->header);
+	//g_hash_table_destroy(res->header);
 	g_free(res->data);
 }
--- a/libpurple/protocols/jabber/bosh.h	Sat Aug 16 21:28:32 2008 +0000
+++ b/libpurple/protocols/jabber/bosh.h	Mon Aug 18 08:42:37 2008 +0000
@@ -30,6 +30,7 @@
 typedef struct _PurpleBOSHConnection PurpleBOSHConnection;
 
 typedef void (*PurpleHTTPConnectionConnectFunction)(PurpleHTTPConnection *conn);
+typedef void (*PurpleHTTPConnectionDisconnectFunction)(PurpleHTTPConnection *conn);
 typedef void (*PurpleHTTPRequestCallback)(PurpleHTTPRequest *req, PurpleHTTPResponse *res, void *userdata);
 typedef void (*PurpleBOSHConnectionConnectFunction)(PurpleBOSHConnection *conn);
 typedef void (*PurpleBOSHConnectionReciveFunction)(PurpleBOSHConnection *conn, xmlnode *node);
@@ -45,7 +46,7 @@
     int rid;
     char *sid;
     int wait;
-    
+        
     JabberStream *js;
     void *userdata;
     PurpleAccount *account;
@@ -74,6 +75,7 @@
     
     int pih;
     PurpleHTTPConnectionConnectFunction connect_cb;
+    PurpleHTTPConnectionConnectFunction disconnect_cb;
     void *userdata;
 };