comparison libpurple/protocols/msn/soap.c @ 20479:6a8463be5b23

Improve MSN_SOAP_DEBUG and workaround a Win32 bug which would case Pidgin to consume insane amounts of memory when printing a large string to the Debug Window.
author Carlos Silva <typ0@pidgin.im>
date Wed, 08 Aug 2007 23:01:44 +0000
parents c1c4468207fa
children eb93710aec4d
comparison
equal deleted inserted replaced
20478:c1c4468207fa 20479:6a8463be5b23
64 PurpleInputCondition cond) 64 PurpleInputCondition cond)
65 { 65 {
66 MsnSoapConn * soapconn; 66 MsnSoapConn * soapconn;
67 MsnSession *session; 67 MsnSession *session;
68 68
69 purple_debug_info("MSN SOAP","SOAP server connection established!\n"); 69 purple_debug_misc("MSN SOAP","SOAP server connection established!\n");
70 70
71 soapconn = data; 71 soapconn = data;
72 g_return_if_fail(soapconn != NULL); 72 g_return_if_fail(soapconn != NULL);
73 73
74 session = soapconn->session; 74 session = soapconn->session;
91 msn_soap_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, void *data) 91 msn_soap_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, void *data)
92 { 92 {
93 MsnSoapConn * soapconn = data; 93 MsnSoapConn * soapconn = data;
94 94
95 g_return_if_fail(data != NULL); 95 g_return_if_fail(data != NULL);
96 purple_debug_info("MSN SOAP","Soap connection error!\n"); 96 purple_debug_warning("MSN SOAP","Soap connection error!\n");
97 msn_soap_set_process_step(soapconn, MSN_SOAP_UNCONNECTED); 97 msn_soap_set_process_step(soapconn, MSN_SOAP_UNCONNECTED);
98 98
99 /*error callback*/ 99 /*error callback*/
100 if(soapconn->error_cb != NULL){ 100 if(soapconn->error_cb != NULL){
101 soapconn->error_cb(gsc,error,data); 101 soapconn->error_cb(gsc,error,data);
106 void 106 void
107 msn_soap_init(MsnSoapConn *soapconn,char * host,int ssl, 107 msn_soap_init(MsnSoapConn *soapconn,char * host,int ssl,
108 PurpleSslInputFunction connect_cb, 108 PurpleSslInputFunction connect_cb,
109 PurpleSslErrorFunction error_cb) 109 PurpleSslErrorFunction error_cb)
110 { 110 {
111 purple_debug_info("MSN SOAP","msn_soap_init()\n"); 111 purple_debug_misc("MSN SOAP","Initializing SOAP connection\n");
112 soapconn->login_host = g_strdup(host); 112 soapconn->login_host = g_strdup(host);
113 soapconn->ssl_conn = ssl; 113 soapconn->ssl_conn = ssl;
114 soapconn->connect_cb = connect_cb; 114 soapconn->connect_cb = connect_cb;
115 soapconn->error_cb = error_cb; 115 soapconn->error_cb = error_cb;
116 } 116 }
216 len = purple_ssl_read(soapconn->gsc, temp_buf, requested_len); 216 len = purple_ssl_read(soapconn->gsc, temp_buf, requested_len);
217 } else { 217 } else {
218 len = read(soapconn->fd, temp_buf, requested_len); 218 len = read(soapconn->fd, temp_buf, requested_len);
219 } 219 }
220 220
221
221 if ( len <= 0 ) { 222 if ( len <= 0 ) {
222 switch (errno) { 223 switch (errno) {
223 224
224 case 0: 225 case 0:
225 case EBADF: /* we are sometimes getting this in Windows */ 226 case EBADF: /* we are sometimes getting this in Windows */
226 case EAGAIN: 227 case EAGAIN: return len;
227 #ifdef MSN_SOAP_DEBUG 228
228 purple_debug_info("MSN SOAP",
229 "msn_soap_read(): %s, returning len = %d.\n",
230 strerror(errno), len);
231 #endif
232 return len;
233 default : purple_debug_error("MSN SOAP", "Read error!" 229 default : purple_debug_error("MSN SOAP", "Read error!"
234 "read len: %d, error = %s\n", 230 "read len: %d, error = %s\n",
235 len, strerror(errno)); 231 len, strerror(errno));
236 purple_input_remove(soapconn->input_handler); 232 purple_input_remove(soapconn->input_handler);
237 soapconn->input_handler = -1; 233 soapconn->input_handler = -1;
241 /* TODO: error handling */ 237 /* TODO: error handling */
242 return len; 238 return len;
243 } 239 }
244 } 240 }
245 else { 241 else {
246 #ifdef MSN_SOAP_DEBUG
247 purple_debug_info("MSN SOAP", "Allocating space for more %d bytes from incoming data. Total space now (according to soapconn->read_len = %d\n", len, soapconn->read_len);
248 #endif
249 soapconn->read_buf = g_realloc(soapconn->read_buf, 242 soapconn->read_buf = g_realloc(soapconn->read_buf,
250 soapconn->read_len + len + 1); 243 soapconn->read_len + len + 1);
251 if ( soapconn->read_buf != NULL ) { 244 if ( soapconn->read_buf != NULL ) {
252 memcpy(soapconn->read_buf + soapconn->read_len, temp_buf, len); 245 memcpy(soapconn->read_buf + soapconn->read_len, temp_buf, len);
253 soapconn->read_len += len; 246 soapconn->read_len += len;
258 exit(EXIT_FAILURE); 251 exit(EXIT_FAILURE);
259 } 252 }
260 253
261 } 254 }
262 255
263 #ifdef MSN_SOAP_DEBUG 256 #if defined(MSN_SOAP_DEBUG)
264 purple_debug_info("MSN SOAP","Read SOAP bytes: %d\n", len); 257 if (len > 0)
265 258 purple_debug_info("MSN SOAP","Read %d bytes from SOAP server:\n%s\n", len, soapconn->read_buf + soapconn->read_len - len);
266 if (len > -1) { 259 #endif
267 gchar * soapbody = NULL; 260
268 xmlnode * node = NULL;
269 soapbody = g_strstr_len(soapconn->read_buf, soapconn->read_len, "\r\n\r\n");
270 if (soapbody != NULL)
271 node = xmlnode_from_str(soapbody+4, -1);
272
273 if (node != NULL) {
274 gchar *pretty = xmlnode_to_formatted_str(node, NULL);
275 gchar *http_headers, *delimiter;
276
277 delimiter = g_strstr_len(soapconn->read_buf, soapconn->read_len,"\r\n\r\n");
278 if (delimiter != NULL) {
279
280 http_headers = g_strndup(soapconn->read_buf, delimiter + 4 - soapconn->read_buf);
281 purple_debug_info("MSN SOAP","Nexus server read data:\n%s%s\n", http_headers, pretty);
282 g_free(http_headers);
283 }
284 else
285 purple_debug_info("MSN SOAP","Nexus server read data:\n%s\n", soapconn->read_buf);
286
287 g_free(pretty);
288 xmlnode_free(node);
289 }
290 else
291 purple_debug_info("MSN SOAP","Received data from Nexus server:\n%s\n", soapconn->read_buf);
292
293 }
294 #endif
295 return len; 261 return len;
296 } 262 }
297 263
298 /*read the whole SOAP server response*/ 264 /*read the whole SOAP server response*/
299 void 265 void
302 MsnSoapConn *soapconn = data; 268 MsnSoapConn *soapconn = data;
303 MsnSession *session; 269 MsnSession *session;
304 int len; 270 int len;
305 char * body_start,*body_len; 271 char * body_start,*body_len;
306 char *length_start,*length_end; 272 char *length_start,*length_end;
307
308 #ifdef MSN_SOAP_DEBUG 273 #ifdef MSN_SOAP_DEBUG
274 #if !defined(_WIN32)
275 gchar * formattedxml = NULL;
276 gchar * http_headers = NULL;
277 xmlnode * node = NULL;
278 #endif
309 purple_debug_misc("MSN SOAP", "msn_soap_read_cb()\n"); 279 purple_debug_misc("MSN SOAP", "msn_soap_read_cb()\n");
310 #endif 280 #endif
311 session = soapconn->session; 281 session = soapconn->session;
312 g_return_if_fail(session != NULL); 282 g_return_if_fail(session != NULL);
313 283
314 284
315
316 /*read the request header*/ 285 /*read the request header*/
317 len = msn_soap_read(soapconn); 286 len = msn_soap_read(soapconn);
318 287
319 if ( len < 0 ) 288 if ( len < 0 )
320 return; 289 return;
466 /*setup the conn body */ 435 /*setup the conn body */
467 soapconn->body = body_start; 436 soapconn->body = body_start;
468 soapconn->body_len = atoi(body_len); 437 soapconn->body_len = atoi(body_len);
469 g_free(body_len); 438 g_free(body_len);
470 #ifdef MSN_SOAP_DEBUG 439 #ifdef MSN_SOAP_DEBUG
471 purple_debug_misc("MSN SOAP","SOAP Read length: %d, Body len: %d\n", soapconn->read_len, soapconn->body_len); 440 purple_debug_misc("MSN SOAP","SOAP bytes read so far: %d, Content-Length: %d\n", soapconn->read_len, soapconn->body_len);
472 #endif 441 #endif
473 soapconn->need_to_read = (body_start - soapconn->read_buf + soapconn->body_len) - soapconn->read_len; 442 soapconn->need_to_read = (body_start - soapconn->read_buf + soapconn->body_len) - soapconn->read_len;
474 if ( soapconn->need_to_read > 0 ) { 443 if ( soapconn->need_to_read > 0 ) {
475 return; 444 return;
476 } 445 }
446
447 #if defined(MSN_SOAP_DEBUG) && !defined(_WIN32)
448
449 node = xmlnode_from_str(soapconn->body, soapconn->body_len);
450
451 if (node != NULL) {
452 formattedxml = xmlnode_to_formatted_str(node, NULL);
453 http_headers = g_strndup(soapconn->read_buf, soapconn->body - soapconn->read_buf);
454
455 purple_debug_info("MSN SOAP","Data with XML payload received from the SOAP server:\n%s%s\n", http_headers, formattedxml);
456 g_free(http_headers);
457 g_free(formattedxml);
458 xmlnode_free(node);
459 }
460 else
461 purple_debug_info("MSN SOAP","Data received from the SOAP server:\n%s\n", soapconn->read_buf);
462 #endif
477 463
478 /*remove the read handler*/ 464 /*remove the read handler*/
479 purple_input_remove(soapconn->input_handler); 465 purple_input_remove(soapconn->input_handler);
480 soapconn->input_handler = -1; 466 soapconn->input_handler = -1;
481 /* 467 /*
656 g_queue_push_tail(soapconn->soap_queue, request); 642 g_queue_push_tail(soapconn->soap_queue, request);
657 } 643 }
658 if (!msn_soap_connected(soapconn) && (soapconn->step == MSN_SOAP_UNCONNECTED) 644 if (!msn_soap_connected(soapconn) && (soapconn->step == MSN_SOAP_UNCONNECTED)
659 &&(!g_queue_is_empty(soapconn->soap_queue))) { 645 &&(!g_queue_is_empty(soapconn->soap_queue))) {
660 /*not connected?and we have something to process connect it first*/ 646 /*not connected?and we have something to process connect it first*/
661 purple_debug_info("MSN SOAP","No connection to SOAP server. Connecting...\n"); 647 purple_debug_misc("MSN SOAP","No connection to SOAP server. Connecting...\n");
662 msn_soap_init_func(soapconn); 648 msn_soap_init_func(soapconn);
663 msn_soap_connect(soapconn); 649 msn_soap_connect(soapconn);
664 return; 650 return;
665 } 651 }
666 purple_debug_info("MSN SOAP","Connected to SOAP server!\n"); 652 purple_debug_misc("MSN SOAP","Connected to SOAP server!\n");
667 653
668 /*if connected, what we only needed to do is to queue the request, 654 /*if connected, what we only needed to do is to queue the request,
669 * when SOAP request in the queue processed done, will do this command. 655 * when SOAP request in the queue processed done, will do this command.
670 * we just waiting... 656 * we just waiting...
671 * If we send the request this time,error may occure 657 * If we send the request this time,error may occure
681 void 667 void
682 msn_soap_post_request(MsnSoapConn *soapconn,MsnSoapReq *request) 668 msn_soap_post_request(MsnSoapConn *soapconn,MsnSoapReq *request)
683 { 669 {
684 char * soap_head = NULL; 670 char * soap_head = NULL;
685 char * request_str = NULL; 671 char * request_str = NULL;
686
687 #ifdef MSN_SOAP_DEBUG 672 #ifdef MSN_SOAP_DEBUG
673 #if !defined(_WIN32)
688 xmlnode * node; 674 xmlnode * node;
689 675 #endif
690 purple_debug_info("MSN SOAP","msn_soap_post_request()...\n"); 676 purple_debug_misc("MSN SOAP","msn_soap_post_request()\n");
691 #endif 677 #endif
678
692 msn_soap_set_process_step(soapconn,MSN_SOAP_PROCESSING); 679 msn_soap_set_process_step(soapconn,MSN_SOAP_PROCESSING);
693 soap_head = g_strdup_printf( 680 soap_head = g_strdup_printf(
694 "POST %s HTTP/1.1\r\n" 681 "POST %s HTTP/1.1\r\n"
695 "SOAPAction: %s\r\n" 682 "SOAPAction: %s\r\n"
696 "Content-Type:text/xml; charset=utf-8\r\n" 683 "Content-Type:text/xml; charset=utf-8\r\n"
707 request->login_host, 694 request->login_host,
708 strlen(request->body) 695 strlen(request->body)
709 ); 696 );
710 request_str = g_strdup_printf("%s%s", soap_head, request->body); 697 request_str = g_strdup_printf("%s%s", soap_head, request->body);
711 698
712 #ifdef MSN_SOAP_DEBUG 699 #if defined(MSN_SOAP_DEBUG) && !defined(_WIN32)
713 node = xmlnode_from_str(request->body, -1); 700 node = xmlnode_from_str(request->body, -1);
714 if (node != NULL) { 701 if (node != NULL) {
715 char *pretty = xmlnode_to_formatted_str(node, NULL); 702 char *formattedstr = xmlnode_to_formatted_str(node, NULL);
716 purple_debug_info("MSN SOAP","Posting request to SOAP server:\n%s%s\n",soap_head, pretty); 703 purple_debug_info("MSN SOAP","Posting request to SOAP server:\n%s%s\n",soap_head, formattedstr);
717 g_free(pretty); 704 g_free(formattedstr);
718 xmlnode_free(node); 705 xmlnode_free(node);
719 } 706 }
720 else 707 else
721 purple_debug_info("MSN SOAP","Failed to parse SOAP request:\n%s\n", request_str); 708 purple_debug_info("MSN SOAP","Failed to parse SOAP request being sent:\n%s\n", request_str);
722 #endif 709 #endif
723 710
724 g_free(soap_head); 711 g_free(soap_head);
725 /*free read buffer*/ 712 /*free read buffer*/
726 msn_soap_free_read_buf(soapconn); 713 msn_soap_free_read_buf(soapconn);