comparison libpurple/protocols/jabber/bosh.c @ 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 8badac6cc7c9
comparison
equal deleted inserted replaced
25051:5f70e13db5cc 25052:0a8484372312
48 if (conn->user || conn->passwd) { 48 if (conn->user || conn->passwd) {
49 purple_debug_info("jabber", "Sorry, HTTP Authentication isn't supported yet. Username and password in the BOSH URL will be ignored.\n"); 49 purple_debug_info("jabber", "Sorry, HTTP Authentication isn't supported yet. Username and password in the BOSH URL will be ignored.\n");
50 } 50 }
51 conn->js = js; 51 conn->js = js;
52 conn->rid = rand() % 100000 + 1728679472; 52 conn->rid = rand() % 100000 + 1728679472;
53 53 conn->ready = FALSE;
54 conn->conn_a = g_new0(PurpleHTTPConnection, 1); 54 conn->conn_a = g_new0(PurpleHTTPConnection, 1);
55 jabber_bosh_http_connection_init(conn->conn_a, conn->account, conn->host, conn->port); 55 jabber_bosh_http_connection_init(conn->conn_a, conn->account, conn->host, conn->port);
56 conn->conn_a->userdata = conn; 56 conn->conn_a->userdata = conn;
57 } 57 }
58 58
107 if (child != NULL && child->type == XMLNODE_TYPE_TAG) { 107 if (child != NULL && child->type == XMLNODE_TYPE_TAG) {
108 JabberStream *js = conn->js; 108 JabberStream *js = conn->js;
109 if (!strcmp(child->name, "success")) { 109 if (!strcmp(child->name, "success")) {
110 jabber_bosh_connection_stream_restart(conn); 110 jabber_bosh_connection_stream_restart(conn);
111 jabber_process_packet(js, &child); 111 jabber_process_packet(js, &child);
112 conn->ready = TRUE;
112 conn->receive_cb = jabber_bosh_connection_received; 113 conn->receive_cb = jabber_bosh_connection_received;
113 } else { 114 } else {
114 js->state = JABBER_STREAM_AUTHENTICATING; 115 js->state = JABBER_STREAM_AUTHENTICATING;
115 jabber_process_packet(js, &child); 116 jabber_process_packet(js, &child);
116 } 117 }
185 xmlnode_set_attrib(packet, "sid", conn->sid); 186 xmlnode_set_attrib(packet, "sid", conn->sid);
186 tmp = g_strdup_printf("%d", conn->rid); 187 tmp = g_strdup_printf("%d", conn->rid);
187 xmlnode_set_attrib(packet, "rid", tmp); 188 xmlnode_set_attrib(packet, "rid", tmp);
188 g_free(tmp); 189 g_free(tmp);
189 190
190 xmlnode_insert_child(packet, node); 191 if (node) xmlnode_insert_child(packet, node);
191 192
192 jabber_bosh_connection_send_native(conn, packet); 193 jabber_bosh_connection_send_native(conn, packet);
193 } 194 }
194 195
195 void jabber_bosh_connection_send_native(PurpleBOSHConnection *conn, xmlnode *node) { 196 void jabber_bosh_connection_send_native(PurpleBOSHConnection *conn, xmlnode *node) {
206 jabber_bosh_http_connection_send_request(conn->conn_a, request); 207 jabber_bosh_http_connection_send_request(conn->conn_a, request);
207 } 208 }
208 209
209 static void jabber_bosh_connection_connected(PurpleHTTPConnection *conn) { 210 static void jabber_bosh_connection_connected(PurpleHTTPConnection *conn) {
210 PurpleBOSHConnection *bosh_conn = conn->userdata; 211 PurpleBOSHConnection *bosh_conn = conn->userdata;
211 bosh_conn->receive_cb = jabber_bosh_connection_received; 212 if (bosh_conn->ready == TRUE && bosh_conn->connect_cb) {
212 if (bosh_conn->ready && bosh_conn->connect_cb) bosh_conn->connect_cb(bosh_conn); 213 purple_debug_info("jabber", "BOSH session already exists. Trying to reuse it.\n");
213 else jabber_bosh_connection_boot(bosh_conn); 214 bosh_conn->receive_cb = jabber_bosh_connection_received;
215 bosh_conn->connect_cb(bosh_conn);
216 } else jabber_bosh_connection_boot(bosh_conn);
217 }
218
219 static void jabber_bosh_connection_refresh(PurpleHTTPConnection *conn) {
220 PurpleBOSHConnection *bosh_conn = conn->userdata;
221 jabber_bosh_connection_send(bosh_conn, NULL);
222 }
223
224 static void jabber_bosh_http_connection_disconnected(PurpleHTTPConnection *conn) {
225 PurpleBOSHConnection *bosh_conn = conn->userdata;
226 bosh_conn->conn_a->connect_cb = jabber_bosh_connection_connected;
227 jabber_bosh_http_connection_connect(bosh_conn->conn_a);
214 } 228 }
215 229
216 void jabber_bosh_connection_connect(PurpleBOSHConnection *conn) { 230 void jabber_bosh_connection_connect(PurpleBOSHConnection *conn) {
217 conn->conn_a->connect_cb = jabber_bosh_connection_connected; 231 conn->conn_a->connect_cb = jabber_bosh_connection_connected;
218 jabber_bosh_http_connection_connect(conn->conn_a); 232 jabber_bosh_http_connection_connect(conn->conn_a);
255 269
256 static void jabber_bosh_http_connection_receive(gpointer data, gint source, PurpleInputCondition condition) { 270 static void jabber_bosh_http_connection_receive(gpointer data, gint source, PurpleInputCondition condition) {
257 char buffer[1025]; 271 char buffer[1025];
258 int len; 272 int len;
259 PurpleHTTPConnection *conn = data; 273 PurpleHTTPConnection *conn = data;
274 PurpleBOSHConnection *bosh_conn = conn->userdata;
260 PurpleHTTPResponse *response = conn->current_response; 275 PurpleHTTPResponse *response = conn->current_response;
261 276
262 purple_debug_info("jabber", "jabber_bosh_http_connection_receive\n"); 277 purple_debug_info("jabber", "jabber_bosh_http_connection_receive\n");
263 278
264 len = read(source, buffer, 1024); 279 len = read(source, buffer, 1024);
291 } 306 }
292 307
293 if (response) { 308 if (response) {
294 if (conn->current_len >= response->data_len) { 309 if (conn->current_len >= response->data_len) {
295 PurpleHTTPRequest *request = g_queue_pop_head(conn->requests); 310 PurpleHTTPRequest *request = g_queue_pop_head(conn->requests);
311
312 #warning for a pure HTTP 1.1 stack this would be needed to be handled elsewhereƄ
313 if (bosh_conn->ready == TRUE && g_queue_is_empty(conn->requests) == TRUE) {
314 jabber_bosh_connection_send(bosh_conn, NULL);
315 printf("\n SEND AN EMPTY REQUEST \n");
316 }
317
296 if (request) { 318 if (request) {
297 response->data = g_memdup(conn->current_data, response->data_len); 319 response->data = g_memdup(conn->current_data, response->data_len);
298 request->cb(request, response, conn->userdata); 320 request->cb(request, response, conn->userdata);
299 jabber_bosh_http_request_clean(request); 321 jabber_bosh_http_request_clean(request);
300 jabber_bosh_http_response_clean(response); 322 jabber_bosh_http_response_clean(response);
301 conn->current_response = NULL; 323 conn->current_response = NULL;
324 g_free(request);
325 g_free(response);
302 } else { 326 } else {
303 purple_debug_info("jabber", "received HTTP response but haven't requested anything yet.\n"); 327 purple_debug_info("jabber", "received HTTP response but haven't requested anything yet.\n");
304 } 328 }
305 } 329 }
306 } 330 }
331 } else if (len == 0) {
332 purple_input_remove(conn->ie_handle);
333 if (conn->disconnect_cb) conn->disconnect_cb(conn);
307 } else { 334 } else {
308 purple_debug_info("jabber", "jabber_bosh_http_connection_receive: problem receiving data\n"); 335 purple_debug_info("jabber", "jabber_bosh_http_connection_receive: problem receiving data (%d)\n", len);
309 } 336 }
310 } 337 }
311 338
312 void jabber_bosh_http_connection_init(PurpleHTTPConnection *conn, PurpleAccount *account, char *host, int port) { 339 void jabber_bosh_http_connection_init(PurpleHTTPConnection *conn, PurpleAccount *account, char *host, int port) {
313 conn->account = account; 340 conn->account = account;
328 if (source < 0) { 355 if (source < 0) {
329 purple_debug_info("jabber", "Couldn't connect becasue of: %s\n", error); 356 purple_debug_info("jabber", "Couldn't connect becasue of: %s\n", error);
330 return; 357 return;
331 } 358 }
332 conn->fd = source; 359 conn->fd = source;
360 if (conn->connect_cb) conn->connect_cb(conn);
361 else purple_debug_info("jabber", "No connect callback for HTTP connection.\n");
333 conn->ie_handle = purple_input_add(conn->fd, PURPLE_INPUT_READ, jabber_bosh_http_connection_receive, conn); 362 conn->ie_handle = purple_input_add(conn->fd, PURPLE_INPUT_READ, jabber_bosh_http_connection_receive, conn);
334 if (conn->connect_cb) conn->connect_cb(conn);
335 } 363 }
336 364
337 void jabber_bosh_http_connection_connect(PurpleHTTPConnection *conn) { 365 void jabber_bosh_http_connection_connect(PurpleHTTPConnection *conn) {
338 if((purple_proxy_connect(&(conn->handle), conn->account, conn->host, conn->port, jabber_bosh_http_connection_callback, conn)) == NULL) { 366 if((purple_proxy_connect(&(conn->handle), conn->account, conn->host, conn->port, jabber_bosh_http_connection_callback, conn)) == NULL) {
339 purple_debug_info("jabber", "Unable to connect to %s.\n", conn->host); 367 purple_debug_info("jabber", "Unable to connect to %s.\n", conn->host);
391 res->header = g_hash_table_new(g_str_hash, g_str_equal); 419 res->header = g_hash_table_new(g_str_hash, g_str_equal);
392 } 420 }
393 421
394 422
395 void jabber_bosh_http_response_clean(PurpleHTTPResponse *res) { 423 void jabber_bosh_http_response_clean(PurpleHTTPResponse *res) {
396 g_hash_table_destroy(res->header); 424 //g_hash_table_destroy(res->header);
397 g_free(res->data); 425 g_free(res->data);
398 } 426 }