Mercurial > pidgin.yaz
comparison libpurple/protocols/jabber/bosh.c @ 28123:14e5eadff540
jabber: Re-order the BOSH structs and normalize the buffer names.
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sat, 01 Aug 2009 03:57:14 +0000 |
parents | 70dcaa0b6fea |
children | 0f79a7b6e856 |
comparison
equal
deleted
inserted
replaced
28117:c8af11ba1ee8 | 28123:14e5eadff540 |
---|---|
45 PACKET_NORMAL, | 45 PACKET_NORMAL, |
46 } PurpleBOSHPacketType; | 46 } PurpleBOSHPacketType; |
47 | 47 |
48 struct _PurpleBOSHConnection { | 48 struct _PurpleBOSHConnection { |
49 JabberStream *js; | 49 JabberStream *js; |
50 PurpleHTTPConnection *connections[MAX_HTTP_CONNECTIONS]; | |
51 | |
52 PurpleCircBuffer *pending; | |
53 PurpleBOSHConnectionConnectFunction connect_cb; | |
54 PurpleBOSHConnectionReceiveFunction receive_cb; | |
55 | |
56 /* Must be big enough to hold 2^53 - 1 */ | |
57 char *sid; | |
58 guint64 rid; | |
59 | |
60 /* decoded URL */ | |
61 char *host; | |
62 char *path; | |
63 guint16 port; | |
64 | |
50 gboolean pipelining; | 65 gboolean pipelining; |
51 PurpleHTTPConnection *connections[MAX_HTTP_CONNECTIONS]; | 66 gboolean ssl; |
52 unsigned short failed_connections; | 67 gboolean needs_restart; |
53 | 68 |
54 enum { | 69 enum { |
55 BOSH_CONN_OFFLINE, | 70 BOSH_CONN_OFFLINE, |
56 BOSH_CONN_BOOTING, | 71 BOSH_CONN_BOOTING, |
57 BOSH_CONN_ONLINE | 72 BOSH_CONN_ONLINE |
58 } state; | 73 } state; |
59 gboolean ssl; | 74 guint8 failed_connections; |
60 gboolean needs_restart; | 75 |
61 | |
62 /* decoded URL */ | |
63 char *host; | |
64 int port; | |
65 char *path; | |
66 | |
67 /* Must be big enough to hold 2^53 - 1 */ | |
68 guint64 rid; | |
69 char *sid; | |
70 | |
71 unsigned int inactivity_timer; | |
72 int max_inactivity; | 76 int max_inactivity; |
73 int wait; | 77 int wait; |
74 | 78 |
75 PurpleCircBuffer *pending; | |
76 int max_requests; | 79 int max_requests; |
77 int requests; | 80 int requests; |
78 | 81 |
79 PurpleBOSHConnectionConnectFunction connect_cb; | 82 guint inactivity_timer; |
80 PurpleBOSHConnectionReceiveFunction receive_cb; | |
81 }; | 83 }; |
82 | 84 |
83 struct _PurpleHTTPConnection { | 85 struct _PurpleHTTPConnection { |
84 PurpleBOSHConnection *bosh; | 86 PurpleBOSHConnection *bosh; |
85 PurpleSslConnection *psc; | 87 PurpleSslConnection *psc; |
88 | |
89 PurpleCircBuffer *write_buf; | |
90 GString *read_buf; | |
91 | |
92 gsize handled_len; | |
93 gsize body_len; | |
94 | |
86 int fd; | 95 int fd; |
87 guint readh; | 96 guint readh; |
88 guint writeh; | 97 guint writeh; |
89 | |
90 PurpleCircBuffer *write_buffer; | |
91 | 98 |
92 enum { | 99 enum { |
93 HTTP_CONN_OFFLINE, | 100 HTTP_CONN_OFFLINE, |
94 HTTP_CONN_CONNECTING, | 101 HTTP_CONN_CONNECTING, |
95 HTTP_CONN_CONNECTED | 102 HTTP_CONN_CONNECTED |
96 } state; | 103 } state; |
97 int requests; /* number of outstanding HTTP requests */ | 104 int requests; /* number of outstanding HTTP requests */ |
98 | 105 |
99 GString *buf; | |
100 gboolean headers_done; | 106 gboolean headers_done; |
101 gsize handled_len; | |
102 gsize body_len; | |
103 | 107 |
104 }; | 108 }; |
105 | 109 |
106 static void http_connection_connect(PurpleHTTPConnection *conn); | 110 static void http_connection_connect(PurpleHTTPConnection *conn); |
107 static void http_connection_send_request(PurpleHTTPConnection *conn, | 111 static void http_connection_send_request(PurpleHTTPConnection *conn, |
138 PurpleHTTPConnection *conn = g_new0(PurpleHTTPConnection, 1); | 142 PurpleHTTPConnection *conn = g_new0(PurpleHTTPConnection, 1); |
139 conn->bosh = bosh; | 143 conn->bosh = bosh; |
140 conn->fd = -1; | 144 conn->fd = -1; |
141 conn->state = HTTP_CONN_OFFLINE; | 145 conn->state = HTTP_CONN_OFFLINE; |
142 | 146 |
143 conn->write_buffer = purple_circ_buffer_new(0 /* default grow size */); | 147 conn->write_buf = purple_circ_buffer_new(0 /* default grow size */); |
144 | 148 |
145 return conn; | 149 return conn; |
146 } | 150 } |
147 | 151 |
148 static void | 152 static void |
149 jabber_bosh_http_connection_destroy(PurpleHTTPConnection *conn) | 153 jabber_bosh_http_connection_destroy(PurpleHTTPConnection *conn) |
150 { | 154 { |
151 if (conn->buf) | 155 if (conn->read_buf) |
152 g_string_free(conn->buf, TRUE); | 156 g_string_free(conn->read_buf, TRUE); |
153 | 157 |
154 if (conn->write_buffer) | 158 if (conn->write_buf) |
155 purple_circ_buffer_destroy(conn->write_buffer); | 159 purple_circ_buffer_destroy(conn->write_buf); |
156 if (conn->readh) | 160 if (conn->readh) |
157 purple_input_remove(conn->readh); | 161 purple_input_remove(conn->readh); |
158 if (conn->writeh) | 162 if (conn->writeh) |
159 purple_input_remove(conn->writeh); | 163 purple_input_remove(conn->writeh); |
160 if (conn->psc) | 164 if (conn->psc) |
577 connection_common_established_cb(PurpleHTTPConnection *conn) | 581 connection_common_established_cb(PurpleHTTPConnection *conn) |
578 { | 582 { |
579 /* Indicate we're ready and reset some variables */ | 583 /* Indicate we're ready and reset some variables */ |
580 conn->state = HTTP_CONN_CONNECTED; | 584 conn->state = HTTP_CONN_CONNECTED; |
581 conn->requests = 0; | 585 conn->requests = 0; |
582 if (conn->buf) { | 586 if (conn->read_buf) { |
583 g_string_free(conn->buf, TRUE); | 587 g_string_free(conn->read_buf, TRUE); |
584 conn->buf = NULL; | 588 conn->read_buf = NULL; |
585 } | 589 } |
586 conn->headers_done = FALSE; | 590 conn->headers_done = FALSE; |
587 conn->handled_len = conn->body_len = 0; | 591 conn->handled_len = conn->body_len = 0; |
588 | 592 |
589 if (conn->bosh->needs_restart) | 593 if (conn->bosh->needs_restart) |
659 static void | 663 static void |
660 jabber_bosh_http_connection_process(PurpleHTTPConnection *conn) | 664 jabber_bosh_http_connection_process(PurpleHTTPConnection *conn) |
661 { | 665 { |
662 const char *cursor; | 666 const char *cursor; |
663 | 667 |
664 cursor = conn->buf->str + conn->handled_len; | 668 cursor = conn->read_buf->str + conn->handled_len; |
665 | 669 |
666 if (!conn->headers_done) { | 670 if (!conn->headers_done) { |
667 const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length"); | 671 const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length"); |
668 const char *end_of_headers = strstr(cursor, "\r\n\r\n"); | 672 const char *end_of_headers = strstr(cursor, "\r\n\r\n"); |
669 | 673 |
688 conn->body_len = len; | 692 conn->body_len = len; |
689 } | 693 } |
690 | 694 |
691 if (end_of_headers) { | 695 if (end_of_headers) { |
692 conn->headers_done = TRUE; | 696 conn->headers_done = TRUE; |
693 conn->handled_len = end_of_headers - conn->buf->str + 4; | 697 conn->handled_len = end_of_headers - conn->read_buf->str + 4; |
694 cursor = end_of_headers + 4; | 698 cursor = end_of_headers + 4; |
695 } else { | 699 } else { |
696 conn->handled_len = conn->buf->len; | 700 conn->handled_len = conn->read_buf->len; |
697 return; | 701 return; |
698 } | 702 } |
699 } | 703 } |
700 | 704 |
701 /* Have we handled everything in the buffer? */ | 705 /* Have we handled everything in the buffer? */ |
702 if (conn->handled_len >= conn->buf->len) | 706 if (conn->handled_len >= conn->read_buf->len) |
703 return; | 707 return; |
704 | 708 |
705 /* Have we read all that the Content-Length promised us? */ | 709 /* Have we read all that the Content-Length promised us? */ |
706 if (conn->buf->len - conn->handled_len < conn->body_len) | 710 if (conn->read_buf->len - conn->handled_len < conn->body_len) |
707 return; | 711 return; |
708 | 712 |
709 --conn->requests; | 713 --conn->requests; |
710 --conn->bosh->requests; | 714 --conn->bosh->requests; |
711 | 715 |
712 http_received_cb(conn->buf->str + conn->handled_len, conn->body_len, | 716 http_received_cb(conn->read_buf->str + conn->handled_len, conn->body_len, |
713 conn->bosh); | 717 conn->bosh); |
714 | 718 |
715 if (conn->bosh->state == BOSH_CONN_ONLINE && | 719 if (conn->bosh->state == BOSH_CONN_ONLINE && |
716 (conn->bosh->requests == 0 || conn->bosh->pending->bufused > 0)) { | 720 (conn->bosh->requests == 0 || conn->bosh->pending->bufused > 0)) { |
717 purple_debug_misc("jabber", "BOSH: Sending an empty request\n"); | 721 purple_debug_misc("jabber", "BOSH: Sending an empty request\n"); |
718 jabber_bosh_connection_send(conn->bosh, PACKET_NORMAL, NULL); | 722 jabber_bosh_connection_send(conn->bosh, PACKET_NORMAL, NULL); |
719 } | 723 } |
720 | 724 |
721 g_string_free(conn->buf, TRUE); | 725 g_string_free(conn->read_buf, TRUE); |
722 conn->buf = NULL; | 726 conn->read_buf = NULL; |
723 conn->headers_done = FALSE; | 727 conn->headers_done = FALSE; |
724 conn->handled_len = conn->body_len = 0; | 728 conn->handled_len = conn->body_len = 0; |
725 } | 729 } |
726 | 730 |
727 /* | 731 /* |
732 http_connection_read(PurpleHTTPConnection *conn) | 736 http_connection_read(PurpleHTTPConnection *conn) |
733 { | 737 { |
734 char buffer[1025]; | 738 char buffer[1025]; |
735 int cnt, count = 0; | 739 int cnt, count = 0; |
736 | 740 |
737 if (!conn->buf) | 741 if (!conn->read_buf) |
738 conn->buf = g_string_new(NULL); | 742 conn->read_buf = g_string_new(NULL); |
739 | 743 |
740 do { | 744 do { |
741 if (conn->psc) | 745 if (conn->psc) |
742 cnt = purple_ssl_read(conn->psc, buffer, sizeof(buffer)); | 746 cnt = purple_ssl_read(conn->psc, buffer, sizeof(buffer)); |
743 else | 747 else |
744 cnt = read(conn->fd, buffer, sizeof(buffer)); | 748 cnt = read(conn->fd, buffer, sizeof(buffer)); |
745 | 749 |
746 if (cnt > 0) { | 750 if (cnt > 0) { |
747 count += cnt; | 751 count += cnt; |
748 g_string_append_len(conn->buf, buffer, cnt); | 752 g_string_append_len(conn->read_buf, buffer, cnt); |
749 } | 753 } |
750 } while (cnt > 0); | 754 } while (cnt > 0); |
751 | 755 |
752 if (cnt == 0 || (cnt < 0 && errno != EAGAIN)) { | 756 if (cnt == 0 || (cnt < 0 && errno != EAGAIN)) { |
753 if (cnt < 0) | 757 if (cnt < 0) |
763 http_connection_disconnected(conn); | 767 http_connection_disconnected(conn); |
764 | 768 |
765 /* Process what we do have */ | 769 /* Process what we do have */ |
766 } | 770 } |
767 | 771 |
768 if (conn->buf->len > 0) | 772 if (conn->read_buf->len > 0) |
769 jabber_bosh_http_connection_process(conn); | 773 jabber_bosh_http_connection_process(conn); |
770 } | 774 } |
771 | 775 |
772 static void | 776 static void |
773 http_connection_read_cb(gpointer data, gint fd, PurpleInputCondition condition) | 777 http_connection_read_cb(gpointer data, gint fd, PurpleInputCondition condition) |
877 static void | 881 static void |
878 http_connection_send_cb(gpointer data, gint source, PurpleInputCondition cond) | 882 http_connection_send_cb(gpointer data, gint source, PurpleInputCondition cond) |
879 { | 883 { |
880 PurpleHTTPConnection *conn = data; | 884 PurpleHTTPConnection *conn = data; |
881 int ret; | 885 int ret; |
882 int writelen = purple_circ_buffer_get_max_read(conn->write_buffer); | 886 int writelen = purple_circ_buffer_get_max_read(conn->write_buf); |
883 | 887 |
884 if (writelen == 0) { | 888 if (writelen == 0) { |
885 purple_input_remove(conn->writeh); | 889 purple_input_remove(conn->writeh); |
886 conn->writeh = 0; | 890 conn->writeh = 0; |
887 return; | 891 return; |
888 } | 892 } |
889 | 893 |
890 ret = http_connection_do_send(conn, conn->write_buffer->outptr, writelen); | 894 ret = http_connection_do_send(conn, conn->write_buf->outptr, writelen); |
891 | 895 |
892 if (ret < 0 && errno == EAGAIN) | 896 if (ret < 0 && errno == EAGAIN) |
893 return; | 897 return; |
894 else if (ret <= 0) { | 898 else if (ret <= 0) { |
895 /* | 899 /* |
904 tmp); | 908 tmp); |
905 g_free(tmp); | 909 g_free(tmp); |
906 return; | 910 return; |
907 } | 911 } |
908 | 912 |
909 purple_circ_buffer_mark_read(conn->write_buffer, ret); | 913 purple_circ_buffer_mark_read(conn->write_buf, ret); |
910 } | 914 } |
911 | 915 |
912 static void | 916 static void |
913 http_connection_send_request(PurpleHTTPConnection *conn, const GString *req) | 917 http_connection_send_request(PurpleHTTPConnection *conn, const GString *req) |
914 { | 918 { |
954 if (ret < 0) | 958 if (ret < 0) |
955 ret = 0; | 959 ret = 0; |
956 if (conn->writeh == 0) | 960 if (conn->writeh == 0) |
957 conn->writeh = purple_input_add(conn->psc ? conn->psc->fd : conn->fd, | 961 conn->writeh = purple_input_add(conn->psc ? conn->psc->fd : conn->fd, |
958 PURPLE_INPUT_WRITE, http_connection_send_cb, conn); | 962 PURPLE_INPUT_WRITE, http_connection_send_cb, conn); |
959 purple_circ_buffer_append(conn->write_buffer, data + ret, len - ret); | 963 purple_circ_buffer_append(conn->write_buf, data + ret, len - ret); |
960 } | 964 } |
961 } | 965 } |
962 | 966 |