Mercurial > pidgin
comparison libpurple/protocols/jabber/bosh.c @ 25051:5f70e13db5cc
* data buffer for received data. Support for any HTTP resonse size now.
author | Tobias Markmann <tfar@soc.pidgin.im> |
---|---|
date | Sat, 16 Aug 2008 21:28:32 +0000 |
parents | a03a953ba63d |
children | 0a8484372312 |
comparison
equal
deleted
inserted
replaced
25050:a03a953ba63d | 25051:5f70e13db5cc |
---|---|
80 | 80 |
81 jabber_bosh_connection_send_native(conn, restart); | 81 jabber_bosh_connection_send_native(conn, restart); |
82 } | 82 } |
83 | 83 |
84 void jabber_bosh_connection_received(PurpleBOSHConnection *conn, xmlnode *node) { | 84 void jabber_bosh_connection_received(PurpleBOSHConnection *conn, xmlnode *node) { |
85 | 85 xmlnode *child; |
86 JabberStream *js = conn->js; | |
87 | |
88 if (node == NULL) return; | |
89 | |
90 child = node->child; | |
91 while (child != 0) { | |
92 if (child->type == XMLNODE_TYPE_TAG) { | |
93 jabber_process_packet(js, &child); | |
94 } | |
95 child = child->next; | |
96 } | |
86 xmlnode_free(node); | 97 xmlnode_free(node); |
87 } | 98 } |
88 | 99 |
89 void jabber_bosh_connection_auth_response(PurpleBOSHConnection *conn, xmlnode *node) { | 100 void jabber_bosh_connection_auth_response(PurpleBOSHConnection *conn, xmlnode *node) { |
90 xmlnode *child = node->child; | 101 xmlnode *child = node->child; |
96 if (child != NULL && child->type == XMLNODE_TYPE_TAG) { | 107 if (child != NULL && child->type == XMLNODE_TYPE_TAG) { |
97 JabberStream *js = conn->js; | 108 JabberStream *js = conn->js; |
98 if (!strcmp(child->name, "success")) { | 109 if (!strcmp(child->name, "success")) { |
99 jabber_bosh_connection_stream_restart(conn); | 110 jabber_bosh_connection_stream_restart(conn); |
100 jabber_process_packet(js, &child); | 111 jabber_process_packet(js, &child); |
112 conn->receive_cb = jabber_bosh_connection_received; | |
101 } else { | 113 } else { |
102 js->state = JABBER_STREAM_AUTHENTICATING; | 114 js->state = JABBER_STREAM_AUTHENTICATING; |
103 conn->receive_cb = jabber_bosh_connection_received; | |
104 jabber_process_packet(js, &child); | 115 jabber_process_packet(js, &child); |
105 } | 116 } |
106 } else printf("\n!! no child!!\n"); | 117 } else printf("\n!! no child!!\n"); |
107 } | 118 } |
108 | 119 |
153 | 164 |
154 void jabber_bosh_connection_http_received_cb(PurpleHTTPRequest *req, PurpleHTTPResponse *res, void *userdata) { | 165 void jabber_bosh_connection_http_received_cb(PurpleHTTPRequest *req, PurpleHTTPResponse *res, void *userdata) { |
155 PurpleBOSHConnection *conn = userdata; | 166 PurpleBOSHConnection *conn = userdata; |
156 if (conn->receive_cb) { | 167 if (conn->receive_cb) { |
157 xmlnode *node = xmlnode_from_str(res->data, res->data_len); | 168 xmlnode *node = xmlnode_from_str(res->data, res->data_len); |
158 char *txt = xmlnode_to_formatted_str(node, NULL); | 169 if (node) { |
159 printf("\njabber_bosh_connection_http_received_cb\n%s\n", txt); | 170 char *txt = xmlnode_to_formatted_str(node, NULL); |
160 g_free(txt); | 171 printf("\njabber_bosh_connection_http_received_cb\n%s\n", txt); |
161 conn->receive_cb(conn, node); | 172 g_free(txt); |
173 conn->receive_cb(conn, node); | |
174 } else { | |
175 printf("\njabber_bosh_connection_http_received_cb: XML ERROR: %s\n", res->data); | |
176 } | |
162 } else purple_debug_info("jabber", "missing receive_cb of PurpleBOSHConnection.\n"); | 177 } else purple_debug_info("jabber", "missing receive_cb of PurpleBOSHConnection.\n"); |
163 } | 178 } |
164 | 179 |
165 void jabber_bosh_connection_send(PurpleBOSHConnection *conn, xmlnode *node) { | 180 void jabber_bosh_connection_send(PurpleBOSHConnection *conn, xmlnode *node) { |
166 xmlnode *packet = xmlnode_new("body"); | 181 xmlnode *packet = xmlnode_new("body"); |
201 void jabber_bosh_connection_connect(PurpleBOSHConnection *conn) { | 216 void jabber_bosh_connection_connect(PurpleBOSHConnection *conn) { |
202 conn->conn_a->connect_cb = jabber_bosh_connection_connected; | 217 conn->conn_a->connect_cb = jabber_bosh_connection_connected; |
203 jabber_bosh_http_connection_connect(conn->conn_a); | 218 jabber_bosh_http_connection_connect(conn->conn_a); |
204 } | 219 } |
205 | 220 |
221 void jabber_bosh_http_connection_receive_parse_header(PurpleHTTPResponse *response, char **data, int *len) { | |
222 GHashTable *header = response->header; | |
223 char *beginning = *data; | |
224 char *found = g_strstr_len(*data, len, "\r\n\r\n"); | |
225 char *field = NULL; | |
226 char *value = NULL; | |
227 char *old_data = *data; | |
228 | |
229 while (*beginning != 'H') ++beginning; | |
230 beginning[12] = 0; | |
231 response->status = atoi(&beginning[9]); | |
232 beginning = &beginning[13]; | |
233 do { | |
234 ++beginning; | |
235 } while (*beginning != '\n'); | |
236 ++beginning; | |
237 /* parse HTTP response header */ | |
238 for (;beginning != found; ++beginning) { | |
239 if (!field) field = beginning; | |
240 if (*beginning == ':') { | |
241 *beginning = 0; | |
242 value = beginning + 1; | |
243 } else if (*beginning == '\r') { | |
244 *beginning = 0; | |
245 g_hash_table_replace(header, g_strdup(field), g_strdup(value)); | |
246 value = field = 0; | |
247 ++beginning; | |
248 } | |
249 } | |
250 ++beginning; ++beginning; ++beginning; ++beginning; | |
251 /* remove the header from data buffer */ | |
252 *data = g_strdup(beginning); | |
253 g_free(old_data); | |
254 } | |
255 | |
206 static void jabber_bosh_http_connection_receive(gpointer data, gint source, PurpleInputCondition condition) { | 256 static void jabber_bosh_http_connection_receive(gpointer data, gint source, PurpleInputCondition condition) { |
207 char buffer[1024]; | 257 char buffer[1025]; |
208 int len; | 258 int len; |
209 PurpleHTTPConnection *conn = data; | 259 PurpleHTTPConnection *conn = data; |
210 PurpleHTTPResponse *response = conn->current_response; | 260 PurpleHTTPResponse *response = conn->current_response; |
211 | 261 |
212 purple_debug_info("jabber", "jabber_bosh_http_connection_receive\n"); | 262 purple_debug_info("jabber", "jabber_bosh_http_connection_receive\n"); |
213 if (!response) { | |
214 // new response | |
215 response = conn->current_response = g_new0(PurpleHTTPResponse, 1); | |
216 jabber_bosh_http_response_init(response); | |
217 } | |
218 | 263 |
219 len = read(source, buffer, 1024); | 264 len = read(source, buffer, 1024); |
220 if (len > 0) { | 265 if (len > 0) { |
221 char *found = NULL; | 266 buffer[len] = 0; |
222 if (found = g_strstr_len(buffer, len, "\r\n\r\n")) { | 267 if (conn->current_data == NULL) { |
223 char *beginning = buffer; | 268 conn->current_len = len; |
224 char *field = NULL; | 269 conn->current_data = g_strdup_printf("%s", buffer); |
225 char *value = NULL; | 270 } else { |
226 char *cl = NULL; | 271 char *old_data = conn->current_data; |
227 | 272 conn->current_len += len; |
228 while (*beginning != 'H') ++beginning; | 273 conn->current_data = g_strdup_printf("%s%s", conn->current_data, buffer); |
229 beginning[12] = 0; | 274 g_free(old_data); |
230 response->status = atoi(&beginning[9]); | 275 } |
231 beginning = &beginning[13]; | 276 |
232 do { | 277 if (!response) { |
233 ++beginning; | 278 /* check for header footer */ |
234 } while (*beginning != '\n'); | 279 char *found = NULL; |
235 ++beginning; | 280 if (found = g_strstr_len(conn->current_data, conn->current_len, "\r\n\r\n")) { |
236 /* parse HTTP response header */ | 281 // new response |
237 for (;beginning != found; ++beginning) { | 282 response = conn->current_response = g_new0(PurpleHTTPResponse, 1); |
238 if (!field) field = beginning; | 283 jabber_bosh_http_response_init(response); |
239 if (*beginning == ':') { | 284 jabber_bosh_http_connection_receive_parse_header(response, &(conn->current_data), &(conn->current_len)); |
240 *beginning = 0; | 285 response->data_len = atoi(g_hash_table_lookup(response->header, "Content-Length")); |
241 value = beginning + 1; | 286 jabber_bosh_http_connection_receive(data, source, condition); |
242 } else if (*beginning == '\r') { | 287 } else { |
243 *beginning = 0; | 288 printf("\nDATA: %s \n", conn->current_data); |
244 g_hash_table_replace(response->header, g_strdup(field), g_strdup(value)); | 289 printf("\nDid not receive HTTP header\n"); |
245 value = field = 0; | |
246 ++beginning; | |
247 } | |
248 } | 290 } |
249 ++found; ++found; ++found; ++found; | 291 } |
250 | 292 |
251 cl = g_hash_table_lookup(response->header, "Content-Length"); | 293 if (response) { |
252 if (cl) { | 294 if (conn->current_len >= response->data_len) { |
253 PurpleHTTPRequest *request = NULL; | 295 PurpleHTTPRequest *request = g_queue_pop_head(conn->requests); |
254 response->data_len = atoi(cl); | |
255 if (response->data <= len - (found - buffer)) response->data = g_memdup(found, response->data_len); | |
256 else printf("\nDidn't receive complete content"); | |
257 | |
258 request = g_queue_pop_head(conn->requests); | |
259 if (request) { | 296 if (request) { |
297 response->data = g_memdup(conn->current_data, response->data_len); | |
260 request->cb(request, response, conn->userdata); | 298 request->cb(request, response, conn->userdata); |
261 jabber_bosh_http_request_clean(request); | 299 jabber_bosh_http_request_clean(request); |
262 jabber_bosh_http_response_clean(response); | 300 jabber_bosh_http_response_clean(response); |
263 conn->current_response = NULL; | 301 conn->current_response = NULL; |
264 } else { | 302 } else { |
265 purple_debug_info("jabber", "received HTTP response but haven't requested anything yet.\n"); | 303 purple_debug_info("jabber", "received HTTP response but haven't requested anything yet.\n"); |
266 } | 304 } |
267 } else { | |
268 printf("\ndidn't receive length.\n"); | |
269 } | 305 } |
270 } else { | |
271 printf("\nDid not receive complete HTTP header!\n"); | |
272 } | 306 } |
273 } else { | 307 } else { |
274 purple_debug_info("jabber", "jabber_bosh_http_connection_receive: problem receiving data\n"); | 308 purple_debug_info("jabber", "jabber_bosh_http_connection_receive: problem receiving data\n"); |
275 } | 309 } |
276 } | 310 } |