Mercurial > pidgin
comparison libpurple/protocols/jabber/bosh.c @ 31134:bb91133708fe
jabber: Make the BOSH parsing a little more resilient and add more diagnostic output
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Mon, 10 Jan 2011 03:34:00 +0000 |
parents | dbd0012e72cb |
children | 6826925abd6d |
comparison
equal
deleted
inserted
replaced
31133:dbd0012e72cb | 31134:bb91133708fe |
---|---|
109 | 109 |
110 gboolean headers_done; | 110 gboolean headers_done; |
111 | 111 |
112 }; | 112 }; |
113 | 113 |
114 static void | |
115 debug_dump_http_connections(PurpleBOSHConnection *conn) | |
116 { | |
117 int i; | |
118 | |
119 g_return_if_fail(conn != NULL); | |
120 | |
121 for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) { | |
122 PurpleHTTPConnection *httpconn = conn->connections[i]; | |
123 if (httpconn == NULL) | |
124 purple_debug_misc("jabber", "BOSH %p->connections[%d] = (nil)\n", | |
125 conn, i); | |
126 else | |
127 purple_debug_misc("jabber", "BOSH %p->connections[%d] = %p, state = %d" | |
128 ", requests = %d\n", conn, i, httpconn, | |
129 httpconn->state, httpconn->requests); | |
130 } | |
131 } | |
132 | |
114 static void http_connection_connect(PurpleHTTPConnection *conn); | 133 static void http_connection_connect(PurpleHTTPConnection *conn); |
115 static void http_connection_send_request(PurpleHTTPConnection *conn, | 134 static void http_connection_send_request(PurpleHTTPConnection *conn, |
116 const GString *req); | 135 const GString *req); |
117 static gboolean send_timer_cb(gpointer data); | 136 static gboolean send_timer_cb(gpointer data); |
118 | 137 |
261 static PurpleHTTPConnection * | 280 static PurpleHTTPConnection * |
262 find_available_http_connection(PurpleBOSHConnection *conn) | 281 find_available_http_connection(PurpleBOSHConnection *conn) |
263 { | 282 { |
264 int i; | 283 int i; |
265 | 284 |
266 if (purple_debug_is_verbose()) { | 285 if (purple_debug_is_verbose()) |
267 for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) { | 286 debug_dump_http_connections(conn); |
268 PurpleHTTPConnection *httpconn = conn->connections[i]; | |
269 if (httpconn == NULL) | |
270 purple_debug_misc("jabber", "BOSH %p->connections[%d] = (nil)\n", | |
271 conn, i); | |
272 else | |
273 purple_debug_misc("jabber", "BOSH %p->connections[%d] = %p, state = %d" | |
274 ", requests = %d\n", conn, i, httpconn, | |
275 httpconn->state, httpconn->requests); | |
276 } | |
277 } | |
278 | 287 |
279 /* Easy solution: Does everyone involved support pipelining? Hooray! Just use | 288 /* Easy solution: Does everyone involved support pipelining? Hooray! Just use |
280 * one TCP connection! */ | 289 * one TCP connection! */ |
281 if (conn->pipelining) | 290 if (conn->pipelining) |
282 return conn->connections[0]->state == HTTP_CONN_CONNECTED ? | 291 return conn->connections[0]->state == HTTP_CONN_CONNECTED ? |
610 } | 619 } |
611 | 620 |
612 static void | 621 static void |
613 connection_common_established_cb(PurpleHTTPConnection *conn) | 622 connection_common_established_cb(PurpleHTTPConnection *conn) |
614 { | 623 { |
624 purple_debug_misc("jabber", "bosh: httpconn %p re-connected\n", conn); | |
625 | |
615 /* Indicate we're ready and reset some variables */ | 626 /* Indicate we're ready and reset some variables */ |
616 conn->state = HTTP_CONN_CONNECTED; | 627 conn->state = HTTP_CONN_CONNECTED; |
617 if (conn->requests != 0) | 628 if (conn->requests != 0) |
618 purple_debug_error("jabber", "bosh: httpconn %p has %d requests, != 0\n", | 629 purple_debug_error("jabber", "bosh: httpconn %p has %d requests, != 0\n", |
619 conn, conn->requests); | 630 conn, conn->requests); |
623 g_string_free(conn->read_buf, TRUE); | 634 g_string_free(conn->read_buf, TRUE); |
624 conn->read_buf = NULL; | 635 conn->read_buf = NULL; |
625 } | 636 } |
626 conn->headers_done = FALSE; | 637 conn->headers_done = FALSE; |
627 conn->handled_len = conn->body_len = 0; | 638 conn->handled_len = conn->body_len = 0; |
639 | |
640 if (purple_debug_is_verbose()) | |
641 debug_dump_http_connections(conn->bosh); | |
628 | 642 |
629 if (conn->bosh->js->reinit) | 643 if (conn->bosh->js->reinit) |
630 jabber_bosh_connection_send(conn->bosh, PACKET_NORMAL, NULL); | 644 jabber_bosh_connection_send(conn->bosh, PACKET_NORMAL, NULL); |
631 else if (conn->bosh->state == BOSH_CONN_ONLINE) { | 645 else if (conn->bosh->state == BOSH_CONN_ONLINE) { |
632 purple_debug_info("jabber", "BOSH session already exists. Trying to reuse it.\n"); | 646 purple_debug_info("jabber", "BOSH session already exists. Trying to reuse it.\n"); |
708 { | 722 { |
709 const char *cursor; | 723 const char *cursor; |
710 | 724 |
711 cursor = conn->read_buf->str + conn->handled_len; | 725 cursor = conn->read_buf->str + conn->handled_len; |
712 | 726 |
727 /* TODO: Chunked encoding :/ */ | |
713 if (!conn->headers_done) { | 728 if (!conn->headers_done) { |
714 const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length"); | 729 const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length:"); |
715 const char *end_of_headers = strstr(cursor, "\r\n\r\n"); | 730 const char *end_of_headers = strstr(cursor, "\r\n\r\n"); |
716 | 731 |
717 /* Make sure Content-Length is in headers, not body */ | 732 /* Make sure Content-Length is in headers, not body */ |
718 if (content_length && (!end_of_headers || content_length < end_of_headers)) { | 733 if (content_length && (!end_of_headers || content_length < end_of_headers)) { |
719 const char *sep; | |
720 int len; | 734 int len; |
721 | 735 |
722 if ((sep = strstr(content_length, ": ")) == NULL || | 736 if (strstr(content_length, "\r\n") == NULL) |
723 strstr(sep, "\r\n") == NULL) | |
724 /* | 737 /* |
725 * The packet ends in the middle of the Content-Length line. | 738 * The packet ends in the middle of the Content-Length line. |
726 * We'll try again later when we have more. | 739 * We'll try again later when we have more. |
727 */ | 740 */ |
728 return; | 741 return; |
729 | 742 |
730 len = atoi(sep + 2); | 743 len = atoi(content_length + strlen("\r\nContent-Length:")); |
731 if (len == 0) | 744 if (len == 0) |
732 purple_debug_warning("jabber", "Found mangled Content-Length header.\n"); | 745 purple_debug_warning("jabber", "Found mangled Content-Length header, or server returned 0-length response.\n"); |
733 | 746 |
734 conn->body_len = len; | 747 conn->body_len = len; |
735 } | 748 } |
736 | 749 |
737 if (end_of_headers) { | 750 if (end_of_headers) { |