Mercurial > pidgin
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 } |