1 /*
2 * Portions of this file Copyright 1999-2005 University of Chicago
3 * Portions of this file Copyright 1999-2005 The University of Southern California.
4 *
5 * This file or a portion of this file is licensed under the
6 * terms of the Globus Toolkit Public License, found at
7 * http://www.globus.org/toolkit/download/license.html.
8 * If you redistribute this file, with or without
9 * modifications, you must include this notice in the file.
10 */
11
12
13 #include "globus_common.h"
14 #include "globus_xio_buffer.h"
15 #include "globus_xio_tcp_driver.h"
16 #include "globus_xio_http.h"
17 #include "globus_soap_message_handle.h"
18 #include "globus_i_soap_message.h"
19 #include "globus_soap_message.h"
20 #include "globus_soap_message_attrs.h"
21 #include "globus_xio_gsi.h"
22
23 static
24 void
25 globus_l_soap_message_response_ready_callback(
26 globus_xio_handle_t handle,
27 globus_result_t result,
28 globus_byte_t * buffer,
29 globus_size_t len,
30 globus_size_t nbytes,
31 globus_xio_data_descriptor_t data_desc,
32 void * user_arg);
33
34 typedef struct
35 {
36 struct globus_soap_message_handle_s * message;
37 globus_soap_message_callback_func_t callback;
38 void * args;
39 enum
40 {
41 GLOBUS_SOAP_MESSAGE_REQUEST_CALLBACK,
42 GLOBUS_SOAP_MESSAGE_RESPONSE_CALLBACK
43 } type;
44 } globus_l_soap_message_callback_handle_t;
45
46
47 void
48 globus_l_soap_message_error_callback(
49 void * arg,
50 const char * msg,
51 xmlParserSeverities severity,
52 xmlTextReaderLocatorPtr locator)
53 0 {
54 globus_soap_message_handle_t handle;
55 int lno;
56 xmlChar * baseuri;
57 GlobusFuncName(globus_i_soap_message_error_callback);
58 0 GlobusSoapMessageDebugEnter();
59
60 0 handle = (globus_soap_message_handle_t) arg;
61 0 if(handle->result != GLOBUS_SUCCESS)
62 {
63 0 return;
64 }
65
66 0 if(handle->result != GLOBUS_SUCCESS)
67 {
68 0 return;
69 }
70
71 0 if(locator)
72 {
73 0 lno = xmlTextReaderLocatorLineNumber(locator);
74 0 baseuri = xmlTextReaderLocatorBaseURI(locator);
75 }
76
77 0 switch(severity)
78 {
79 case XML_PARSER_SEVERITY_ERROR:
80 case XML_PARSER_SEVERITY_VALIDITY_ERROR:
81
82 0 handle->result = GlobusSoapMessageErrorParserFailed(msg, lno, baseuri);
83 0 break;
84
85 case XML_PARSER_SEVERITY_WARNING:
86 case XML_PARSER_SEVERITY_VALIDITY_WARNING:
87
88 0 GlobusSoapMessageDebugPrintf(GLOBUS_SOAP_MESSAGE_DEBUG_WARN,
89 ("%s:%d: %s", baseuri, lno, msg));
90
91 default:
92 break;
93 }
94
95 0 GlobusSoapMessageDebugExit();
96 }
97
98 void
99 globus_l_soap_message_structured_error_callback(
100 void * userdata,
101 xmlErrorPtr error)
102 10 {
103 globus_soap_message_handle_t handle;
104 GlobusFuncName(globus_i_soap_message_structured_error_callback);
105 10 GlobusSoapMessageDebugEnter();
106
107 10 handle = (globus_soap_message_handle_t) userdata;
108
109 10 if(handle->result != GLOBUS_SUCCESS)
110 {
111 6 return;
112 }
113
114 6 handle->result = GlobusSoapMessageErrorParserFailed(
115 error->message, error->line, error->file);
116
117 6 GlobusSoapMessageDebugExit();
118 }
119
120 static
121 int
122 globus_l_soap_message_handle_libxml_io_read_callback(
123 void * context,
124 char * buffer,
125 int length)
126 79774 {
127 79774 globus_size_t read_length = 0;
128 globus_soap_message_handle_t handle;
129 79774 globus_result_t result = GLOBUS_SUCCESS;
130 GlobusFuncName(
131 globus_l_soap_message_handle_libxml_io_read_callback);
132 79774 GlobusSoapMessageDebugEnter();
133
134 79774 handle = (globus_soap_message_handle_t) context;
135 79774 globus_assert_string(handle, "NULL handle passed to function");
136
137 79774 if(handle->buffer_eof)
138 {
139 74801 goto exit;
140 }
141
142 74801 result = globus_xio_read(
143 handle->xio_handle, (globus_byte_t *)buffer,
144 length, 1, &read_length, NULL);
145 79997 if(result != GLOBUS_SUCCESS &&
146 globus_xio_driver_error_match(
147 globus_i_soap_message_buffer_driver,
148 globus_error_peek(result),
149 GLOBUS_XIO_BUFFER_ERROR_EOF))
150 {
151 5196 handle->result = GLOBUS_SUCCESS;
152 5196 handle->buffer_eof = 1;
153 }
154 69605 else if(result != GLOBUS_SUCCESS)
155 {
156 22 handle->result = result;
157 }
158
159 79774 exit:
160
161 79774 GlobusSoapMessageDebugExit();
162 79774 return read_length;
163 }
164
165 static
166 int
167 globus_l_soap_message_handle_libxml_io_write_callback(
168 void * context,
169 const char * buffer,
170 int length)
171 84694 {
172 84694 globus_size_t bytes_written = 0;
173 84694 globus_result_t result = GLOBUS_SUCCESS;
174 globus_soap_message_handle_t handle;
175 GlobusFuncName(
176 globus_l_soap_message_handle_libxml_io_write_callback);
177 84694 GlobusSoapMessageDebugEnter();
178
179 84694 handle = (globus_soap_message_handle_t) context;
180 84694 globus_assert_string(handle, "NULL handle passed to function");
181
182 84694 result = globus_xio_write(
183 handle->xio_handle, (globus_byte_t *) buffer,
184 length, length, &bytes_written, NULL);
185 84694 if(result != GLOBUS_SUCCESS)
186 {
187 0 handle->result = result;
188 }
189
190 84694 GlobusSoapMessageDebugExit();
191 84694 return bytes_written;
192 }
193
194 static
195 int
196 globus_l_soap_message_handle_libxml_io_close_callback(
197 void * context)
198 11472 {
199 globus_soap_message_handle_t handle;
200 GlobusFuncName(
201 globus_l_soap_message_handle_libxml_io_close_callback);
202 11472 GlobusSoapMessageDebugEnter();
203
204 11472 handle = (globus_soap_message_handle_t) context;
205 11472 globus_assert_string(handle, "NULL handle passed to function");
206
207 /* do nothing. close should be done async. */
208
209 11472 GlobusSoapMessageDebugExit();
210 11472 return 0;
211 }
212
213 static
214 void
215 globus_l_soap_message_open_callback(
216 globus_xio_handle_t handle,
217 globus_result_t result,
218 void * user_args)
219 3065 {
220 globus_l_soap_message_callback_handle_t * callback_handle;
221
222 3065 callback_handle = (globus_l_soap_message_callback_handle_t *) user_args;
223
224 3065 if(result == GLOBUS_SUCCESS)
225 {
226 3065 result = globus_soap_message_setup_writer(
227 callback_handle->message);
228 if(result != GLOBUS_SUCCESS)
229 {
230 goto exit;
231 }
232 }
233 else
234 {
235 0 callback_handle->message->result = result;
236 }
237
238
239 3065 exit:
240
241 3065 callback_handle->callback(result, callback_handle->args);
242 3065 free(callback_handle);
243 }
244
245 globus_result_t
246 globus_i_soap_message_setup_unbuffered_writer(
247 globus_soap_message_handle_t message)
248 0 {
249 0 xmlOutputBufferPtr output_buffer = NULL;
250 0 globus_result_t result = GLOBUS_SUCCESS;
251 GlobusFuncName(globus_i_soap_message_setup_unbuffered_writer);
252 0 GlobusSoapMessageDebugEnter();
253
254 0 output_buffer = xmlOutputBufferCreateIO(
255 globus_l_soap_message_handle_libxml_io_write_callback,
256 globus_l_soap_message_handle_libxml_io_close_callback,
257 message,
258 0);
259 0 if(!output_buffer)
260 {
261 0 result = GlobusSoapMessageErrorInitFailed(
262 "Failed to initialize output buffer");
263 0 goto exit;
264 }
265
266 0 message->writer = xmlNewTextWriter(output_buffer);
267 0 if(!message->writer)
268 {
269 0 result = GlobusSoapMessageErrorInitFailed(
270 "Failed to initialize xmlWriter");
271 goto free_output;
272 }
273
274 goto exit;
275
276 0 free_output:
277
278 0 xmlOutputBufferClose(output_buffer);
279
280 0 exit:
281
282 0 GlobusSoapMessageDebugExit();
283 0 return result;
284 }
285
286
287 globus_result_t
288 globus_soap_message_setup_writer(
289 globus_soap_message_handle_t message)
290 5197 {
291 5197 xmlOutputBufferPtr output_buffer = NULL;
292 5197 globus_result_t result = GLOBUS_SUCCESS;
293 GlobusFuncName(globus_soap_message_setup_writer);
294 5197 GlobusSoapMessageDebugEnter();
295
296 5197 globus_assert(message);
297
298 5197 result = globus_xio_handle_cntl(
299 message->xio_handle,
300 globus_i_soap_message_buffer_driver,
301 GLOBUS_XIO_BUFFER_CLEAR);
302 5197 if(result != GLOBUS_SUCCESS)
303 {
304 0 result = GlobusSoapMessageErrorFailedTransport(
305 result, "Failed to enable buffering for message write");
306 0 goto exit;
307 }
308
309 5197 result = globus_xio_handle_cntl(
310 message->xio_handle,
311 globus_i_soap_message_buffer_driver,
312 GLOBUS_XIO_BUFFER_ENABLE_WRITE_BUFFERING);
313 5197 if(result != GLOBUS_SUCCESS)
314 {
315 0 result = GlobusSoapMessageErrorFailedTransport(
316 result, "Failed to enable buffering for message write");
317 0 goto exit;
318 }
319
320 5197 output_buffer = xmlOutputBufferCreateIO(
321 globus_l_soap_message_handle_libxml_io_write_callback,
322 globus_l_soap_message_handle_libxml_io_close_callback,
323 message,
324 0);
325 5197 if(!output_buffer)
326 {
327 0 result = GlobusSoapMessageErrorInitFailed(
328 "Failed to initialize output buffer");
329 0 goto exit;
330 }
331
332 5197 message->writer = xmlNewTextWriter(output_buffer);
333 5197 if(!message->writer)
334 {
335 0 result = GlobusSoapMessageErrorInitFailed(
336 "Failed to initialize xmlWriter");
337 goto free_output;
338 }
339
340 goto exit;
341
342 0 free_output:
343
344 0 xmlOutputBufferClose(output_buffer);
345
346 5197 exit:
347
348 5197 GlobusSoapMessageDebugExit();
349 5197 return result;
350 }
351
352 static
353 void
354 globus_l_soap_message_flush_callback(
355 globus_xio_handle_t handle,
356 globus_result_t result,
357 globus_xio_iovec_t * iovec,
358 int count,
359 globus_size_t nbytes,
360 globus_xio_data_descriptor_t data_desc,
361 void * user_args)
362 5187 {
363 5187 globus_result_t internal_result = GLOBUS_SUCCESS;
364 static globus_byte_t buffer[1];
365 globus_l_soap_message_callback_handle_t * callback_handle;
366
367 5187 callback_handle = (globus_l_soap_message_callback_handle_t *) user_args;
368 5187 callback_handle->message->result = result;
369
370 5187 if(count > 0 && (iovec->iov_len > 0))
371 {
372 5187 internal_result = globus_xio_handle_cntl(
373 callback_handle->message->xio_handle,
374 globus_i_soap_message_http_driver,
375 GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY);
376 5187 if(internal_result != GLOBUS_SUCCESS)
377 {
378 0 internal_result = GlobusSoapMessageErrorFailedTransport(
379 internal_result,
380 "Failed to flush message");
381 0 goto error;
382 }
383 }
384
385 5187 internal_result = globus_xio_handle_cntl(
386 callback_handle->message->xio_handle,
387 globus_i_soap_message_buffer_driver,
388 GLOBUS_XIO_BUFFER_CLEAR);
389 5187 if(internal_result != GLOBUS_SUCCESS)
390 {
391 0 internal_result = GlobusSoapMessageErrorFailedTransport(
392 internal_result,
393 "Failed to flush message");
394 0 goto error;
395 }
396
397 5187 callback_handle->callback(result, callback_handle->args);
398
399 5187 if (callback_handle->type == GLOBUS_SOAP_MESSAGE_REQUEST_CALLBACK)
400 {
401 3065 result = globus_xio_register_read(handle,
402 buffer,
403 0,
404 0,
405 NULL,
406 globus_l_soap_message_response_ready_callback,
407 callback_handle->message);
408
409 3065 if(result != GLOBUS_SUCCESS)
410 {
411 0 globus_l_soap_message_response_ready_callback(
412 handle,
413 result,
414 buffer,
415 0,
416 0,
417 NULL,
418 callback_handle->message);
419 }
420 }
421 else
422 {
423 2122 globus_assert(
424 callback_handle->type == GLOBUS_SOAP_MESSAGE_RESPONSE_CALLBACK);
425 }
426
427 goto exit;
428
429 0 error:
430 0 callback_handle->callback(internal_result, callback_handle->args);
431
432 5187 exit:
433 5187 free(callback_handle);
434 }
435
436 static
437 void
438 globus_l_soap_message_read_callback(
439 globus_xio_handle_t handle,
440 globus_result_t result,
441 globus_byte_t * buffer,
442 globus_size_t len,
443 globus_size_t nbytes,
444 globus_xio_data_descriptor_t data_desc,
445 void * user_arg)
446 556973 {
447 globus_l_soap_message_callback_handle_t * callback_handle;
448 556973 globus_result_t local_result = GLOBUS_SUCCESS;
449 GlobusFuncName(globus_l_soap_message_read_callback);
450 556973 GlobusSoapMessageDebugEnter();
451
452 556973 callback_handle = (globus_l_soap_message_callback_handle_t *) user_arg;
453 556973 callback_handle->message->result = result;
454
455 556973 if(result != GLOBUS_SUCCESS)
456 {
457 10392 if(globus_xio_error_is_eof(result) ||
458 globus_xio_driver_error_match(
459 globus_i_soap_message_http_driver,
460 globus_error_peek(result), GLOBUS_XIO_HTTP_ERROR_EOF) ||
461 globus_xio_driver_error_match(
462 globus_i_soap_message_buffer_driver,
463 globus_error_peek(result), GLOBUS_XIO_BUFFER_ERROR_EOF))
464 {
465 5196 result = GLOBUS_SUCCESS;
466
467 5196 local_result = globus_xio_handle_cntl(
468 callback_handle->message->xio_handle,
469 globus_i_soap_message_buffer_driver,
470 GLOBUS_XIO_BUFFER_DONE_BUFFERING);
471 5196 if(local_result != GLOBUS_SUCCESS)
472 {
473 0 local_result = GlobusSoapMessageErrorFailedTransport(
474 local_result,
475 "Failed to disable buffering for buffer driver");
476 0 goto exit;
477 }
478
479 5196 if(GlobusSoapMessageDebug(GLOBUS_SOAP_MESSAGE_DEBUG_MESSAGES))
480 {
481 char * buffer;
482 size_t read_length;
483
484 0 globus_xio_handle_cntl(
485 callback_handle->message->xio_handle,
486 globus_i_soap_message_buffer_driver,
487 GLOBUS_XIO_BUFFER_GET_MARKED_BUFFERS,
488 NULL, NULL, &buffer, &read_length);
489
490 0 GlobusSoapMessageDebugPrintf(
491 GLOBUS_SOAP_MESSAGE_DEBUG_MESSAGES,
492 ("----------------READING--------------\n%.*s\n"
493 "=====================================\n\n",
494 read_length, buffer));
495
496 0 free(buffer);
497 }
498
499 5196 local_result = globus_xio_handle_cntl(
500 callback_handle->message->xio_handle,
501 globus_i_soap_message_buffer_driver,
502 GLOBUS_XIO_BUFFER_RESET_READ_POSITION);
503 5196 if(local_result != GLOBUS_SUCCESS)
504 {
505 0 local_result = GlobusSoapMessageErrorFailedTransport(
506 local_result,
507 "failed to reset buffer read position to start");
508 0 goto exit;
509 }
510
511 5196 if (callback_handle->message->reader != NULL)
512 {
513 1057 xmlFreeTextReader(callback_handle->message->reader);
514 }
515 5196 callback_handle->message->reader = xmlReaderForIO(
516 globus_l_soap_message_handle_libxml_io_read_callback,
517 globus_l_soap_message_handle_libxml_io_close_callback,
518 callback_handle->message,
519 NULL,
520 NULL,
521 0);
522 5196 if(!callback_handle->message->reader)
523 {
524 0 result = GlobusSoapMessageErrorInitFailed(
525 "Failed to initialize xmlReader");
526 0 goto exit;
527 }
528
529 5196 xmlTextReaderSetErrorHandler(callback_handle->message->reader,
530 globus_l_soap_message_error_callback,
531 callback_handle->message);
532
533 5196 xmlTextReaderSetStructuredErrorHandler(
534 callback_handle->message->reader,
535 globus_l_soap_message_structured_error_callback,
536 callback_handle->message);
537
538 5196 callback_handle->callback(result, callback_handle->args);
539 5196 free(callback_handle);
540 }
541 else
542 {
543 0 local_result = result;
544 }
545
546 goto exit;
547 }
548
549 551777 local_result = globus_xio_register_read(
550 callback_handle->message->xio_handle,
551 (globus_byte_t *)callback_handle->message->readbuf,
552 GLOBUS_I_SOAP_MESSAGE_READBUF_SIZE,
553 1,
554 NULL,
555 globus_l_soap_message_read_callback,
556 callback_handle);
557 551777 if(local_result != GLOBUS_SUCCESS)
558 {
559 0 local_result = GlobusSoapMessageErrorFailedTransport(
560 local_result, "Failed to begin reading SOAP message");
561 goto exit;
562 }
563
564 556973 exit:
565
566 556973 if(local_result != GLOBUS_SUCCESS)
567 {
568 0 callback_handle->message->result = local_result;
569 0 callback_handle->callback(result, callback_handle->args);
570 }
571
572 556973 GlobusSoapMessageDebugExit();
573 return;
574 }
575
576 static
577 void
578 globus_l_soap_message_response_callback(
579 void * args)
580 3065 {
581 3065 globus_result_t result = GLOBUS_SUCCESS;
582 globus_l_soap_message_callback_handle_t * callback_handle;
583 GlobusFuncName(globus_l_soap_message_response_callback);
584 3065 GlobusSoapMessageDebugEnter();
585
586 3065 callback_handle = (globus_l_soap_message_callback_handle_t *) args;
587
588 3065 if(callback_handle->message->response_semaphore >= 2)
589 {
590 3065 globus_mutex_lock(&callback_handle->message->mutex);
591 3065 callback_handle->message->response_semaphore = 0;
592 3065 globus_mutex_unlock(&callback_handle->message->mutex);
593
594 3065 if(callback_handle->message->result != GLOBUS_SUCCESS)
595 {
596 4 if (globus_error_match
597 (globus_error_peek(
598 callback_handle->message->result),
599 GLOBUS_SOAP_MESSAGE_MODULE,
600 GLOBUS_SOAP_MESSAGE_ERROR_TYPE_FAILED_TRANSPORT))
601 {
602 0 result = callback_handle->message->result;
603 0 goto exit;
604 }
605 }
606 3065 result = globus_xio_handle_cntl(
607 callback_handle->message->xio_handle,
608 globus_i_soap_message_buffer_driver,
609 GLOBUS_XIO_BUFFER_ENABLE_READ_BUFFERING);
610 3065 if(result != GLOBUS_SUCCESS)
611 {
612 0 result = GlobusSoapMessageErrorFailedTransport(
613 result, "Failed to enable read buffering in buffer driver");
614 0 goto exit;
615 }
616
617 3065 result = globus_xio_register_read(
618 callback_handle->message->xio_handle,
619 (globus_byte_t *)callback_handle->message->readbuf,
620 GLOBUS_I_SOAP_MESSAGE_READBUF_SIZE,
621 1,
622 NULL,
623 globus_l_soap_message_read_callback,
624 callback_handle);
625 3065 if(result != GLOBUS_SUCCESS)
626 {
627 0 result = GlobusSoapMessageErrorFailedTransport(
628 result, "Failed to begin reading SOAP message");
629 goto exit;
630 }
631 }
632
633 3065 exit:
634
635 3065 if(result != GLOBUS_SUCCESS)
636 {
637
638 0 callback_handle->callback(result, callback_handle->args);
639 0 free(callback_handle);
640 }
641
642 3065 GlobusSoapMessageDebugExit();
643 return;
644 }
645
646 static
647 void
648 globus_l_soap_message_response_ready_callback(
649 globus_xio_handle_t handle,
650 globus_result_t result,
651 globus_byte_t * buffer,
652 globus_size_t len,
653 globus_size_t nbytes,
654 globus_xio_data_descriptor_t data_desc,
655 void * user_arg)
656 3065 {
657 globus_soap_message_handle_t message_handle;
658 int response_code;
659 const char * message;
660 globus_xio_http_version_t version;
661 globus_hashtable_t headers;
662 GlobusFuncName(globus_l_soap_message_response_ready_callback);
663 3065 GlobusSoapMessageDebugEnter();
664
665 3065 message_handle = (globus_soap_message_handle_t) user_arg;
666
667 3065 if (result == GLOBUS_SUCCESS)
668 {
669 3065 result = globus_xio_data_descriptor_cntl(
670 data_desc,
671 globus_i_soap_message_http_driver,
672 GLOBUS_XIO_HTTP_GET_RESPONSE,
673 &response_code,
674 &message,
675 &version,
676 &headers);
677 }
678
679 3065 if(result != GLOBUS_SUCCESS)
680 {
681 0 message_handle->result = GlobusSoapMessageErrorFailedTransport(
682 result, "Error in HTTP response");
683 0 response_code = -1;
684 0 GlobusSoapMessageDebugError(message_handle->result);
685 }
686 3065 GlobusSoapMessageDebugPrintf(GLOBUS_SOAP_MESSAGE_DEBUG_DEBUG,
687 ("response code: %d\n", response_code));
688
689
690 3065 if(response_code > 299)
691 {
692 4 if(response_code > 399 && response_code < 500)
693 {
694 2 message_handle->result = GlobusSoapMessageErrorBadRequest(
695 response_code, message);
696 }
697
698 4 if(response_code > 499)
699 {
700 2 message_handle->result = GlobusSoapMessageErrorFailedResponse(
701 response_code, message);
702 }
703 }
704
705 3065 globus_mutex_lock(&message_handle->mutex);
706 3065 message_handle->response_semaphore++;
707
708 6130 if(message_handle->response_semaphore > 1 &&
709 message_handle->response_handle)
710 {
711 globus_l_soap_message_callback_handle_t * response_handle =
712 (globus_l_soap_message_callback_handle_t *)
713 3065 message_handle->response_handle;
714
715 3065 globus_mutex_unlock(&message_handle->mutex);
716
717 3065 message_handle->response_handle = NULL;
718
719 3065 globus_l_soap_message_response_callback(
720 response_handle);
721 }
722 else
723 {
724 0 globus_mutex_unlock(&message_handle->mutex);
725 }
726
727 3065 GlobusSoapMessageDebugExit();
728 return;
729 }
730
731 static
732 globus_bool_t
733 globus_l_soap_message_timeout_callback(
734 globus_xio_handle_t handle,
735 globus_xio_operation_type_t type,
736 void * user_arg)
737 0 {
738 0 return GLOBUS_TRUE;
739 }
740
741
742 globus_result_t
743 globus_soap_message_register_open(
744 globus_soap_message_handle_t handle,
745 char * endpoint,
746 globus_soap_message_callback_func_t callback,
747 void * args)
748 3065 {
749 globus_soap_message_auth_method_t sectype;
750 3065 globus_xio_attr_t attr = NULL;
751 globus_l_soap_message_callback_handle_t * callback_handle;
752 3065 globus_result_t result = GLOBUS_SUCCESS;
753 char * soap_action;
754 3065 char * http_version = NULL;
755 3065 char * connection = NULL;
756 3065 void * timeout = NULL;
757 3065 char * quoted_soap_action = NULL;
758 GlobusFuncName(globus_soap_message_register_open);
759 3065 GlobusSoapMessageDebugEnter();
760
761 3065 globus_mutex_lock(&handle->cancel_mutex);
762 3065 handle->cancelled = 0;
763 3065 globus_mutex_unlock(&handle->cancel_mutex);
764
765 3065 callback_handle = (globus_l_soap_message_callback_handle_t *)
766 globus_malloc(sizeof(globus_l_soap_message_callback_handle_t));
767 3065 if(!callback_handle)
768 {
769 0 result = GlobusSoapMessageErrorOutOfMemory;
770 0 goto exit;
771 }
772 3065 memset(callback_handle, 0,
773 (sizeof(globus_l_soap_message_callback_handle_t)));
774
775 3065 if(handle->xio_handle)
776 {
777 0 result = GlobusSoapMessageErrorFailedTransport(
778 result, "Session already opened");
779 0 goto exit;
780 }
781
782 3065 callback_handle->callback = callback;
783 3065 callback_handle->args = args;
784 3065 callback_handle->message = handle;
785
786 3065 if(strncmp(endpoint, "https://", 8) == 0)
787 {
788 1382 result = globus_xio_handle_create(
789 &handle->xio_handle,
790 globus_i_soap_message_xio_https_stack);
791 1382 if(result != GLOBUS_SUCCESS)
792 {
793 0 result = GlobusSoapMessageErrorFailedTransport(
794 result, "Failed to create xio handle with https stack");
795 0 goto exit;
796 }
797
798 1382 result = globus_xio_attr_init(&attr);
799 1382 if(result != GLOBUS_SUCCESS)
800 {
801 0 result = GlobusSoapMessageErrorFailedTransport(
802 result, "Failed to initialize xio attr");
803 0 goto exit;
804 }
805
806 1382 result = globus_i_soap_message_setup_transport_security(
807 handle->attrs,
808 attr);
809 1382 if(result != GLOBUS_SUCCESS)
810 {
811 0 result = GlobusSoapMessageErrorFailedTransport(
812 result, "Failed to initialize xio attributes for https");
813 0 goto exit;
814 }
815 }
816 else
817 {
818 1683 sectype = (globus_soap_message_auth_method_t)
819 globus_soap_message_handle_get_attr(
820 handle,
821 GLOBUS_SOAP_MESSAGE_AUTHENTICATION_METHOD_KEY);
822
823 1683 if(sectype && (sectype == GLOBUS_SOAP_MESSAGE_AUTH_SECURE))
824 {
825 /* XXX may not be a good idea if users can 'set attrs' on this
826 * handle while it is open
827 */
828 0 globus_soap_message_handle_set_attr(
829 handle,
830 GLOBUS_SOAP_MESSAGE_AUTHENTICATION_METHOD_KEY,
831 NULL,
832 NULL,
833 (void *) GLOBUS_SOAP_MESSAGE_AUTH_SECURE_MESSAGE);
834 }
835
836 1683 result = globus_xio_handle_create(&handle->xio_handle,
837 globus_i_soap_message_xio_stack);
838
839 1683 result = globus_xio_attr_init(&attr);
840 1683 if(result != GLOBUS_SUCCESS)
841 {
842 0 result = GlobusSoapMessageErrorFailedTransport(
843 result, "Failed to initialize xio attr");
844 0 goto exit;
845 }
846 }
847
848 3065 timeout = globus_soap_message_handle_get_attr(
849 handle, GLOBUS_SOAP_MESSAGE_TIMEOUT_KEY);
850 3065 if(timeout)
851 {
852 0 result = globus_xio_attr_cntl(
853 attr,
854 GLOBUS_NULL,
855 GLOBUS_XIO_ATTR_SET_TIMEOUT_ALL,
856 globus_l_soap_message_timeout_callback,
857 timeout,
858 GLOBUS_NULL);
859 0 if(result != GLOBUS_SUCCESS)
860 {
861 0 result = GlobusSoapMessageErrorFailedTransport(
862 result, "Failed to set timeout for xio handle");
863 0 goto exit;
864 }
865 }
866
867 3065 http_version = globus_soap_message_handle_get_attr(
868 handle, GLOBUS_SOAP_MESSAGE_HTTP_VERSION_KEY);
869 3065 if(http_version && !strcmp(http_version, "1.0"))
870 {
871 0 result = globus_xio_attr_cntl(
872 attr,
873 globus_i_soap_message_http_driver,
874 GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_HTTP_VERSION,
875 GLOBUS_XIO_HTTP_VERSION_1_0);
876 0 if(result != GLOBUS_SUCCESS)
877 {
878 0 result = GlobusSoapMessageErrorFailedTransport(
879 result, "Failed to set HTTP version to 1.0");
880 0 goto exit;
881 }
882
883 0 result = globus_xio_attr_cntl(
884 attr,
885 globus_i_soap_message_http_driver,
886 GLOBUS_XIO_HTTP_ATTR_DELAY_WRITE_HEADER);
887 0 if(result != GLOBUS_SUCCESS)
888 {
889 0 result = GlobusSoapMessageErrorFailedTransport(
890 result, "Failed to set delay write of HTTP Header");
891 0 goto exit;
892 }
893 }
894
895 3065 result = globus_xio_attr_cntl(
896 attr, globus_i_soap_message_http_driver,
897 GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_HEADER,
898 "Content-Type",
899 "text/xml; charset=utf-8");
900 3065 if(result != GLOBUS_SUCCESS)
901 {
902 0 result = GlobusSoapMessageErrorFailedTransport(
903 result, "Failed to set HTTP request header: Content-Type");
904 0 goto exit;
905 }
906
907 3065 result = globus_xio_attr_cntl(
908 attr, globus_i_soap_message_http_driver,
909 GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_HEADER,
910 "Accept",
911 "text/xml");
912 3065 if(result != GLOBUS_SUCCESS)
913 {
914 0 result = GlobusSoapMessageErrorFailedTransport(
915 result, "Failed to set HTTP request header: Accept");
916 0 goto exit;
917 }
918
919 3065 connection = (char *) globus_soap_message_handle_get_attr(
920 handle,
921 GLOBUS_SOAP_MESSAGE_CONNECTION_KEY);
922 3065 if (connection && !strcmp(connection, "close"))
923 {
924 1940 result = globus_xio_attr_cntl(
925 attr, globus_i_soap_message_http_driver,
926 GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_HEADER,
927 "Connection",
928 "close");
929 1940 if(result != GLOBUS_SUCCESS)
930 {
931 0 result = GlobusSoapMessageErrorFailedTransport(
932 result, "Failed to set HTTP request header: Connection");
933 0 goto exit;
934 }
935 }
936
937 3065 soap_action = globus_soap_message_handle_get_attr(
938 handle, GLOBUS_SOAP_MESSAGE_SOAP_ACTION_KEY);
939 3065 if(!soap_action)
940 {
941 0 result = GlobusSoapMessageErrorFailedTransport(
942 result, "SOAPAction not set in message attributes");
943 0 goto exit;
944 }
945
946 3065 if (soap_action[0] != '"')
947 {
948 /* WS-I BP requires that SOAPAction be quoted */
949 size_t soap_action_len;
950
951 3065 soap_action_len = strlen(soap_action);
952
953 3065 quoted_soap_action = malloc(soap_action_len + 3);
954
955 3065 memcpy(quoted_soap_action + 1, soap_action, soap_action_len);
956 3065 quoted_soap_action[0] = '"';
957 3065 quoted_soap_action[soap_action_len+1] = '"';
958 3065 quoted_soap_action[soap_action_len+2] = '\0';
959
960 3065 soap_action = quoted_soap_action;
961 }
962
963 3065 result = globus_xio_attr_cntl(
964 attr,
965 globus_i_soap_message_http_driver,
966 GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_HEADER,
967 "SOAPAction",
968 soap_action);
969 3065 if(result != GLOBUS_SUCCESS)
970 {
971 0 result = GlobusSoapMessageErrorFailedTransport(
972 result, "Failed to set request method in http driver");
973 0 goto exit;
974 }
975
976 3065 result = globus_xio_attr_cntl(
977 attr, globus_i_soap_message_http_driver,
978 GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_METHOD,
979 "POST");
980 3065 if(result != GLOBUS_SUCCESS)
981 {
982 0 result = GlobusSoapMessageErrorFailedTransport(
983 result, "Failed to set request method in http driver");
984 0 goto exit;
985 }
986
987 3065 result = globus_xio_attr_cntl(attr,
988 globus_i_soap_message_tcp_driver,
989 GLOBUS_XIO_TCP_SET_NODELAY,
990 GLOBUS_TRUE);
991 3065 if(result != GLOBUS_SUCCESS)
992 {
993 0 result = GlobusSoapMessageErrorFailedTransport(
994 result, "Failed to set tcp nodelay.");
995 0 goto exit;
996 }
997
998
999 3065 result = globus_xio_register_open(
1000 handle->xio_handle,
1001 endpoint,
1002 attr,
1003 globus_l_soap_message_open_callback,
1004 callback_handle);
1005 3065 if(result != GLOBUS_SUCCESS)
1006 {
1007 0 result = GlobusSoapMessageErrorFailedTransport(
1008 result, "Failed to connect to server");
1009 0 goto exit;
1010 }
1011
1012 3065 if(attr)
1013 {
1014 3065 globus_xio_attr_destroy(attr);
1015 3065 attr = NULL;
1016 }
1017
1018 3065 exit:
1019
1020 3065 if(result != GLOBUS_SUCCESS)
1021 {
1022 0 free(callback_handle);
1023 0 if(attr)
1024 {
1025 0 globus_xio_attr_destroy(attr);
1026 }
1027 }
1028 3065 if (quoted_soap_action != NULL)
1029 {
1030 3065 free(quoted_soap_action);
1031 }
1032
1033 3065 GlobusSoapMessageDebugExit();
1034 3065 return result;
1035 }
1036
1037 globus_bool_t
1038 globus_soap_message_is_cancelled(
1039 globus_soap_message_handle_t handle)
1040 3065 {
1041 globus_bool_t cancelled;
1042
1043 3065 globus_mutex_lock(&handle->cancel_mutex);
1044 3065 cancelled = handle->cancelled;
1045 3065 globus_mutex_unlock(&handle->cancel_mutex);
1046
1047 3065 return cancelled;
1048 }
1049
1050 globus_result_t
1051 globus_soap_message_cancel_message(
1052 globus_soap_message_handle_t handle)
1053 0 {
1054 0 globus_result_t result = GLOBUS_SUCCESS;
1055 GlobusFuncName(globus_soap_message_operations_cancel);
1056 0 GlobusSoapMessageDebugEnter();
1057
1058 0 globus_xio_handle_cancel_operations(
1059 handle->xio_handle,
1060 GLOBUS_XIO_CANCEL_OPEN|
1061 GLOBUS_XIO_CANCEL_CLOSE|
1062 GLOBUS_XIO_CANCEL_READ|
1063 GLOBUS_XIO_CANCEL_WRITE);
1064
1065 0 globus_mutex_lock(&handle->cancel_mutex);
1066 0 handle->cancelled = 1;
1067 0 globus_mutex_unlock(&handle->cancel_mutex);
1068
1069 0 return result;
1070 }
1071
1072 globus_result_t
1073 globus_soap_message_register_write_request(
1074 globus_soap_message_handle_t handle,
1075 globus_soap_message_callback_func_t callback,
1076 void * args,
1077 globus_bool_t response)
1078 3065 {
1079 char content_length_buffer[100];
1080 int buffer_length;
1081 globus_l_soap_message_callback_handle_t * callback_handle;
1082 3065 globus_result_t result = GLOBUS_SUCCESS;
1083 GlobusFuncName(globus_soap_message_register_write_request);
1084 3065 GlobusSoapMessageDebugEnter();
1085
1086 3065 globus_xio_handle_cntl(
1087 handle->xio_handle, globus_i_soap_message_buffer_driver,
1088 GLOBUS_XIO_BUFFER_DONE_BUFFERING);
1089
1090 3065 callback_handle = (globus_l_soap_message_callback_handle_t *)
1091 globus_malloc(sizeof(globus_l_soap_message_callback_handle_t));
1092 3065 if(!callback_handle)
1093 {
1094 0 result = GlobusSoapMessageErrorOutOfMemory;
1095 0 goto exit;
1096 }
1097 3065 memset(callback_handle, 0,
1098 (sizeof(globus_l_soap_message_callback_handle_t)));
1099
1100 3065 callback_handle->callback = callback;
1101 3065 callback_handle->args = args;
1102 3065 callback_handle->message = handle;
1103 3065 callback_handle->type = (response ? GLOBUS_SOAP_MESSAGE_REQUEST_CALLBACK:
1104 GLOBUS_SOAP_MESSAGE_RESPONSE_CALLBACK);
1105
1106 3065 if(callback_handle->message->writer)
1107 {
1108 3065 xmlFreeTextWriter(callback_handle->message->writer);
1109 3065 callback_handle->message->writer = NULL;
1110 }
1111
1112 3065 result = globus_xio_handle_cntl(
1113 handle->xio_handle,
1114 globus_i_soap_message_buffer_driver,
1115 GLOBUS_XIO_BUFFER_GET_LENGTH,
1116 &buffer_length);
1117 3065 if(result != GLOBUS_SUCCESS)
1118 {
1119 0 result = GlobusSoapMessageErrorFailedTransport(
1120 result, "Failed to set get length of message");
1121 0 goto exit;
1122 }
1123
1124 3065 memset(content_length_buffer, 0, 100);
1125 3065 sprintf(content_length_buffer, "%d", buffer_length);
1126
1127 3065 result = globus_xio_handle_cntl(
1128 handle->xio_handle,
1129 globus_i_soap_message_http_driver,
1130 GLOBUS_XIO_HTTP_HANDLE_SET_REQUEST_HEADER,
1131 "Content-Length",
1132 content_length_buffer);
1133 3065 if(result != GLOBUS_SUCCESS)
1134 {
1135 0 result = GlobusSoapMessageErrorFailedTransport(
1136 result, "Failed to set Content-Length in HTTP header");
1137 0 goto exit;
1138 }
1139
1140 3065 if(GlobusSoapMessageDebug(GLOBUS_SOAP_MESSAGE_DEBUG_MESSAGES))
1141 {
1142 char * buffer;
1143 size_t read_length;
1144
1145 0 globus_xio_handle_cntl(
1146 callback_handle->message->xio_handle,
1147 globus_i_soap_message_buffer_driver,
1148 GLOBUS_XIO_BUFFER_GET_MARKED_BUFFERS,
1149 NULL, NULL, &buffer, &read_length);
1150
1151 0 GlobusSoapMessageDebugPrintf(
1152 GLOBUS_SOAP_MESSAGE_DEBUG_MESSAGES,
1153 ("----------------WRITING--------------\n%.*s\n"
1154 "=====================================\n\n",
1155 read_length, buffer));
1156
1157 0 free(buffer);
1158 }
1159
1160 3065 result = globus_xio_handle_cntl(
1161 handle->xio_handle,
1162 globus_i_soap_message_buffer_driver,
1163 GLOBUS_XIO_BUFFER_FLUSH,
1164 handle->xio_handle,
1165 globus_l_soap_message_flush_callback,
1166 callback_handle);
1167 3065 if(result != GLOBUS_SUCCESS)
1168 {
1169 0 result = GlobusSoapMessageErrorFailedTransport(
1170 result, "Failed to write message");
1171 goto exit;
1172 }
1173
1174 3065 exit:
1175
1176 3065 if(result != GLOBUS_SUCCESS)
1177 {
1178 0 free(callback_handle);
1179 }
1180
1181 3065 GlobusSoapMessageDebugExit();
1182 3065 return result;
1183 }
1184
1185 globus_result_t
1186 globus_soap_message_register_write_response(
1187 globus_soap_message_handle_t handle,
1188 globus_soap_message_callback_func_t callback,
1189 void * args)
1190 2132 {
1191 char content_length_buffer[100];
1192 char * connection;
1193 int buffer_length;
1194 globus_l_soap_message_callback_handle_t * callback_handle;
1195 2132 globus_result_t result = GLOBUS_SUCCESS;
1196 GlobusFuncName(globus_soap_message_register_write_response);
1197 2132 GlobusSoapMessageDebugEnter();
1198
1199 2132 globus_xio_handle_cntl(
1200 handle->xio_handle, globus_i_soap_message_buffer_driver,
1201 GLOBUS_XIO_BUFFER_DONE_BUFFERING);
1202
1203 2132 callback_handle = (globus_l_soap_message_callback_handle_t *)
1204 globus_malloc(sizeof(globus_l_soap_message_callback_handle_t));
1205 2132 if(!callback_handle)
1206 {
1207 0 result = GlobusSoapMessageErrorOutOfMemory;
1208 0 goto exit;
1209 }
1210 2132 memset(callback_handle, 0,
1211 (sizeof(globus_l_soap_message_callback_handle_t)));
1212
1213 2132 callback_handle->callback = callback;
1214 2132 callback_handle->args = args;
1215 2132 callback_handle->message = handle;
1216 2132 callback_handle->type = GLOBUS_SOAP_MESSAGE_RESPONSE_CALLBACK;
1217
1218 2132 if(callback_handle->message->writer)
1219 {
1220 2132 xmlFreeTextWriter(callback_handle->message->writer);
1221 2132 callback_handle->message->writer = NULL;
1222 }
1223
1224 2132 result = globus_xio_handle_cntl(
1225 handle->xio_handle,
1226 globus_i_soap_message_buffer_driver,
1227 GLOBUS_XIO_BUFFER_GET_LENGTH,
1228 &buffer_length);
1229 2132 if(result != GLOBUS_SUCCESS)
1230 {
1231 0 result = GlobusSoapMessageErrorFailedTransport(
1232 result, "Failed to set get length of message");
1233 0 goto exit;
1234 }
1235
1236 2132 memset(content_length_buffer, 0, 100);
1237 2132 sprintf(content_length_buffer, "%d", buffer_length);
1238
1239 2132 result = globus_xio_handle_cntl(
1240 handle->xio_handle,
1241 globus_i_soap_message_http_driver,
1242 GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HEADER,
1243 "Content-Length",
1244 content_length_buffer);
1245 2132 if(result != GLOBUS_SUCCESS)
1246 {
1247 0 result = GlobusSoapMessageErrorFailedTransport(
1248 result, "Failed to set Content-Length in HTTP header");
1249 0 goto exit;
1250 }
1251
1252 2132 connection = globus_soap_message_handle_get_attr(
1253 handle,
1254 GLOBUS_SOAP_MESSAGE_CONNECTION_KEY);
1255
1256 2132 if (connection && !strcmp(connection, "close"))
1257 {
1258 1 result = globus_xio_handle_cntl(
1259 handle->xio_handle,
1260 globus_i_soap_message_http_driver,
1261 GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HEADER,
1262 "Connection",
1263 "close");
1264
1265 1 if(result != GLOBUS_SUCCESS)
1266 {
1267 0 result = GlobusSoapMessageErrorFailedTransport(
1268 result, "Failed to set Connection in HTTP header");
1269 0 goto exit;
1270 }
1271 }
1272
1273 2132 if(GlobusSoapMessageDebug(GLOBUS_SOAP_MESSAGE_DEBUG_MESSAGES))
1274 {
1275 char * buffer;
1276 size_t read_length;
1277
1278 0 globus_xio_handle_cntl(
1279 callback_handle->message->xio_handle,
1280 globus_i_soap_message_buffer_driver,
1281 GLOBUS_XIO_BUFFER_GET_MARKED_BUFFERS,
1282 NULL, NULL, &buffer, &read_length);
1283
1284 0 GlobusSoapMessageDebugPrintf(
1285 GLOBUS_SOAP_MESSAGE_DEBUG_MESSAGES,
1286 ("----------------WRITING--------------\n%.*s\n"
1287 "=====================================\n\n",
1288 read_length, buffer));
1289
1290 0 free(buffer);
1291 }
1292
1293 2132 if(buffer_length > 0)
1294 {
1295 2122 result = globus_xio_handle_cntl(
1296 handle->xio_handle,
1297 globus_i_soap_message_buffer_driver,
1298 GLOBUS_XIO_BUFFER_FLUSH,
1299 handle->xio_handle,
1300 globus_l_soap_message_flush_callback,
1301 callback_handle);
1302 2122 if(result != GLOBUS_SUCCESS)
1303 {
1304 0 result = GlobusSoapMessageErrorFailedTransport(
1305 result, "Failed to write message");
1306 0 goto exit;
1307 }
1308 }
1309 else
1310 {
1311 10 globus_xio_handle_cntl(
1312 handle->xio_handle,
1313 globus_i_soap_message_http_driver,
1314 GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY);
1315
1316 10 callback_handle->callback(result, callback_handle->args);
1317
1318 10 free(callback_handle);
1319 10 callback_handle = NULL;
1320 }
1321
1322
1323 2132 result = globus_xio_handle_cntl(
1324 handle->xio_handle,
1325 globus_i_soap_message_buffer_driver,
1326 GLOBUS_XIO_BUFFER_DONE_BUFFERING);
1327 2132 if(result != GLOBUS_SUCCESS)
1328 {
1329 0 result = GlobusSoapMessageErrorFailedTransport(
1330 result, "Failed to write message");
1331 goto exit;
1332 }
1333
1334 2132 exit:
1335
1336 2132 if(result != GLOBUS_SUCCESS && callback_handle != NULL)
1337 {
1338 0 free(callback_handle);
1339 }
1340
1341 2132 GlobusSoapMessageDebugExit();
1342 2132 return result;
1343 }
1344
1345 globus_result_t
1346 globus_soap_message_register_read_response(
1347 globus_soap_message_handle_t handle,
1348 globus_soap_message_callback_func_t callback,
1349 void * args)
1350 3065 {
1351 globus_l_soap_message_callback_handle_t * callback_handle;
1352 3065 globus_result_t result = GLOBUS_SUCCESS;
1353 GlobusFuncName(globus_soap_message_register_read_response);
1354 3065 GlobusSoapMessageDebugEnter();
1355
1356
1357 3065 callback_handle = globus_malloc(
1358 sizeof(globus_l_soap_message_callback_handle_t));
1359 3065 if(!callback_handle)
1360 {
1361 0 result = GlobusSoapMessageErrorOutOfMemory;
1362 0 goto exit;
1363 }
1364 3065 memset(callback_handle, 0,
1365 (sizeof(globus_l_soap_message_callback_handle_t)));
1366
1367 3065 callback_handle->callback = callback;
1368 3065 callback_handle->args = args;
1369 3065 callback_handle->message = handle;
1370
1371 3065 globus_mutex_lock(&handle->mutex);
1372 3065 handle->response_semaphore++;
1373
1374 3065 if(handle->response_semaphore > 1)
1375 {
1376 0 globus_mutex_unlock(&handle->mutex);
1377 0 result = globus_callback_register_oneshot(
1378 NULL,
1379 &globus_i_reltime_zero,
1380 globus_l_soap_message_response_callback,
1381 callback_handle);
1382 0 if(result != GLOBUS_SUCCESS)
1383 {
1384 0 result = GlobusSoapMessageErrorFailedTransport(
1385 result, "Failed to register periodic callbcak for response");
1386 0 goto exit;
1387 }
1388 }
1389 else
1390 {
1391 3065 globus_mutex_unlock(&handle->mutex);
1392 3065 handle->response_handle = (void *)callback_handle;
1393 }
1394
1395 3065 exit:
1396
1397 3065 GlobusSoapMessageDebugExit();
1398 3065 return result;
1399 }
1400
1401 globus_result_t
1402 globus_soap_message_register_read_request(
1403 globus_soap_message_handle_t handle,
1404 globus_soap_message_callback_func_t callback,
1405 void * args)
1406 2131 {
1407 globus_l_soap_message_callback_handle_t * callback_handle;
1408 2131 globus_result_t result = GLOBUS_SUCCESS;
1409 GlobusFuncName(globus_soap_message_register_read_request);
1410 2131 GlobusSoapMessageDebugEnter();
1411
1412 2131 callback_handle = globus_malloc(
1413 sizeof(globus_l_soap_message_callback_handle_t));
1414 2131 if(!callback_handle)
1415 {
1416 0 result = GlobusSoapMessageErrorOutOfMemory;
1417 0 goto exit;
1418 }
1419 2131 memset(callback_handle, 0,
1420 (sizeof(globus_l_soap_message_callback_handle_t)));
1421
1422 2131 callback_handle->callback = callback;
1423 2131 callback_handle->args = args;
1424 2131 callback_handle->message = handle;
1425
1426 2131 result = globus_xio_handle_cntl(
1427 callback_handle->message->xio_handle,
1428 globus_i_soap_message_buffer_driver,
1429 GLOBUS_XIO_BUFFER_ENABLE_READ_BUFFERING);
1430 2131 if(result != GLOBUS_SUCCESS)
1431 {
1432 0 result = GlobusSoapMessageErrorFailedTransport(
1433 result, "Failed to enable read buffering in buffer driver");
1434 0 goto exit;
1435 }
1436
1437 2131 result = globus_xio_register_read(
1438 handle->xio_handle,
1439 (globus_byte_t *)handle->readbuf,
1440 GLOBUS_I_SOAP_MESSAGE_READBUF_SIZE,
1441 1,
1442 NULL,
1443 globus_l_soap_message_read_callback,
1444 callback_handle);
1445 2131 if(result != GLOBUS_SUCCESS)
1446 {
1447 0 result = GlobusSoapMessageErrorFailedTransport(
1448 result, "Failed to begin reading SOAP message");
1449 goto exit;
1450 }
1451
1452 2131 exit:
1453
1454 2131 GlobusSoapMessageDebugExit();
1455 2131 return result;
1456 }
1457
1458 typedef struct
1459 {
1460 globus_soap_message_callback_func_t callback;
1461 void * args;
1462 } globus_l_soap_message_close_callback_t;
1463
1464 void
1465 globus_l_soap_message_register_close_callback(
1466 globus_xio_handle_t handle,
1467 globus_result_t result,
1468 void * args)
1469 4139 {
1470 globus_l_soap_message_close_callback_t * callback_handle;
1471
1472 4139 callback_handle = (globus_l_soap_message_close_callback_t *) args;
1473
1474 4139 callback_handle->callback(result, callback_handle->args);
1475
1476 4139 free(callback_handle);
1477 }
1478
1479 globus_result_t
1480 globus_soap_message_register_close(
1481 globus_soap_message_handle_t handle,
1482 globus_soap_message_callback_func_t callback,
1483 void * args)
1484 4139 {
1485 4139 globus_result_t result = GLOBUS_SUCCESS;
1486 globus_l_soap_message_close_callback_t * callback_handle;
1487 GlobusFuncName(globus_soap_message_register_close);
1488 4139 GlobusSoapMessageDebugEnter();
1489
1490 4139 if(handle->reader)
1491 {
1492 3064 xmlFreeTextReader(handle->reader);
1493 }
1494 4139 handle->reader = NULL;
1495
1496 4139 callback_handle = globus_malloc(
1497 sizeof(globus_l_soap_message_close_callback_t));
1498 4139 if(!callback_handle)
1499 {
1500 0 result = GlobusSoapMessageErrorOutOfMemory;
1501 0 goto exit;
1502 }
1503 4139 callback_handle->callback = callback;
1504 4139 callback_handle->args = args;
1505
1506 4139 globus_xio_register_close(
1507 handle->xio_handle,
1508 NULL,
1509 globus_l_soap_message_register_close_callback,
1510 callback_handle);
1511
1512 4139 handle->xio_handle = NULL;
1513
1514 4139 exit:
1515 4139 GlobusSoapMessageDebugExit();
1516 4139 return result;
1517 }
1518
1519 globus_result_t
1520 globus_i_soap_message_reset_reader(
1521 globus_soap_message_handle_t handle)
1522 1079 {
1523 1079 globus_result_t result = GLOBUS_SUCCESS;
1524 GlobusFuncName(globus_i_soap_message_reset_reader);
1525 1079 GlobusSoapMessageDebugEnter();
1526
1527 1079 if(handle->reader)
1528 {
1529 0 xmlFreeTextReader(handle->reader);
1530 }
1531
1532 1079 handle->buffer_eof = 0;
1533
1534 1079 handle->reader = xmlReaderForIO(
1535 globus_l_soap_message_handle_libxml_io_read_callback,
1536 globus_l_soap_message_handle_libxml_io_close_callback,
1537 handle,
1538 NULL,
1539 NULL,
1540 0);
1541 1079 if(!handle->reader)
1542 {
1543 0 result = GlobusSoapMessageErrorInitFailed(
1544 "Failed to initialize xmlReader");
1545 0 goto exit;
1546 }
1547
1548 1079 xmlTextReaderSetErrorHandler(handle->reader,
1549 globus_l_soap_message_error_callback,
1550 handle);
1551
1552 1079 xmlTextReaderSetStructuredErrorHandler(
1553 handle->reader,
1554 globus_l_soap_message_structured_error_callback,
1555 handle);
1556
1557 1079 exit:
1558
1559 1079 GlobusSoapMessageDebugExit();
1560 1079 return result;
1561 }
1562
1563 globus_result_t
1564 globus_i_soap_message_setup_transport_security(
1565 globus_soap_message_attr_t attrs,
1566 globus_xio_attr_t xio_attr)
1567 1383 {
1568 globus_xio_gsi_authorization_mode_t gsi_authz;
1569 globus_soap_message_auth_protection_level_t protect;
1570 globus_soap_message_authz_method_t authz;
1571 void * credential;
1572 void * target_name;
1573 1383 globus_result_t result = GLOBUS_SUCCESS;
1574 GlobusFuncName(globus_l_soap_message_setup_transport_security);
1575 1383 GlobusSoapMessageDebugEnter();
1576
1577 1383 credential = globus_soap_message_attr_get(
1578 attrs,
1579 GLOBUS_SOAP_MESSAGE_USER_CREDENTIAL_KEY);
1580 1383 if(credential)
1581 {
1582 0 result = globus_xio_attr_cntl(
1583 xio_attr,
1584 globus_i_soap_message_gsi_driver,
1585 GLOBUS_XIO_GSI_SET_CREDENTIAL,
1586 credential);
1587 0 if(result != GLOBUS_SUCCESS)
1588 {
1589 0 result = GlobusSoapMessageErrorFailedTransport(
1590 result, "Failed to set credential for gsi driver");
1591 0 goto exit;
1592 }
1593 }
1594
1595 1383 result = globus_xio_attr_cntl(
1596 xio_attr,
1597 globus_i_soap_message_gsi_driver,
1598 GLOBUS_XIO_GSI_SET_DELEGATION_MODE,
1599 GLOBUS_XIO_GSI_DELEGATION_MODE_NONE);
1600 1383 if(result != GLOBUS_SUCCESS)
1601 {
1602 0 result = GlobusSoapMessageErrorFailedTransport(
1603 result, "Failed to set delegation mode for gsi driver");
1604 0 goto exit;
1605 }
1606
1607 1383 result = globus_xio_attr_cntl(
1608 xio_attr,
1609 globus_i_soap_message_gsi_driver,
1610 GLOBUS_XIO_GSI_SET_SSL_COMPATIBLE,
1611 1);
1612 1383 if(result != GLOBUS_SUCCESS)
1613 {
1614 0 result = GlobusSoapMessageErrorFailedTransport(
1615 result, "Failed to set delegation mode for gsi driver");
1616 0 goto exit;
1617 }
1618
1619 1383 protect =
1620 (globus_soap_message_auth_protection_level_t)
1621 globus_soap_message_attr_get(
1622 attrs,
1623 GLOBUS_SOAP_MESSAGE_AUTH_PROTECTION_KEY);
1624 1383 if(protect != GLOBUS_SOAP_MESSAGE_AUTH_PROTECTION_NOT_SET)
1625 {
1626 0 result = globus_xio_attr_cntl(
1627 xio_attr,
1628 globus_i_soap_message_gsi_driver,
1629 GLOBUS_XIO_GSI_SET_PROTECTION_LEVEL,
1630 ((protect == GLOBUS_SOAP_MESSAGE_AUTH_PROTECTION_INTEGRITY) ?
1631 GLOBUS_XIO_GSI_PROTECTION_LEVEL_INTEGRITY :
1632 GLOBUS_XIO_GSI_PROTECTION_LEVEL_PRIVACY));
1633 0 if(result != GLOBUS_SUCCESS)
1634 {
1635 0 result = GlobusSoapMessageErrorFailedTransport(
1636 result, "Failed to set delegation mode for gsi driver");
1637 0 goto exit;
1638 }
1639 }
1640
1641 1383 authz =
1642 (globus_soap_message_authz_method_t)
1643 globus_soap_message_attr_get(
1644 attrs,
1645 GLOBUS_SOAP_MESSAGE_AUTHZ_METHOD_KEY);
1646
1647 1383 switch(authz)
1648 {
1649 case GLOBUS_SOAP_MESSAGE_AUTHZ_SELF:
1650 1383 gsi_authz = GLOBUS_XIO_GSI_SELF_AUTHORIZATION;
1651 1383 break;
1652 case GLOBUS_SOAP_MESSAGE_AUTHZ_IDENTITY:
1653 0 gsi_authz = GLOBUS_XIO_GSI_IDENTITY_AUTHORIZATION;
1654 0 break;
1655 case GLOBUS_SOAP_MESSAGE_AUTHZ_HOST:
1656 0 gsi_authz = GLOBUS_XIO_GSI_HOST_AUTHORIZATION;
1657 0 break;
1658 case GLOBUS_SOAP_MESSAGE_AUTHZ_NONE:
1659 0 gsi_authz = GLOBUS_XIO_GSI_NO_AUTHORIZATION;
1660 0 break;
1661 default:
1662 0 gsi_authz = GLOBUS_XIO_GSI_SELF_AUTHORIZATION;
1663 }
1664
1665 1383 result = globus_xio_attr_cntl(
1666 xio_attr,
1667 globus_i_soap_message_gsi_driver,
1668 GLOBUS_XIO_GSI_SET_AUTHORIZATION_MODE,
1669 gsi_authz);
1670 1383 if(result != GLOBUS_SUCCESS)
1671 {
1672 0 result = GlobusSoapMessageErrorFailedTransport(
1673 result, "Failed to set delegation mode for gsi driver");
1674 0 goto exit;
1675 }
1676
1677 1383 target_name = globus_soap_message_attr_get(
1678 attrs,
1679 GLOBUS_SOAP_MESSAGE_AUTHZ_TARGET_NAME_KEY);
1680 1383 if(target_name)
1681 {
1682 0 result = globus_xio_attr_cntl(
1683 xio_attr,
1684 globus_i_soap_message_gsi_driver,
1685 GLOBUS_XIO_GSI_SET_TARGET_NAME,
1686 target_name);
1687 0 if(result != GLOBUS_SUCCESS)
1688 {
1689 0 result = GlobusSoapMessageErrorFailedTransport(
1690 result, "Failed to set target name on gsi driver");
1691 goto exit;
1692 }
1693 }
1694
1695 1383 exit:
1696
1697 1383 GlobusSoapMessageDebugExit();
1698 1383 return result;
1699 }