Mercurial > pidgin
comparison libpurple/protocols/msn/soap2.c @ 23475:f85450504940
propagate from branch 'im.pidgin.pidgin' (head 5387bc28fa09b238593c3dc292863ec3ce5f3c4e)
to branch 'im.pidgin.cpw.qulogic.msn' (head f2d5cd45d05d5b074677524bb08f2069d0683b09)
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Sat, 14 Jun 2008 07:47:38 +0000 |
parents | f06adc198c1d 06b491a23d19 |
children | 314fcd0879ec |
comparison
equal
deleted
inserted
replaced
23365:ef4dbd2bb696 | 23475:f85450504940 |
---|---|
80 MsnSoapMessage *message, const char *host, const char *path, | 80 MsnSoapMessage *message, const char *host, const char *path, |
81 MsnSoapCallback cb, gpointer cb_data, gboolean first); | 81 MsnSoapCallback cb, gpointer cb_data, gboolean first); |
82 | 82 |
83 static void msn_soap_request_destroy(MsnSoapRequest *req); | 83 static void msn_soap_request_destroy(MsnSoapRequest *req); |
84 static void msn_soap_connection_sanitize(MsnSoapConnection *conn, gboolean disconnect); | 84 static void msn_soap_connection_sanitize(MsnSoapConnection *conn, gboolean disconnect); |
85 static gboolean msn_soap_write_cb_internal(gpointer data, gint fd, PurpleInputCondition cond, gboolean initial); | |
85 static void msn_soap_process(MsnSoapConnection *conn); | 86 static void msn_soap_process(MsnSoapConnection *conn); |
86 | 87 |
87 static gboolean | 88 static gboolean |
88 msn_soap_cleanup_each(gpointer key, gpointer value, gpointer data) | 89 msn_soap_cleanup_each(gpointer key, gpointer value, gpointer data) |
89 { | 90 { |
230 msn_soap_handle_redirect(conn, urldata); | 231 msn_soap_handle_redirect(conn, urldata); |
231 g_free(urldata); | 232 g_free(urldata); |
232 } | 233 } |
233 | 234 |
234 g_free(faultdata); | 235 g_free(faultdata); |
236 msn_soap_message_destroy(response); | |
235 return TRUE; | 237 return TRUE; |
236 } else if (g_str_equal(faultdata, "wsse:FailedAuthentication")) { | 238 } else if (g_str_equal(faultdata, "wsse:FailedAuthentication")) { |
237 xmlnode *reason = xmlnode_get_child(body, "faultstring"); | 239 xmlnode *reason = xmlnode_get_child(body, "faultstring"); |
238 char *reasondata = xmlnode_get_data(reason); | 240 char *reasondata = xmlnode_get_data(reason); |
239 | 241 |
241 msn_session_set_error(conn->session, MSN_ERROR_AUTH, | 243 msn_session_set_error(conn->session, MSN_ERROR_AUTH, |
242 reasondata); | 244 reasondata); |
243 | 245 |
244 g_free(reasondata); | 246 g_free(reasondata); |
245 g_free(faultdata); | 247 g_free(faultdata); |
248 msn_soap_message_destroy(response); | |
246 return FALSE; | 249 return FALSE; |
247 } | 250 } |
248 | 251 |
249 g_free(faultdata); | 252 g_free(faultdata); |
250 } | 253 } |
253 if (fault || body) { | 256 if (fault || body) { |
254 MsnSoapRequest *request = conn->current_request; | 257 MsnSoapRequest *request = conn->current_request; |
255 conn->current_request = NULL; | 258 conn->current_request = NULL; |
256 request->cb(request->message, response, | 259 request->cb(request->message, response, |
257 request->cb_data); | 260 request->cb_data); |
261 msn_soap_message_destroy(response); | |
258 msn_soap_request_destroy(request); | 262 msn_soap_request_destroy(request); |
259 } | 263 } |
260 | 264 |
261 return TRUE; | 265 return TRUE; |
262 } | 266 } |
404 MsnSoapMessage *message = conn->message; | 408 MsnSoapMessage *message = conn->message; |
405 conn->message = NULL; | 409 conn->message = NULL; |
406 message->xml = node; | 410 message->xml = node; |
407 | 411 |
408 if (!msn_soap_handle_body(conn, message)) { | 412 if (!msn_soap_handle_body(conn, message)) { |
409 msn_soap_message_destroy(message); | |
410 return; | 413 return; |
411 } | 414 } |
412 msn_soap_message_destroy(message); | |
413 } | 415 } |
414 | 416 |
415 msn_soap_connection_handle_next(conn); | 417 msn_soap_connection_handle_next(conn); |
416 } | 418 } |
417 | 419 |
424 } | 426 } |
425 | 427 |
426 static void | 428 static void |
427 msn_soap_write_cb(gpointer data, gint fd, PurpleInputCondition cond) | 429 msn_soap_write_cb(gpointer data, gint fd, PurpleInputCondition cond) |
428 { | 430 { |
431 msn_soap_write_cb_internal(data, fd, cond, FALSE); | |
432 } | |
433 | |
434 static gboolean | |
435 msn_soap_write_cb_internal(gpointer data, gint fd, PurpleInputCondition cond, | |
436 gboolean initial) | |
437 { | |
429 MsnSoapConnection *conn = data; | 438 MsnSoapConnection *conn = data; |
430 int written; | 439 int written; |
431 | 440 |
432 g_return_if_fail(cond == PURPLE_INPUT_WRITE); | 441 if (cond != PURPLE_INPUT_WRITE) return TRUE; |
433 | 442 |
434 written = purple_ssl_write(conn->ssl, conn->buf->str + conn->handled_len, | 443 written = purple_ssl_write(conn->ssl, conn->buf->str + conn->handled_len, |
435 conn->buf->len - conn->handled_len); | 444 conn->buf->len - conn->handled_len); |
436 | 445 |
437 if (written < 0 && errno == EAGAIN) | 446 if (written < 0 && errno == EAGAIN) |
438 return; | 447 return TRUE; |
439 else if (written <= 0) { | 448 else if (written <= 0) { |
440 purple_ssl_close(conn->ssl); | 449 purple_ssl_close(conn->ssl); |
441 conn->ssl = NULL; | 450 conn->ssl = NULL; |
442 msn_soap_connection_handle_next(conn); | 451 if (!initial) msn_soap_connection_handle_next(conn); |
443 return; | 452 return FALSE; |
444 } | 453 } |
445 | 454 |
446 conn->handled_len += written; | 455 conn->handled_len += written; |
447 | 456 |
448 if (conn->handled_len < conn->buf->len) | 457 if (conn->handled_len < conn->buf->len) |
449 return; | 458 return TRUE; |
450 | 459 |
451 /* we are done! */ | 460 /* we are done! */ |
452 g_string_free(conn->buf, TRUE); | 461 g_string_free(conn->buf, TRUE); |
453 conn->buf = NULL; | 462 conn->buf = NULL; |
454 conn->handled_len = 0; | 463 conn->handled_len = 0; |
458 conn->close_when_done = FALSE; | 467 conn->close_when_done = FALSE; |
459 | 468 |
460 purple_input_remove(conn->event_handle); | 469 purple_input_remove(conn->event_handle); |
461 conn->event_handle = purple_input_add(conn->ssl->fd, PURPLE_INPUT_READ, | 470 conn->event_handle = purple_input_add(conn->ssl->fd, PURPLE_INPUT_READ, |
462 msn_soap_read_cb, conn); | 471 msn_soap_read_cb, conn); |
472 return TRUE; | |
463 } | 473 } |
464 | 474 |
465 static gboolean | 475 static gboolean |
466 msn_soap_connection_run(gpointer data) | 476 msn_soap_connection_run(gpointer data) |
467 { | 477 { |
476 443, msn_soap_connected_cb, msn_soap_error_cb, conn); | 486 443, msn_soap_connected_cb, msn_soap_error_cb, conn); |
477 } else if (conn->connected) { | 487 } else if (conn->connected) { |
478 int len = -1; | 488 int len = -1; |
479 char *body = xmlnode_to_str(req->message->xml, &len); | 489 char *body = xmlnode_to_str(req->message->xml, &len); |
480 GSList *iter; | 490 GSList *iter; |
481 char *authstr = NULL; | |
482 | 491 |
483 g_queue_pop_head(conn->queue); | 492 g_queue_pop_head(conn->queue); |
484 | 493 |
485 conn->buf = g_string_new(""); | 494 conn->buf = g_string_new(""); |
486 | |
487 if (conn->session->passport_info.mspauth) | |
488 authstr = g_strdup_printf("Cookie: MSPAuth=%s\r\n", | |
489 conn->session->passport_info.mspauth); | |
490 | |
491 | 495 |
492 g_string_append_printf(conn->buf, | 496 g_string_append_printf(conn->buf, |
493 "POST %s HTTP/1.1\r\n" | 497 "POST %s HTTP/1.1\r\n" |
494 "SOAPAction: %s\r\n" | 498 "SOAPAction: %s\r\n" |
495 "Content-Type:text/xml; charset=utf-8\r\n" | 499 "Content-Type:text/xml; charset=utf-8\r\n" |
496 "%s" | |
497 "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n" | 500 "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n" |
498 "Accept: */*\r\n" | 501 "Accept: */*\r\n" |
499 "Host: %s\r\n" | 502 "Host: %s\r\n" |
500 "Content-Length: %d\r\n" | 503 "Content-Length: %d\r\n" |
501 "Connection: Keep-Alive\r\n" | 504 "Connection: Keep-Alive\r\n" |
502 "Cache-Control: no-cache\r\n", | 505 "Cache-Control: no-cache\r\n", |
503 req->path, req->message->action ? req->message->action : "", | 506 req->path, req->message->action ? req->message->action : "", |
504 authstr ? authstr : "", conn->host, len); | 507 conn->host, len); |
505 | 508 |
506 for (iter = req->message->headers; iter; iter = iter->next) { | 509 for (iter = req->message->headers; iter; iter = iter->next) { |
507 g_string_append(conn->buf, (char *)iter->data); | 510 g_string_append(conn->buf, (char *)iter->data); |
508 g_string_append(conn->buf, "\r\n"); | 511 g_string_append(conn->buf, "\r\n"); |
509 } | 512 } |
516 conn->handled_len = 0; | 519 conn->handled_len = 0; |
517 conn->current_request = req; | 520 conn->current_request = req; |
518 | 521 |
519 conn->event_handle = purple_input_add(conn->ssl->fd, | 522 conn->event_handle = purple_input_add(conn->ssl->fd, |
520 PURPLE_INPUT_WRITE, msn_soap_write_cb, conn); | 523 PURPLE_INPUT_WRITE, msn_soap_write_cb, conn); |
521 msn_soap_write_cb(conn, conn->ssl->fd, PURPLE_INPUT_WRITE); | 524 if (!msn_soap_write_cb_internal(conn, conn->ssl->fd, PURPLE_INPUT_WRITE, TRUE)) { |
522 | 525 /* Not connected => reconnect and retry */ |
523 g_free(authstr); | 526 purple_debug_info("soap", "not connected, reconnecting"); |
527 | |
528 conn->connected = FALSE; | |
529 conn->current_request = NULL; | |
530 msn_soap_connection_sanitize(conn, FALSE); | |
531 | |
532 g_queue_push_head(conn->queue, req); | |
533 conn->event_handle = purple_timeout_add(0, msn_soap_connection_run, conn); | |
534 } | |
535 | |
524 g_free(body); | 536 g_free(body); |
525 } | 537 } |
526 } | 538 } |
527 | 539 |
528 return FALSE; | 540 return FALSE; |
671 g_free(req->path); | 683 g_free(req->path); |
672 msn_soap_message_destroy(req->message); | 684 msn_soap_message_destroy(req->message); |
673 g_free(req); | 685 g_free(req); |
674 } | 686 } |
675 | 687 |
676 xmlnode * | |
677 msn_soap_xml_get(xmlnode *parent, const char *node) | |
678 { | |
679 xmlnode *ret = NULL; | |
680 char **tokens = g_strsplit(node, "/", -1); | |
681 int i; | |
682 | |
683 for (i = 0; tokens[i]; i++) { | |
684 if ((ret = xmlnode_get_child(parent, tokens[i])) != NULL) | |
685 parent = ret; | |
686 else | |
687 break; | |
688 } | |
689 | |
690 g_strfreev(tokens); | |
691 return ret; | |
692 } | |
693 |