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