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