Mercurial > pidgin
changeset 31139:365ec0996ca0
merge of '2efa9b7fc41104668975df54e8be8a7171383794'
and '88aea2f701d6cff5efc151d40ef06257da67cf3d'
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Mon, 10 Jan 2011 05:20:06 +0000 |
parents | d5b710c91104 (current diff) 6826925abd6d (diff) |
children | be5cb357c7b5 7986f4e5a05f |
files | ChangeLog |
diffstat | 5 files changed, 124 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Mon Jan 10 03:30:05 2011 +0000 +++ b/ChangeLog Mon Jan 10 05:20:06 2011 +0000 @@ -9,6 +9,7 @@ calls to stop sending audio and video. (Jakub Adam) (#12758) * Perl bindings now respect LDFLAGS. (Peter Volkov, Markos Chandras) (#12638) + * Added AddTrust External Root CA. (#11554) Groupwise: * Don't show two windows when using "Get Info" on a buddy. (Gabriel Burt; @@ -46,6 +47,8 @@ XMPP: * Don't crash when receiving an unexpected/invalid jingle transport type. (Nikita Kozlov) (#13136) + * Handle Connection: Close headers for BOSH, when the server does not + terminate the connection itself. (#13008) Yahoo!/Yahoo! JAPAN: * Fix a crash when an account disconnects before a p2p session is
--- a/libpurple/protocols/jabber/bosh.c Mon Jan 10 03:30:05 2011 +0000 +++ b/libpurple/protocols/jabber/bosh.c Mon Jan 10 05:20:06 2011 +0000 @@ -108,8 +108,27 @@ int requests; /* number of outstanding HTTP requests */ gboolean headers_done; + gboolean close; +}; -}; +static void +debug_dump_http_connections(PurpleBOSHConnection *conn) +{ + int i; + + g_return_if_fail(conn != NULL); + + for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) { + PurpleHTTPConnection *httpconn = conn->connections[i]; + if (httpconn == NULL) + purple_debug_misc("jabber", "BOSH %p->connections[%d] = (nil)\n", + conn, i); + else + purple_debug_misc("jabber", "BOSH %p->connections[%d] = %p, state = %d" + ", requests = %d\n", conn, i, httpconn, + httpconn->state, httpconn->requests); + } +} static void http_connection_connect(PurpleHTTPConnection *conn); static void http_connection_send_request(PurpleHTTPConnection *conn, @@ -263,18 +282,8 @@ { int i; - if (purple_debug_is_verbose()) { - for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) { - PurpleHTTPConnection *httpconn = conn->connections[i]; - if (httpconn == NULL) - purple_debug_misc("jabber", "BOSH %p->connections[%d] = (nil)\n", - conn, i); - else - purple_debug_misc("jabber", "BOSH %p->connections[%d] = %p, state = %d" - ", requests = %d\n", conn, i, httpconn, - httpconn->state, httpconn->requests); - } - } + if (purple_debug_is_verbose()) + debug_dump_http_connections(conn); /* Easy solution: Does everyone involved support pipelining? Hooray! Just use * one TCP connection! */ @@ -300,8 +309,9 @@ /* Third loop, look for one that's NULL and create a new connection */ for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) { if (!conn->connections[i]) { - purple_debug_info("jabber", "bosh: Creating and connecting new httpconn\n"); conn->connections[i] = jabber_bosh_http_connection_init(conn); + purple_debug_info("jabber", "bosh: Creating and connecting new httpconn " + "(%i, %p)\n", i, conn->connections[i]); http_connection_connect(conn->connections[i]); return NULL; @@ -444,6 +454,25 @@ send_timer_cb(bosh); } +static void +jabber_bosh_disable_pipelining(PurpleBOSHConnection *bosh) +{ + /* Do nothing if it's already disabled */ + if (!bosh->pipelining) + return; + + bosh->pipelining = FALSE; + if (bosh->connections[1] == NULL) { + bosh->connections[1] = jabber_bosh_http_connection_init(bosh); + http_connection_connect(bosh->connections[1]); + } else { + /* Shouldn't happen; this should be the only place pipelining + * is turned off. + */ + g_warn_if_reached(); + } +} + static void jabber_bosh_connection_received(PurpleBOSHConnection *conn, xmlnode *node) { xmlnode *child; JabberStream *js = conn->js; @@ -611,6 +640,8 @@ static void connection_common_established_cb(PurpleHTTPConnection *conn) { + purple_debug_misc("jabber", "bosh: httpconn %p re-connected\n", conn); + /* Indicate we're ready and reset some variables */ conn->state = HTTP_CONN_CONNECTED; if (conn->requests != 0) @@ -622,9 +653,13 @@ g_string_free(conn->read_buf, TRUE); conn->read_buf = NULL; } + conn->close = FALSE; conn->headers_done = FALSE; conn->handled_len = conn->body_len = 0; + if (purple_debug_is_verbose()) + debug_dump_http_connections(conn->bosh); + if (conn->bosh->js->reinit) jabber_bosh_connection_send(conn->bosh, PACKET_NORMAL, NULL); else if (conn->bosh->state == BOSH_CONN_ONLINE) { @@ -671,11 +706,7 @@ if (conn->bosh->pipelining) { /* Hmmmm, fall back to multiple connections */ - conn->bosh->pipelining = FALSE; - if (conn->bosh->connections[1] == NULL) { - conn->bosh->connections[1] = jabber_bosh_http_connection_init(conn->bosh); - http_connection_connect(conn->bosh->connections[1]); - } + jabber_bosh_disable_pipelining(conn->bosh); } if (++conn->bosh->failed_connections == MAX_FAILED_CONNECTIONS) { @@ -704,30 +735,49 @@ cursor = conn->read_buf->str + conn->handled_len; + if (purple_debug_is_verbose()) + purple_debug_misc("jabber", "BOSH server sent: %s\n", cursor); + + /* TODO: Chunked encoding and check response version :/ */ if (!conn->headers_done) { - const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length"); + const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length:"); + const char *connection = purple_strcasestr(cursor, "\r\nConnection:"); const char *end_of_headers = strstr(cursor, "\r\n\r\n"); /* Make sure Content-Length is in headers, not body */ if (content_length && (!end_of_headers || content_length < end_of_headers)) { - const char *sep; int len; - if ((sep = strstr(content_length, ": ")) == NULL || - strstr(sep, "\r\n") == NULL) + if (strstr(content_length, "\r\n") == NULL) /* * The packet ends in the middle of the Content-Length line. * We'll try again later when we have more. */ return; - len = atoi(sep + 2); + len = atoi(content_length + strlen("\r\nContent-Length:")); if (len == 0) - purple_debug_warning("jabber", "Found mangled Content-Length header.\n"); + purple_debug_warning("jabber", "Found mangled Content-Length header, or server returned 0-length response.\n"); conn->body_len = len; } + if (connection && (!end_of_headers || content_length < end_of_headers)) { + const char *tmp; + if (strstr(connection, "\r\n") == NULL) + return; + + + tmp = connection + strlen("\r\nConnection:"); + while (*tmp && (*tmp == ' ' || *tmp == '\t')) + ++tmp; + + if (!g_ascii_strncasecmp(tmp, "close", strlen("close"))) { + conn->close = TRUE; + jabber_bosh_disable_pipelining(conn->bosh); + } + } + if (end_of_headers) { conn->headers_done = TRUE; conn->handled_len = end_of_headers - conn->read_buf->str + 4; @@ -752,6 +802,14 @@ http_received_cb(conn->read_buf->str + conn->handled_len, conn->body_len, conn->bosh); + /* Connection: Close? */ + if (conn->close && conn->state == HTTP_CONN_CONNECTED) { + if (purple_debug_is_verbose()) + purple_debug_misc("jabber", "bosh (%p), server sent Connection: " + "close\n", conn); + http_connection_disconnected(conn); + } + if (conn->bosh->state == BOSH_CONN_ONLINE && (conn->bosh->requests == 0 || conn->bosh->pending->bufused > 0)) { purple_debug_misc("jabber", "BOSH: Sending an empty request\n"); @@ -791,10 +849,11 @@ if (cnt == 0 || (cnt < 0 && errno != EAGAIN)) { if (cnt < 0) - purple_debug_info("jabber", "bosh read=%d, errno=%d, error=%s\n", - cnt, errno, g_strerror(errno)); + purple_debug_info("jabber", "BOSH (%p) read=%d, errno=%d, error=%s\n", + conn, cnt, errno, g_strerror(errno)); else - purple_debug_info("jabber", "bosh server closed the connection\n"); + purple_debug_info("jabber", "BOSH server closed the connection (%p)\n", + conn); /* * If the socket is closed, the processing really needs to know about @@ -911,6 +970,9 @@ else ret = write(conn->fd, data, len); + if (purple_debug_is_verbose()) + purple_debug_misc("jabber", "BOSH (%p): wrote %d bytes\n", conn, ret); + return ret; } @@ -975,7 +1037,10 @@ if (purple_debug_is_unsafe() && purple_debug_is_verbose()) /* Will contain passwords for SASL PLAIN and is verbose */ - purple_debug_misc("jabber", "BOSH: Sending %s\n", data); + purple_debug_misc("jabber", "BOSH (%p): Sending %s\n", conn, data); + else if (purple_debug_is_verbose()) + purple_debug_misc("jabber", "BOSH (%p): Sending request of " + "%" G_GSIZE_FORMAT " bytes.\n", conn, len); if (conn->writeh == 0) ret = http_connection_do_send(conn, data, len);
--- a/pidgin/win32/nsis/pidgin-installer.nsi Mon Jan 10 03:30:05 2011 +0000 +++ b/pidgin/win32/nsis/pidgin-installer.nsi Mon Jan 10 05:20:06 2011 +0000 @@ -530,6 +530,7 @@ Push "xmpp" Call un.UnregisterURIHandler + Delete "$INSTDIR\ca-certs\AddTrust_External_Root.pem" Delete "$INSTDIR\ca-certs\America_Online_Root_Certification_Authority_1.pem" Delete "$INSTDIR\ca-certs\AOL_Member_CA.pem" Delete "$INSTDIR\ca-certs\CAcert_Class3.pem"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/ca-certs/AddTrust_External_Root.pem Mon Jan 10 05:20:06 2011 +0000 @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE-----