comparison libpurple/protocols/msn/soap2.c @ 20534:7e69275a4eef

oim migrated to new soap code, quadruply duplicated message! the timestamp seems to be off too, but I didn't change that part at all, I need to sleep now though
author Ka-Hing Cheung <khc@hxbc.us>
date Mon, 01 Oct 2007 07:20:35 +0000
parents 66921a5c9ae9
children c49b886231d5
comparison
equal deleted inserted replaced
20533:66921a5c9ae9 20534:7e69275a4eef
31 #include "xmlnode.h" 31 #include "xmlnode.h"
32 32
33 #include <glib.h> 33 #include <glib.h>
34 #include <error.h> 34 #include <error.h>
35 35
36 #define SOAP_TIMEOUT 10 36 #define SOAP_TIMEOUT (5 * 60)
37
38 static GHashTable *conn_table = NULL;
39 37
40 typedef struct _MsnSoapRequest { 38 typedef struct _MsnSoapRequest {
41 char *path; 39 char *path;
42 MsnSoapMessage *message; 40 MsnSoapMessage *message;
43 MsnSoapCallback cb; 41 MsnSoapCallback cb;
120 msn_soap_get_connection(MsnSession *session, const char *host) 118 msn_soap_get_connection(MsnSession *session, const char *host)
121 { 119 {
122 MsnSoapConnection *conn = NULL; 120 MsnSoapConnection *conn = NULL;
123 121
124 if (session->soap_table) { 122 if (session->soap_table) {
125 conn = g_hash_table_lookup(conn_table, host); 123 conn = g_hash_table_lookup(session->soap_table, host);
126 } else { 124 } else {
127 session->soap_table = g_hash_table_new_full(g_str_hash, g_str_equal, 125 session->soap_table = g_hash_table_new_full(g_str_hash, g_str_equal,
128 NULL, (GDestroyNotify)msn_soap_connection_destroy); 126 NULL, (GDestroyNotify)msn_soap_connection_destroy);
129 } 127 }
130 128
205 } 203 }
206 204
207 static gboolean 205 static gboolean
208 msn_soap_handle_body(MsnSoapConnection *conn, MsnSoapMessage *response) 206 msn_soap_handle_body(MsnSoapConnection *conn, MsnSoapMessage *response)
209 { 207 {
210 xmlnode *node = response->xml; 208 xmlnode *body = xmlnode_get_child(response->xml, "Body");
211 209
212 if (strcmp(node->name, "Envelope") == 0 && 210 if (body) {
213 node->child && strcmp(node->child->name, "Header") == 0 &&
214 node->child->next) {
215 xmlnode *body = node->child->next;
216 MsnSoapRequest *request; 211 MsnSoapRequest *request;
217 212
218 if (strcmp(body->name, "Fault") == 0) { 213 if (strcmp(body->name, "Fault") == 0) {
219 xmlnode *fault = xmlnode_get_child(body, "faultcode"); 214 xmlnode *fault = xmlnode_get_child(body, "faultcode");
220 215
295 290
296 purple_debug_info("soap", "current %s\n", conn->buf->str); 291 purple_debug_info("soap", "current %s\n", conn->buf->str);
297 292
298 cursor = conn->buf->str + conn->handled_len; 293 cursor = conn->buf->str + conn->handled_len;
299 294
300 if (conn->headers_done) { 295 if (!conn->headers_done) {
296 while ((linebreak = strstr(cursor, "\r\n")) != NULL) {
297 conn->handled_len = linebreak - conn->buf->str + 2;
298
299 if (conn->response_code == 0) {
300 if (sscanf(cursor, "HTTP/1.1 %d", &conn->response_code) != 1) {
301 /* something horribly wrong */
302 purple_ssl_close(conn->ssl);
303 conn->ssl = NULL;
304 msn_soap_connection_handle_next(conn);
305 handled = TRUE;
306 break;
307 } else if (conn->response_code == 503) {
308 msn_soap_connection_sanitize(conn, TRUE);
309 msn_session_set_error(conn->session, MSN_ERROR_SERV_UNAVAILABLE, NULL);
310 return;
311 }
312 } else if (cursor == linebreak) {
313 /* blank line */
314 conn->headers_done = TRUE;
315 cursor = conn->buf->str + conn->handled_len;
316 break;
317 } else {
318 char *line = g_strndup(cursor, linebreak - cursor);
319 char *sep = strstr(line, ": ");
320 char *key = line;
321 char *value;
322
323 if (sep == NULL) {
324 purple_debug_info("soap", "ignoring malformed line: %s\n", line);
325 g_free(line);
326 goto loop_end;
327 }
328
329 value = sep + 2;
330 *sep = '\0';
331 msn_soap_message_add_header(conn->message, key, value);
332 purple_debug_info("soap", "header %s: %s\n", key, value);
333
334 if ((conn->response_code == 301 || conn->response_code == 300)
335 && strcmp(key, "Location") == 0) {
336
337 msn_soap_handle_redirect(conn, value);
338
339 handled = TRUE;
340 g_free(line);
341 break;
342 } else if (conn->response_code == 401 &&
343 strcmp(key, "WWW-Authenticate") == 0) {
344 char *error = strstr(value, "cbtxt=");
345
346 if (error) {
347 error += strlen("cbtxt=");
348 }
349
350 msn_soap_connection_sanitize(conn, TRUE);
351 msn_session_set_error(conn->session, MSN_ERROR_AUTH,
352 error ? purple_url_decode(error) : NULL);
353
354 g_free(line);
355 return;
356 } else if (strcmp(key, "Content-Length") == 0) {
357 conn->body_len = atoi(value);
358 } else if (strcmp(key, "Connection") == 0) {
359 if (strcmp(value, "close") == 0) {
360 conn->close_when_done = TRUE;
361 }
362 }
363 }
364
365 loop_end:
366 cursor = conn->buf->str + conn->handled_len;
367 }
368 }
369
370 if (!handled && conn->headers_done) {
301 if (conn->buf->len - conn->handled_len >= 371 if (conn->buf->len - conn->handled_len >=
302 conn->body_len) { 372 conn->body_len) {
303 xmlnode *node = xmlnode_from_str(cursor, conn->body_len); 373 xmlnode *node = xmlnode_from_str(cursor, conn->body_len);
304 374
305 if (node == NULL) { 375 if (node == NULL) {
316 386
317 msn_soap_connection_handle_next(conn); 387 msn_soap_connection_handle_next(conn);
318 } 388 }
319 389
320 return; 390 return;
321 }
322
323 while ((linebreak = strstr(cursor, "\r\n")) != NULL) {
324 conn->handled_len = linebreak - conn->buf->str + 2;
325
326 if (conn->response_code == 0) {
327 if (sscanf(cursor, "HTTP/1.1 %d", &conn->response_code) != 1) {
328 /* something horribly wrong */
329 purple_ssl_close(conn->ssl);
330 conn->ssl = NULL;
331 msn_soap_connection_handle_next(conn);
332 handled = TRUE;
333 break;
334 } else if (conn->response_code == 503) {
335 msn_soap_connection_sanitize(conn, TRUE);
336 msn_session_set_error(conn->session, MSN_ERROR_SERV_UNAVAILABLE, NULL);
337 return;
338 }
339 } else if (cursor == linebreak) {
340 /* blank line */
341 conn->headers_done = TRUE;
342 } else {
343 char *line = g_strndup(cursor, linebreak - cursor);
344 char *sep = strstr(line, ": ");
345 char *key = line;
346 char *value;
347
348 if (sep == NULL) {
349 purple_debug_info("soap", "ignoring malformed line: %s\n", line);
350 g_free(line);
351 goto loop_end;
352 }
353
354 value = sep + 2;
355 *sep = '\0';
356 msn_soap_message_add_header(conn->message, key, value);
357 purple_debug_info("soap", "header %s: %s\n", key, value);
358
359 if ((conn->response_code == 301 || conn->response_code == 300)
360 && strcmp(key, "Location") == 0) {
361
362 msn_soap_handle_redirect(conn, value);
363
364 handled = TRUE;
365 g_free(line);
366 break;
367 } else if (conn->response_code == 401 &&
368 strcmp(key, "WWW-Authenticate") == 0) {
369 char *error = strstr(value, "cbtxt=");
370
371 if (error) {
372 error += strlen("cbtxt=");
373 }
374
375 msn_soap_connection_sanitize(conn, TRUE);
376 msn_session_set_error(conn->session, MSN_ERROR_AUTH,
377 error ? purple_url_decode(error) : NULL);
378
379 g_free(line);
380 return;
381 } else if (strcmp(key, "Content-Length") == 0) {
382 conn->body_len = atoi(value);
383 } else if (strcmp(key, "Connection") == 0) {
384 if (strcmp(value, "close") == 0) {
385 conn->close_when_done = TRUE;
386 }
387 }
388 }
389
390 loop_end:
391 cursor = conn->buf->str + conn->handled_len;
392 } 391 }
393 392
394 if (handled) { 393 if (handled) {
395 msn_soap_connection_handle_next(conn); 394 msn_soap_connection_handle_next(conn);
396 } 395 }