Mercurial > pidgin
comparison libpurple/protocols/jabber/bosh.c @ 25994:a94b28023bf6
Clean up BOSH reading and disconnection handling.
In particular, notice we've disconnected _before_ we process what we read,
so that, if processing ends up trying to send a new packet, this connection
will be marked as closed.
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Mon, 16 Mar 2009 02:45:53 +0000 |
parents | c3c2e8b64539 |
children | e995540378f0 |
comparison
equal
deleted
inserted
replaced
25993:6d7d360687bd | 25994:a94b28023bf6 |
---|---|
496 http_connection_send_request(chosen, packet); | 496 http_connection_send_request(chosen, packet); |
497 } | 497 } |
498 | 498 |
499 static void http_connection_connected(PurpleHTTPConnection *conn) | 499 static void http_connection_connected(PurpleHTTPConnection *conn) |
500 { | 500 { |
501 /* Indicate we're ready and reset some variables */ | |
501 conn->ready = TRUE; | 502 conn->ready = TRUE; |
503 conn->requests = 0; | |
504 if (conn->buf) { | |
505 g_string_free(conn->buf, TRUE); | |
506 conn->buf = NULL; | |
507 } | |
508 conn->headers_done = FALSE; | |
509 conn->handled_len = conn->body_len = 0; | |
502 | 510 |
503 if (conn->bosh->ready) { | 511 if (conn->bosh->ready) { |
504 purple_debug_info("jabber", "BOSH session already exists. Trying to reuse it.\n"); | 512 purple_debug_info("jabber", "BOSH session already exists. Trying to reuse it.\n"); |
505 if (conn->bosh->pending && conn->bosh->pending->len > 0) { | 513 if (conn->bosh->pending && conn->bosh->pending->len > 0) { |
506 /* Send the pending data */ | 514 /* Send the pending data */ |
526 * Well, then. Fine! I never liked you anyway, server! I was cheating on you | 534 * Well, then. Fine! I never liked you anyway, server! I was cheating on you |
527 * with AIM! | 535 * with AIM! |
528 */ | 536 */ |
529 conn->ready = FALSE; | 537 conn->ready = FALSE; |
530 conn->fd = -1; | 538 conn->fd = -1; |
539 purple_input_remove(conn->ie_handle); | |
540 conn->ie_handle = 0; | |
531 | 541 |
532 if (conn->bosh->pipelining) | 542 if (conn->bosh->pipelining) |
533 /* Hmmmm, fall back to multiple connections */ | 543 /* Hmmmm, fall back to multiple connections */ |
534 conn->bosh->pipelining = FALSE; | 544 conn->bosh->pipelining = FALSE; |
535 | 545 |
603 jabber_bosh_http_connection_read(gpointer data, gint fd, | 613 jabber_bosh_http_connection_read(gpointer data, gint fd, |
604 PurpleInputCondition condition) | 614 PurpleInputCondition condition) |
605 { | 615 { |
606 PurpleHTTPConnection *conn = data; | 616 PurpleHTTPConnection *conn = data; |
607 char buffer[1025]; | 617 char buffer[1025]; |
608 int perrno; | |
609 int cnt, count = 0; | 618 int cnt, count = 0; |
610 | |
611 purple_debug_info("jabber", "jabber_bosh_http_connection_read\n"); | |
612 | 619 |
613 if (!conn->buf) | 620 if (!conn->buf) |
614 conn->buf = g_string_new(""); | 621 conn->buf = g_string_new(""); |
615 | 622 |
616 while ((cnt = read(fd, buffer, sizeof(buffer))) > 0) { | 623 while ((cnt = read(fd, buffer, sizeof(buffer))) > 0) { |
617 purple_debug_info("jabber", "bosh read %d bytes\n", cnt); | |
618 count += cnt; | 624 count += cnt; |
619 g_string_append_len(conn->buf, buffer, cnt); | 625 g_string_append_len(conn->buf, buffer, cnt); |
620 } | 626 } |
621 | 627 |
622 perrno = errno; | 628 if (cnt == 0 || (cnt < 0 && errno != EAGAIN)) { |
623 if (cnt == 0 && count) { | |
624 /* TODO: process should know this response ended with a closed socket | |
625 * and throw an error if it's not a complete response. */ | |
626 jabber_bosh_http_connection_process(conn); | |
627 } | |
628 | |
629 if (cnt == 0 || (cnt < 0 && perrno != EAGAIN)) { | |
630 if (cnt < 0) | 629 if (cnt < 0) |
631 purple_debug_info("jabber", "bosh read: %d\n", cnt); | 630 purple_debug_info("jabber", "bosh read=%d, errno=%d\n", cnt, errno); |
632 else | 631 else |
633 purple_debug_info("jabber", "bosh socket closed\n"); | 632 purple_debug_info("jabber", "bosh server closed connection\n"); |
634 | 633 |
635 purple_input_remove(conn->ie_handle); | 634 /* |
636 conn->ie_handle = 0; | 635 * If the socket is closed, the processing really needs to know about |
637 | 636 * it. Handle that now (it will be handled again post-processing). |
637 */ | |
638 http_connection_disconnected(conn); | 638 http_connection_disconnected(conn); |
639 return; | 639 |
640 /* Process what we do have */ | |
640 } | 641 } |
641 | 642 |
642 jabber_bosh_http_connection_process(conn); | 643 jabber_bosh_http_connection_process(conn); |
643 } | 644 } |
644 | 645 |
692 conn->bosh->path, conn->bosh->host, bosh_useragent, | 693 conn->bosh->path, conn->bosh->host, bosh_useragent, |
693 req->len); | 694 req->len); |
694 | 695 |
695 packet = g_string_append(packet, req->str); | 696 packet = g_string_append(packet, req->str); |
696 | 697 |
697 purple_debug_misc("jabber", "BOSH out: %s\n", packet->str); | |
698 /* TODO: Better error handling, circbuffer or possible integration with | 698 /* TODO: Better error handling, circbuffer or possible integration with |
699 * low-level code in jabber.c */ | 699 * low-level code in jabber.c */ |
700 ret = write(conn->fd, packet->str, packet->len); | 700 ret = write(conn->fd, packet->str, packet->len); |
701 | 701 |
702 ++conn->requests; | 702 ++conn->requests; |
703 ++conn->bosh->requests; | 703 ++conn->bosh->requests; |
704 g_string_free(packet, TRUE); | 704 g_string_free(packet, TRUE); |
705 | 705 |
706 if (ret < 0 && errno == EAGAIN) | 706 if (ret < 0 && errno == EAGAIN) |
707 purple_debug_warning("jabber", "BOSH write would have blocked\n"); | 707 purple_debug_error("jabber", "BOSH write would have blocked\n"); |
708 | 708 |
709 if (ret <= 0) { | 709 if (ret <= 0) { |
710 purple_connection_error_reason(conn->bosh->js->gc, | 710 purple_connection_error_reason(conn->bosh->js->gc, |
711 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | 711 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, |
712 _("Write error")); | 712 _("Write error")); |