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_i_service_engine.h"
14 #include "globus_service_registry.h"
15 #include "globus_soap_message.h"
16 #include "globus_soap_message_attrs.h"
17 #include "globus_soap_message_fault.h"
18 #include "globus_xio_tcp_driver.h"
19 #include "globus_xio_http.h"
20 #include "globus_xio_buffer.h"
21 #include "version.h"
22 #include "globus_flavor.h"
23 #include "libxml/uri.h"
24 #include "globus_ws_addressing.h"
25 #include "globus_soap_message_markers.h"
26 #include "globus_i_soap_message.h"
27 #include "globus_usage.h"
28
29 #define SOAP_ACTION_HEADER              "SOAPAction"
30 #define CONTENT_TYPE_HEADER             "Content-Type"
31
32 #define GLOBUS_I_SERVICE_DESCRIPTOR_KEY       "GLOBUS_SERVICE_DESCRIPTOR"
33 #define GLOBUS_I_SERVICE_EXTENSION_HANDLE_KEY "GLOBUS_SERVICE_EXTENSION_HANDLE"
34 #define GLOBUS_I_SESSION_HANDLE_KEY           "GLOBUS_ENGINE_CALLBACK_HANDLE"
35 #define GLOBUS_I_SERVICE_OPERATION_QNAME_KEY  "GLOBUS_SERVICE_OPERATION_QNAME"
36
37 static globus_list_t *              globus_l_service_engine_extensions = NULL;
38 static globus_mutex_t               globus_l_service_engine_extensions_mutex;
39
40 globus_extension_registry_t             globus_service_registry =
41 {
42     NULL,
43     GLOBUS_FALSE,
44     GLOBUS_FALSE
45 };
46
47 static int
48 globus_l_service_engine_activate();
49
50 static int
51 globus_l_service_engine_deactivate();
52
53 globus_module_descriptor_t              globus_l_service_engine_module =
54 {
55     "globus_service_engine_module",
56     globus_l_service_engine_activate,
57     globus_l_service_engine_deactivate,
58     NULL,
59     NULL,
60     &local_version
61 };
62
63 0 GlobusDebugDefine(GLOBUS_SERVICE_ENGINE);
64
65 typedef enum
66 {
67     GLOBUS_L_SERVICE_ENGINE_REQUEST_READ_MESSAGE,
68     GLOBUS_L_SERVICE_ENGINE_REQUEST_INIT_SERVICE_HANDLERS,
69     GLOBUS_L_SERVICE_ENGINE_REQUEST_INIT_HANDLERS,
70     GLOBUS_L_SERVICE_ENGINE_START_DESERIALIZE,
71     GLOBUS_L_SERVICE_ENGINE_TRIGGER_INVOKE_HANDLERS,
72     GLOBUS_L_SERVICE_ENGINE_REQUEST_HEADER_FAILED,
73     GLOBUS_L_SERVICE_ENGINE_REQUEST_INVOKE_HANDLERS,
74     GLOBUS_L_SERVICE_ENGINE_REQUEST_INVOKE_SERVICE_HANDLERS,
75     GLOBUS_L_SERVICE_ENGINE_REQUEST_DESERIALIZE,
76     GLOBUS_L_SERVICE_ENGINE_REQUEST_DESTROY_SERVICE_HANDLERS,
77     GLOBUS_L_SERVICE_ENGINE_REQUEST_DESTROY_HANDLERS,
78     GLOBUS_L_SERVICE_ENGINE_REQUEST_INVOKE_OPERATION,
79     GLOBUS_L_SERVICE_ENGINE_REQUEST_READ_ANOTHER_MESSAGE,
80     GLOBUS_L_SERVICE_ENGINE_RESPONSE_INIT_SERVICE_HANDLERS,
81     GLOBUS_L_SERVICE_ENGINE_RESPONSE_INIT_HANDLERS,
82     GLOBUS_L_SERVICE_ENGINE_RESPONSE_INVOKE_SERVICE_HANDLERS,
83     GLOBUS_L_SERVICE_ENGINE_RESPONSE_INVOKE_HANDLERS,
84     GLOBUS_L_SERVICE_ENGINE_RESPONSE_DESTROY_SERVICE_HANDLERS,
85     GLOBUS_L_SERVICE_ENGINE_RESPONSE_DESTROY_HANDLERS,
86     GLOBUS_L_SERVICE_ENGINE_RESPONSE_SEND,
87     GLOBUS_L_SERVICE_ENGINE_RESPONSE_CLOSE,
88     GLOBUS_L_SERVICE_ENGINE_RESPONSE_DONE
89 } globus_l_service_session_state_t;
90
91 static char * globus_l_service_engine_state_strings[22] =
92 {
93     "GLOBUS_L_SERVICE_ENGINE_REQUEST_READ_MESSAGE",
94     "GLOBUS_L_SERVICE_ENGINE_REQUEST_INIT_SERVICE_HANDLERS",
95     "GLOBUS_L_SERVICE_ENGINE_REQUEST_INIT_HANDLERS",
96     "GLOBUS_L_SERVICE_ENGINE_START_DESERIALIZE",
97     "GLOBUS_L_SERVICE_ENGINE_TRIGGER_INVOKE_HANDLERS",
98     "GLOBUS_L_SERVICE_ENGINE_REQUEST_HEADER_FAILED",
99     "GLOBUS_L_SERVICE_ENGINE_REQUEST_INVOKE_HANDLERS",
100     "GLOBUS_L_SERVICE_ENGINE_REQUEST_INVOKE_SERVICE_HANDLERS",
101     "GLOBUS_L_SERVICE_ENGINE_REQUEST_DESERIALIZE",
102     "GLOBUS_L_SERVICE_ENGINE_REQUEST_DESTROY_SERVICE_HANDLERS",
103     "GLOBUS_L_SERVICE_ENGINE_REQUEST_DESTROY_HANDLERS",
104     "GLOBUS_L_SERVICE_ENGINE_REQUEST_INVOKE_OPERATION",
105     "GLOBUS_L_SERVICE_ENGINE_REQUEST_READ_ANOTHER_MESSAGE",
106     "GLOBUS_L_SERVICE_ENGINE_RESPONSE_INIT_SERVICE_HANDLERS",
107     "GLOBUS_L_SERVICE_ENGINE_RESPONSE_INIT_HANDLERS",
108     "GLOBUS_L_SERVICE_ENGINE_RESPONSE_INVOKE_SERVICE_HANDLERS",
109     "GLOBUS_L_SERVICE_ENGINE_RESPONSE_INVOKE_HANDLERS",
110     "GLOBUS_L_SERVICE_ENGINE_RESPONSE_DESTROY_SERVICE_HANDLERS",
111     "GLOBUS_L_SERVICE_ENGINE_RESPONSE_DESTROY_HANDLERS",
112     "GLOBUS_L_SERVICE_ENGINE_RESPONSE_SEND",
113     "GLOBUS_L_SERVICE_ENGINE_RESPONSE_CLOSE",
114     "GLOBUS_L_SERVICE_ENGINE_RESPONSE_DONE"
115 };
116
117 typedef struct globus_l_session_callback_handle_s
118 {
119     globus_service_engine_t                engine;
120     globus_soap_message_handle_t           message;
121     globus_service_session_callback_func_t callback;
122     void *                                 args;
123     globus_l_service_session_state_t       state;
124     globus_result_t                        result;
125     globus_result_t                        callback_result;
126     globus_service_response_t              response;
127
128     globus_service_session_callback_func_t process_callback;
129     void *                                 process_args;
130     globus_bool_t                          faulting;
131 } globus_l_session_callback_handle_t;
132
133 typedef struct
134 {
135     globus_service_engine_t               engine;
136     globus_service_engine_callback_func_t callback;
137     void *                                args;
138     globus_result_t                       result;
139 } globus_l_service_engine_callback_handle_t;
140
141 static
142 void
143 globus_l_service_session_callback(
144     void *                              args);
145
146 static
147 void
148 globus_l_service_session_callback_handle_destroy(
149     globus_l_session_callback_handle_t * callback_handle);
150
151 static
152 void
153 globus_l_service_engine_open_callback(
154     globus_xio_handle_t                 handle,
155     globus_result_t                     result,
156     void *                              user_arg);
157
158 static
159 void
160 globus_l_service_engine_service_module_destroy(
161     void *                              ext);
162
163 static
164 void
165 globus_l_service_engine_request_ready_callback(
166     globus_xio_handle_t                 handle,
167     globus_result_t                     result,
168     globus_byte_t *                     buffer,
169     globus_size_t                       len,
170     globus_size_t                       nbytes,
171     globus_xio_data_descriptor_t        data_desc,
172     void *                              user_arg);
173
174 static
175 void
176 globus_l_service_engine_accept_callback(
177     globus_xio_server_t                 server,
178     globus_xio_handle_t                 new_handle,
179     globus_result_t                     result,
180     void *                              user_args);
181
182 static
183 void
184 globus_l_service_session_result_callback(
185     globus_result_t                     result,
186     void *                              args);
187
188 static
189 void
190 globus_l_service_engine_send_client_fault(
191     void *                              args);
192
193 static
194 void 
195 globus_l_service_engine_session_complete_callback(
196     globus_result_t                     result,
197     globus_service_engine_t             engine,
198     globus_soap_message_handle_t        session,
199     void *                              args);
200
201 static
202 void
203 globus_l_service_engine_session_started_callback(
204     globus_result_t                     result,
205     globus_service_engine_t             engine,
206     globus_soap_message_handle_t        session,
207     void *                              args);
208
209 static globus_usage_stats_handle_t globus_l_service_engine_usage;
210
211 static int
212 globus_l_service_engine_activate()
213 {
214 33     int                                 rc = 0;
215 33     GlobusFuncName(globus_l_service_engine_activate);
216
217 33     rc = globus_module_activate(GLOBUS_COMMON_MODULE);
218 33     if(rc != GLOBUS_SUCCESS)
219     {
220 0         return rc;
221     }
222
223 33     GlobusDebugInit(GLOBUS_SERVICE_ENGINE, DEBUG INFO TRACE WARN ERROR);
224 33     GlobusServiceEngineDebugEnter();
225
226 33     rc = globus_module_activate(GLOBUS_SOAP_MESSAGE_MODULE);
227 33     if(rc != GLOBUS_SUCCESS)
228     {
229 0         globus_module_deactivate(GLOBUS_COMMON_MODULE);
230 0         goto error_exit;
231     }
232     
233 33     rc = globus_module_activate(GLOBUS_OPERATION_PROVIDER_MODULE);
234 33     if(rc != GLOBUS_SUCCESS)
235     {
236 0         globus_module_deactivate(GLOBUS_SOAP_MESSAGE_MODULE);
237 0         globus_module_deactivate(GLOBUS_COMMON_MODULE);
238 0         goto error_exit;
239     }
240
241 33     rc = globus_module_activate(GLOBUS_USAGE_MODULE);
242 33     if(rc != GLOBUS_SUCCESS)
243     {
244 0         globus_module_deactivate(GLOBUS_OPERATION_PROVIDER_MODULE);
245 0         globus_module_deactivate(GLOBUS_SOAP_MESSAGE_MODULE);
246 0         globus_module_deactivate(GLOBUS_COMMON_MODULE);
247 0         goto error_exit;
248     }
249
250 33     rc = globus_usage_stats_handle_init(
251         &globus_l_service_engine_usage,
252         4, 1, NULL);
253 33     if(rc == GLOBUS_SUCCESS)
254     {
255 33 globus_usage_stats_send(globus_l_service_engine_usage, 0);
256     }
257     else
258     {
259 0 globus_object_free(globus_error_get(rc));
260 0 rc = GLOBUS_SUCCESS;
261     }
262
263 33     globus_mutex_init(&globus_l_service_engine_extensions_mutex, NULL);
264     
265 33     goto exit;
266
267  error_exit:
268
269 0     GlobusServiceEngineDebugExit();
270 0     GlobusDebugDestroy(GLOBUS_SERVICE_ENGINE);
271 0     return rc;
272
273  exit:
274
275 33     GlobusServiceEngineDebugExit();
276 33     return rc;
277 }
278
279 static
280 void
281 globus_l_service_engine_extension_destroy(
282     void *                              sym)
283 59 {
284 59     char *                              symbol = (char *) sym;
285
286 59     globus_extension_deactivate(sym);
287 59     globus_free(symbol);
288 }
289
290 static int
291 globus_l_service_engine_deactivate()
292 33 {
293 33     int                                 rc = 0;
294 33     GlobusFuncName(globus_l_service_engine_deactivate);
295 33     GlobusServiceEngineDebugEnter();
296
297 33     globus_usage_stats_handle_destroy(globus_l_service_engine_usage);
298     
299 33     globus_mutex_lock(&globus_l_service_engine_extensions_mutex);
300 33     globus_list_destroy_all(globus_l_service_engine_extensions,
301                             globus_l_service_engine_extension_destroy);
302 33     globus_mutex_unlock(&globus_l_service_engine_extensions_mutex);
303 33     globus_mutex_destroy(&globus_l_service_engine_extensions_mutex);
304
305 33     rc = globus_module_deactivate(GLOBUS_USAGE_MODULE);
306 33     if(rc != GLOBUS_SUCCESS)
307     {
308 0         goto exit;
309     }
310
311 33     rc = globus_module_deactivate(GLOBUS_OPERATION_PROVIDER_MODULE);
312 33     if(rc != GLOBUS_SUCCESS)
313     {
314 0         goto exit;
315     }
316
317 33     rc = globus_module_deactivate(GLOBUS_SOAP_MESSAGE_MODULE);
318 33     if(rc != GLOBUS_SUCCESS)
319     {
320 33         goto exit;
321     }
322
323  exit:
324
325 33     GlobusServiceEngineDebugExit();
326 33     GlobusDebugDestroy(GLOBUS_SERVICE_ENGINE);
327 33     globus_module_deactivate(GLOBUS_COMMON_MODULE);
328
329 33     return rc;
330 }
331
332 static
333 globus_bool_t
334 globus_l_service_engine_timeout_callback(
335     globus_xio_handle_t                 handle,
336     globus_xio_operation_type_t         type,
337     void *                              user_arg)
338 0 {
339 0     return GLOBUS_TRUE;
340 }
341
342 globus_result_t
343 globus_service_engine_init(
344     globus_service_engine_t *           new_engine,
345     globus_soap_message_attr_t          attrs,
346     const char *                        port_contact,
347     globus_handler_chain_t              handlers,
348     globus_bool_t                       enable_https)
349 30 {
350 30     globus_result_t                     result = GLOBUS_SUCCESS;
351 30     int                                 port = 0;
352 30     globus_i_service_engine_t *         engine = NULL;
353 30     globus_xio_attr_t                   server_attr = NULL;
354 30     char *                              contact = NULL;
355 30     void *                              timeout = NULL;
356 30     globus_soap_message_auth_method_t   secattr;
357 30     GlobusFuncName(globus_service_engine_init);
358 30     GlobusServiceEngineDebugEnter();
359
360 30     engine = malloc(sizeof(globus_i_service_engine_t));
361 30     if(!engine)
362     {
363 0         result = GlobusServiceEngineErrorOutOfMemory;
364 0         goto exit;
365     }
366 30     memset(engine, 0, sizeof(globus_i_service_engine_t));
367
368 30     if(!attrs)
369     {
370 30         result = globus_soap_message_attr_init(&engine->attrs);
371 30         if(result != GLOBUS_SUCCESS)
372         {
373 0             result = GlobusServiceEngineErrorInitFailed(result);
374 0             goto exit;
375         }
376     }
377     else
378     {
379 0         result = globus_soap_message_attr_copy(
380             &engine->attrs, attrs);
381 0         if(result != GLOBUS_SUCCESS)
382         {
383 0             result = GlobusServiceEngineErrorInitFailed(result);
384 0             goto exit;
385         }
386     }
387
388 30     result = globus_xio_attr_init(&server_attr);
389 30     if(result != GLOBUS_SUCCESS)
390     {
391 0         result = GlobusServiceEngineErrorInitFailed(result);
392 0         goto error;
393     }
394         
395 30     if(port_contact)
396     {
397 27         port = atoi(port_contact);
398 27         if(port < 0)
399         {
400 0             result = GlobusServiceEngineErrorInvalidContact(port_contact);
401 0             goto error;
402         }
403
404 27         result = globus_xio_attr_cntl(server_attr, 
405                                       globus_i_soap_message_tcp_driver,
406                                       GLOBUS_XIO_TCP_SET_PORT, port);
407 27         if(result != GLOBUS_SUCCESS)
408         {
409 0             result = GlobusServiceEngineErrorInitFailed(result);
410 0             goto error;
411         }
412         
413 27         result = globus_xio_attr_cntl(server_attr, 
414                                       globus_i_soap_message_tcp_driver,
415                                       GLOBUS_XIO_TCP_SET_REUSEADDR,
416                                       GLOBUS_TRUE);
417 27         if(result != GLOBUS_SUCCESS)
418         {
419 0             result = GlobusServiceEngineErrorInitFailed(result);
420 0             goto error;
421         }
422     }
423 30     result = globus_xio_attr_cntl(server_attr,
424                                   globus_i_soap_message_tcp_driver,
425                                   GLOBUS_XIO_TCP_SET_NODELAY,
426                                   GLOBUS_TRUE);
427
428 30     if(result != GLOBUS_SUCCESS)
429     {
430 0         result = GlobusServiceEngineErrorInitFailed(result);
431 0         goto error;
432     }
433
434
435 30     timeout = globus_soap_message_attr_get(
436         engine->attrs, GLOBUS_SOAP_MESSAGE_TIMEOUT_KEY);
437 30     if(timeout)
438     {
439 0         result = globus_xio_attr_cntl(
440             server_attr,
441             GLOBUS_NULL,
442             GLOBUS_XIO_ATTR_SET_TIMEOUT_ALL,
443             globus_l_service_engine_timeout_callback,
444             timeout,
445             GLOBUS_NULL);
446 0         if(result != GLOBUS_SUCCESS)
447         {
448 0             result = GlobusSoapMessageErrorFailedTransport(
449                 result, "Failed to set timeout for xio handle");
450 0             goto exit;
451         }
452     }
453
454 30     if(enable_https)
455     {
456 1         result = globus_i_soap_message_setup_transport_security(
457             engine->attrs,
458             server_attr);
459 1         if(result != GLOBUS_SUCCESS)
460         {
461 0             result = GlobusServiceEngineErrorInitFailed(result);
462 0             goto error;
463         }
464
465 1         result = globus_xio_server_create(
466             &engine->server,
467             server_attr,
468             globus_i_soap_message_xio_https_stack);
469 1         if(result != GLOBUS_SUCCESS)
470         {
471 0             result = GlobusServiceEngineErrorInitFailed(result);
472 0             goto error;
473         }
474     }
475     else
476     {
477 29         result = globus_xio_server_create(&engine->server, 
478                                           server_attr, 
479                                           globus_i_soap_message_xio_stack);
480 29         if(result != GLOBUS_SUCCESS)
481         {
482 0             result = GlobusServiceEngineErrorInitFailed(result);
483 0             goto error;
484         }
485     }
486
487 30     globus_mutex_init(&engine->mutex, NULL);
488
489 30     globus_xio_server_get_contact_string(engine->server, &contact);
490 30     engine->contact = globus_common_create_string(
491         "http%s://%s/",
492         (enable_https ? "s" : ""),
493         contact);
494 30     free(contact);
495
496 30     if(!handlers)
497     {
498 30         int                             res = 0;
499 30         res = globus_extension_activate(GLOBUS_HANDLER_WS_ADDRESSING_LIB);
500 30         if(res != 0)
501         {
502 0             globus_object_t *           tmp = globus_error_get((globus_result_t) res);
503 0             result = GlobusServiceEngineErrorHandlerLoadFailed(
504                 GLOBUS_HANDLER_WS_ADDRESSING_MODULE,
505                 tmp);
506 0             goto error;
507         }
508         
509 30         globus_mutex_lock(&globus_l_service_engine_extensions_mutex);
510 30         globus_list_insert(&globus_l_service_engine_extensions,
511                            strdup(GLOBUS_HANDLER_WS_ADDRESSING_LIB));
512 30         globus_mutex_unlock(&globus_l_service_engine_extensions_mutex);
513
514 30         globus_handler_chain_init(&engine->handlers);
515         
516 30         result = globus_handler_chain_push(
517             engine->handlers, 
518             GLOBUS_HANDLER_TYPE_REQUEST_ALL,
519             GLOBUS_HANDLER_WS_ADDRESSING_SERVER);
520 30         if(result != GLOBUS_SUCCESS)
521         {
522 0             result = GlobusServiceEngineErrorInitFailed(result);
523 0             goto error;
524         }
525         
526 30         result = globus_handler_chain_push(
527             engine->handlers, 
528             GLOBUS_HANDLER_TYPE_RESPONSE_ALL,
529             GLOBUS_HANDLER_WS_ADDRESSING_SERVER);
530 30         if(result != GLOBUS_SUCCESS)
531         {
532 0             result = GlobusServiceEngineErrorInitFailed(result);
533 0             goto error;
534         }
535
536 30         secattr = (globus_soap_message_auth_method_t)
537             globus_soap_message_attr_get(
538                 engine->attrs,
539                 GLOBUS_SOAP_MESSAGE_AUTHENTICATION_METHOD_KEY);
540
541 30         if ((!enable_https) &&
542                 (secattr == GLOBUS_SOAP_MESSAGE_AUTH_SECURE ||
543                  secattr == GLOBUS_SOAP_MESSAGE_AUTH_SECURE_MESSAGE))
544         {
545 0             res = globus_extension_activate("globus_handler_ws_secure_message");
546 0             if(res != 0)
547             {
548 0                 globus_object_t *       tmp = globus_error_get((globus_result_t) res);
549 0                 result = GlobusServiceEngineErrorHandlerLoadFailed(
550                     "globus_handler_ws_secure_message",
551                     tmp);
552 0                 goto error;
553             }
554             
555 0             globus_mutex_lock(&globus_l_service_engine_extensions_mutex);
556 0             globus_list_insert(&globus_l_service_engine_extensions,
557                                strdup("globus_handler_ws_secure_message"));
558 0             globus_mutex_unlock(&globus_l_service_engine_extensions_mutex);
559
560 0             result = globus_handler_chain_push(
561                 engine->handlers,
562                 GLOBUS_HANDLER_TYPE_REQUEST,
563                 "globus_handler_ws_secure_message_server");
564 0             if(result != GLOBUS_SUCCESS)
565             {
566 0                 result = GlobusServiceEngineErrorInitFailed(result);
567 0                 goto error;
568             }
569
570 0             result = globus_handler_chain_push(
571                 engine->handlers,
572                 GLOBUS_HANDLER_TYPE_RESPONSE_ALL,
573                 "globus_handler_ws_secure_message_server");
574 0             if(result != GLOBUS_SUCCESS)
575             {
576 0                 result = GlobusServiceEngineErrorInitFailed(result);
577 0                 goto error;
578             }
579         }
580     }
581     else
582     {
583 0         globus_handler_chain_copy(&engine->handlers, handlers);
584     }
585
586 30     *new_engine = (globus_service_engine_t) engine;
587 30     goto exit;
588
589  error:
590
591 0     if(server_attr)
592     {
593 0         globus_xio_attr_destroy(server_attr);
594     }
595
596 0     if(engine)
597     {
598 0         if(engine->server)
599         {
600 0             globus_xio_server_close(engine->server);
601         }
602
603 0         free(engine);
604     }
605
606  exit:
607
608 30     GlobusServiceEngineDebugExit();
609 30     return result;
610 }
611
612 globus_result_t
613 globus_service_engine_get_contact(
614     globus_service_engine_t             engine,
615     char **                             contact)
616 76 {
617 76     *contact = globus_libc_strdup(engine->contact);
618 76     return GLOBUS_SUCCESS;
619 }
620
621 void
622 globus_service_engine_destroy(
623     globus_service_engine_t             engine)
624 30 {
625 30     int                                 res;
626 30     GlobusFuncName(globus_service_engine_destroy);
627 30     GlobusServiceEngineDebugEnter();
628     
629 30     if(engine->handlers)
630     {
631 30         globus_handler_chain_destroy(engine->handlers);
632     }
633
634 30     if(engine->contact)
635     {
636 30         free(engine->contact);
637     }
638
639 30     if(engine->server)
640     {
641 30         globus_xio_server_close(engine->server);
642     }
643
644 30     res = globus_mutex_destroy(&engine->mutex);
645 30     globus_assert_string((res == 0), "Failed to destroy mutex");
646
647 30     if(engine->attrs)
648     {
649 30         globus_soap_message_attr_destroy(engine->attrs);
650     }
651     
652 30     free(engine);
653 30     GlobusServiceEngineDebugExit();
654 }
655
656 static
657 void
658 globus_l_service_session_callback_handle_destroy(
659     globus_l_session_callback_handle_t * callback_handle)
660 1066 {
661 1066     if(callback_handle)
662     {
663 1066         if(callback_handle->result)
664         {
665 0             globus_object_free(globus_error_get(callback_handle->result));
666         }
667
668 1066         if(callback_handle->callback_result)
669         {
670 2             globus_object_free(
671                 globus_error_get(callback_handle->callback_result));
672         }
673                
674 1066         free(callback_handle);
675     }
676 }
677
678 static
679 void
680 globus_l_service_engine_open_callback(
681     globus_xio_handle_t                 handle,
682     globus_result_t                     result,
683     void *                              user_arg)
684 1066 {
685 1066     globus_l_session_callback_handle_t *callback_handle = NULL;
686 1066     static globus_byte_t                buffer[1];
687 1066     GlobusFuncName(globus_l_service_engine_open_callback);
688 1066     GlobusServiceEngineDebugEnter();
689
690 1066     callback_handle = (globus_l_session_callback_handle_t *) user_arg;
691
692 1066     globus_mutex_lock(&callback_handle->engine->mutex);
693 1066     if(result == GLOBUS_SUCCESS)
694     {
695 1066         result = globus_xio_register_read(handle,
696                 buffer,
697                 0,
698                 0,
699                 NULL,
700                 globus_l_service_engine_request_ready_callback,
701                 callback_handle);
702     }
703
704 1066     if (result != GLOBUS_SUCCESS)
705     {
706 0         globus_soap_message_handle_destroy(callback_handle->message);
707 0         callback_handle->message = NULL;
708 0         callback_handle->callback(
709             result, callback_handle->engine,
710             callback_handle->message, callback_handle->args);
711     }
712 1066     globus_mutex_unlock(&callback_handle->engine->mutex);
713     
714 1066     GlobusServiceEngineDebugExit();
715 }
716
717 static
718 globus_result_t
719 globus_l_service_engine_service_module_copy(
720     void **                             ne,
721     void *                              e)
722 2123 {
723 2123     globus_extension_reference((globus_extension_handle_t)e);
724 2123     *ne = e;
725 2123     return GLOBUS_SUCCESS;
726 }
727
728 static
729 void
730 globus_l_service_engine_service_module_destroy(
731     void *                              e)
732 2123 {
733 2123     globus_extension_release((globus_extension_handle_t)e);
734 }
735
736 static
737 void
738 globus_l_service_engine_request_ready_callback(
739     globus_xio_handle_t                 handle,
740     globus_result_t                     result,
741     globus_byte_t *                     buffer,
742     globus_size_t                       len,
743     globus_size_t                       nbytes,
744     globus_xio_data_descriptor_t        data_desc,
745     void *                              user_arg)
746 3189 {
747 3189     const char *                        uriref = NULL;
748 3189     char *                              service_path = NULL;
749 3189     globus_xio_http_header_t *          soap_action = NULL;
750 3189     globus_xio_http_header_t *          content_type = NULL;
751 3189     globus_xio_http_header_t *          connection = NULL;
752 3189     char *                              method = NULL;
753 3189     char *                              uri = NULL;
754 3189     globus_xio_http_version_t           http_version;
755 3189     globus_hashtable_t                  headers;
756     
757 3189     globus_l_session_callback_handle_t * callback_handle = NULL;
758 3189     GlobusFuncName(globus_l_service_engine_request_ready_callback);
759 3189     GlobusServiceEngineDebugEnter();
760
761 3189     callback_handle = (globus_l_session_callback_handle_t *) user_arg;
762
763 3189     if (result == GLOBUS_SUCCESS)
764     {
765 2124         result = globus_xio_data_descriptor_cntl(
766                 data_desc,
767                 globus_i_soap_message_http_driver,
768                 GLOBUS_XIO_HTTP_GET_REQUEST,
769                 &method,
770                 &uri,
771                 &http_version,
772                 &headers);
773
774     }
775
776 3189     if (method == NULL || result != GLOBUS_SUCCESS)
777     {
778         /* No more requests */
779 1065         if (callback_handle->process_callback != NULL)
780         {
781 1065             callback_handle->state = GLOBUS_L_SERVICE_ENGINE_RESPONSE_CLOSE;
782 1065             globus_soap_message_handle_set_attr(
783                 callback_handle->message,
784                 GLOBUS_SOAP_MESSAGE_CONNECTION_KEY,
785                 globus_soap_message_attr_copy_string,
786                 globus_libc_free,
787                 (void *) "close");
788         }
789     }
790 2124     else if(!strcmp(method, "POST"))
791     {
792 2124         globus_extension_handle_t       ext;
793 2124         globus_service_descriptor_t *   service_desc;
794
795 2124         soap_action = (globus_xio_http_header_t *)
796         globus_hashtable_lookup(&headers, (void *) SOAP_ACTION_HEADER);
797 2124         if(!soap_action)
798         {
799 0             GlobusServiceEngineDebugPrintf(
800                 GLOBUS_L_SERVICE_ENGINE_DEBUG_DEBUG, 
801                 ("Service request: %s does not "
802                  "have a SOAPAction header entry\n",
803                  uri));
804         }
805
806 2124         content_type = (globus_xio_http_header_t *)
807         globus_hashtable_lookup(&headers, (void *) CONTENT_TYPE_HEADER);
808 2124         if(!content_type || !content_type->value || 
809            !strstr(content_type->value, "text/xml"))
810         {
811 0             result = GlobusServiceEngineErrorUnsupportedMediaType(
812                 content_type->value);
813 0             goto exit;
814         }
815 2124         if (http_version != GLOBUS_XIO_HTTP_VERSION_1_0)
816         {
817             /*
818              * Assume persistent connection with HTTP/1.1 unless told 
819              * otherwise
820              */
821 2124             connection = globus_hashtable_lookup(
822                     &headers,
823                     (void *) "Connection");
824 2124             if (connection && connection->value &&
825                         strstr(connection->value, "close"))
826             {
827 0                 result = globus_soap_message_handle_set_attr(
828                     callback_handle->message,
829                     GLOBUS_SOAP_MESSAGE_CONNECTION_KEY,
830                     globus_soap_message_attr_copy_string,
831                     globus_libc_free,
832                     (void *) "close");
833             }
834         }
835         else
836         {
837 0             result = globus_soap_message_handle_set_attr(
838                 callback_handle->message,
839                 GLOBUS_SOAP_MESSAGE_CONNECTION_KEY,
840                 globus_soap_message_attr_copy_string,
841                 globus_libc_free,
842                 (void *) "close");
843         }
844 2124         if (result != GLOBUS_SUCCESS)
845         {
846 0             goto exit;
847         }
848
849 2124         uriref = uri;
850 4248         while (*uriref == '/')
851         {
852 2124             uriref++;
853         }
854
855 2124         service_path = globus_common_create_string(
856             GLOBUS_SERVICE_ENGINE_MODULE_PATH_PREFIX "/%s", uriref);
857 2124         service_desc = globus_extension_lookup(
858             &ext,
859             GLOBUS_SERVICE_REGISTRY,
860             service_path);
861 2124         if(!service_desc)
862         {
863 30             int                         res = 0;
864
865 30             res = globus_extension_activate(
866                 service_path);
867 30             if(res != GLOBUS_SUCCESS)
868             {
869 1                 globus_object_t *       tmp_err = globus_error_get((globus_result_t) res);
870 1 if(GlobusServiceEngineDebug(
871 GLOBUS_L_SERVICE_ENGINE_DEBUG_DEBUG))
872 {
873 0     char * serror = globus_error_print_chain(
874 0 tmp_err);
875 0     GlobusServiceEngineDebugPrintf(
876 GLOBUS_L_SERVICE_ENGINE_DEBUG_DEBUG,
877 ("Module Activation Failed:\n\n%s\n",
878 serror));
879 0     globus_free(serror);
880 }
881
882 1                 result = GlobusServiceEngineErrorServiceLoadFailed(uri, tmp_err);
883 1                 goto exit;
884             }
885
886 29             globus_mutex_lock(&globus_l_service_engine_extensions_mutex);
887 29             globus_list_insert(&globus_l_service_engine_extensions,
888                                strdup(service_path));
889 29             globus_mutex_unlock(&globus_l_service_engine_extensions_mutex);
890
891 29             service_desc = (globus_service_descriptor_t *) 
892             globus_extension_lookup(&ext, GLOBUS_SERVICE_REGISTRY, 
893                                     service_path);
894 29             if(!service_desc)
895             {
896 0                 result = GlobusServiceEngineErrorServiceLoadFailed(uri, NULL);
897 0                 goto exit;
898             }
899         }
900
901 2123         result = globus_soap_message_handle_set_attr(
902             callback_handle->message,
903             GLOBUS_SOAP_MESSAGE_SERVICE_ENDPOINT_KEY,
904             globus_soap_message_attr_copy_string,
905             globus_libc_free,
906             (void *)uri);
907 2123         if(result != GLOBUS_SUCCESS)
908         {
909 0             result = GlobusServiceEngineErrorReadRequestFailed(result);
910 0             goto exit;
911         }
912
913 2123         result = globus_soap_message_handle_set_attr(
914             callback_handle->message,
915             GLOBUS_I_SERVICE_DESCRIPTOR_KEY,
916             globus_l_service_engine_service_module_copy,
917             globus_l_service_engine_service_module_destroy,
918             (void *)ext);
919 2123         if(result != GLOBUS_SUCCESS)
920         {
921 0             result = GlobusServiceEngineErrorReadRequestFailed(result);
922 0             goto exit;
923         }
924
925 2123         if(soap_action)
926         {
927 2123             result = globus_soap_message_handle_set_attr(
928                 callback_handle->message,
929                 GLOBUS_SOAP_MESSAGE_SOAP_ACTION_KEY,
930                 globus_soap_message_attr_copy_string,
931                 globus_libc_free,
932                 (void *)soap_action->value);
933 2123             if(result != GLOBUS_SUCCESS)
934             {
935 0                 result = GlobusServiceEngineErrorReadRequestFailed(result);
936 0                 goto exit;
937             }
938         }
939     }
940     else
941     {
942 0         result = GlobusServiceEngineErrorMethodNotAllowed(method);
943 0         goto exit;
944     }
945
946 3188     if (callback_handle->state ==
947             GLOBUS_L_SERVICE_ENGINE_REQUEST_READ_ANOTHER_MESSAGE ||
948         callback_handle->state ==
949             GLOBUS_L_SERVICE_ENGINE_RESPONSE_CLOSE)
950     {
951 2123         result = globus_callback_register_oneshot(
952             NULL,
953             &globus_i_reltime_zero,
954             globus_l_service_session_callback,
955             callback_handle);
956 2123         if(result == GLOBUS_SUCCESS)
957         {
958 2123             goto no_callback_exit;
959         }
960         else
961         {
962 0             result = GlobusServiceEngineErrorFailedRequestProcess(
963                 result, "Failed to register callback to invoke operation");
964             goto exit;
965         }
966     }
967  exit:
968
969 1066     if(result != GLOBUS_SUCCESS)
970     {
971 1         callback_handle->result = result;
972 1         globus_soap_message_handle_set_attr(
973             callback_handle->message,
974             GLOBUS_SOAP_MESSAGE_CONNECTION_KEY,
975             globus_soap_message_attr_copy_string,
976             globus_libc_free,
977             (void *) "close");
978     }
979
980 1066     callback_handle->callback(
981         result, callback_handle->engine,
982         callback_handle->message, callback_handle->args);
983
984 no_callback_exit:
985
986 3189     if(service_path)
987     {
988 2124         free(service_path);
989     }
990
991
992 3189     GlobusServiceEngineDebugExit();
993 }
994
995 static
996 void
997 globus_l_service_engine_accept_callback(
998     globus_xio_server_t                 server,
999     globus_xio_handle_t                 new_handle,
1000     globus_result_t                     result,
1001     void *                              user_args)
1002 1096 {
1003 1096     char *                              peer_contact = NULL;
1004 1096     globus_xio_attr_t                   attr;
1005 1096     globus_soap_message_handle_t        message = NULL;
1006 1096     globus_l_session_callback_handle_t * callback_handle;
1007 1096     GlobusFuncName(globus_l_service_engine_accept_callback);
1008 1096     GlobusServiceEngineDebugEnter();
1009     
1010 1096     callback_handle = (globus_l_session_callback_handle_t *) user_args;
1011
1012 1096     if(result != GLOBUS_SUCCESS)
1013     {
1014 30         goto exit;
1015     }
1016
1017 1066     result = globus_soap_message_handle_init(&message, new_handle);
1018 1066     if(result != GLOBUS_SUCCESS)
1019     {
1020 0         result = GlobusServiceEngineErrorFailedRequest(result);
1021 0         goto exit;
1022     }
1023 1066     globus_mutex_lock(&callback_handle->engine->mutex);
1024 1066     result = globus_soap_message_handle_set_attrs(
1025         message,
1026         callback_handle->engine->attrs);
1027 1066     if(result != GLOBUS_SUCCESS)
1028     {
1029 0         globus_mutex_unlock(&callback_handle->engine->mutex);
1030 0         result = GlobusServiceEngineErrorFailedRequest(result);
1031 0         goto exit;
1032     }
1033 1066     result = globus_soap_message_handle_set_attr(
1034         message,
1035         GLOBUS_I_SESSION_HANDLE_KEY,
1036         NULL,
1037         NULL,
1038         callback_handle);
1039 1066     if(result != GLOBUS_SUCCESS)
1040     {
1041 0         globus_mutex_unlock(&callback_handle->engine->mutex);
1042 0         result = GlobusServiceEngineErrorFailedRequest(result);
1043 0         goto exit;
1044     }
1045
1046 1066     globus_mutex_unlock(&callback_handle->engine->mutex);
1047         
1048 1066     callback_handle->message = message;
1049
1050 1066     result = globus_xio_attr_init(&attr);
1051 1066     if(result != GLOBUS_SUCCESS)
1052     {
1053 0         result = GlobusServiceEngineErrorFailedRequest(result);
1054 0         goto exit;
1055     }
1056
1057 1066     result = globus_xio_handle_cntl(
1058         new_handle, globus_i_soap_message_tcp_driver,
1059         GLOBUS_XIO_TCP_GET_REMOTE_CONTACT,
1060         &peer_contact);
1061 1066     if(result != GLOBUS_SUCCESS)
1062     {
1063 0         result = GlobusServiceEngineErrorFailedRequest(result);
1064 0         goto exit;
1065     }
1066
1067 1066     result = globus_xio_register_open(
1068         new_handle, peer_contact, attr, 
1069         globus_l_service_engine_open_callback, callback_handle);
1070 1066     if(result != GLOBUS_SUCCESS)
1071     {
1072 0         result = GlobusServiceEngineErrorFailedRequest(result);
1073         goto exit;
1074     }
1075
1076  exit:
1077 1096     if (peer_contact != NULL)
1078     {
1079 1066         globus_libc_free(peer_contact);
1080     }
1081
1082 1096     if(result != GLOBUS_SUCCESS)
1083     {
1084 30         callback_handle->callback(result, callback_handle->engine, 
1085                                   message, callback_handle->args);
1086 30         free(callback_handle);
1087 30         if(message)
1088         {
1089 0             globus_soap_message_handle_destroy(message);
1090         }
1091     }
1092
1093 1096     GlobusServiceEngineDebugExit();
1094 }
1095
1096 globus_result_t
1097 globus_service_engine_register_session(
1098     globus_service_engine_t                engine,
1099     globus_service_session_callback_func_t callback,
1100     void *                                 user_args)
1101 1096 {
1102 1096     globus_l_session_callback_handle_t * callback_handle = NULL;
1103 1096     globus_result_t                     result = GLOBUS_SUCCESS;
1104 1096     GlobusFuncName(globus_service_engine_register_session);
1105 1096     GlobusServiceEngineDebugEnter();
1106
1107 1096     callback_handle = calloc(1, sizeof(globus_l_session_callback_handle_t));
1108 1096     if(!callback_handle)
1109     {
1110 0         result = GlobusServiceEngineErrorOutOfMemory;
1111 0         goto exit;
1112     }
1113
1114 1096     callback_handle->callback = callback;
1115 1096     callback_handle->args = user_args;
1116 1096     callback_handle->engine = engine;
1117 1096     callback_handle->faulting = GLOBUS_FALSE;
1118
1119 1096     result = globus_xio_server_register_accept(
1120         engine->server,
1121         globus_l_service_engine_accept_callback,
1122         callback_handle);
1123 1096     if(result != GLOBUS_SUCCESS)
1124     {
1125 0         result = GlobusServiceEngineErrorAcceptFailed(result);
1126         goto exit;
1127     }
1128
1129  exit:
1130
1131 1096     GlobusServiceEngineDebugExit();
1132 1096     return result;
1133 }
1134
1135 static
1136 void
1137 globus_l_service_session_result_callback(
1138     globus_result_t                    result,
1139     void *                             args)
1140 32861 {
1141 32861     globus_l_session_callback_handle_t * callback_handle;
1142 32861     GlobusFuncName(globus_l_service_session_result_callback);
1143 32861     GlobusServiceEngineDebugEnter();
1144
1145 32861     callback_handle = (globus_l_session_callback_handle_t *) args;
1146 32861     callback_handle->result = result;
1147
1148 32861     globus_l_service_session_callback(callback_handle);
1149
1150 32861     GlobusServiceEngineDebugExit();
1151 }
1152
1153 static
1154 void
1155 globus_l_service_session_callback(
1156     void *                              args)
1157 38174 {
1158 38174     globus_result_t                      result = GLOBUS_SUCCESS;
1159 38174     globus_service_descriptor_t *        service_desc = NULL;
1160 38174     globus_extension_handle_t            ext;
1161 38174     globus_l_session_callback_handle_t * callback_handle;
1162 38174     globus_service_operation_descriptor_t * op_desc = NULL;
1163 38174     xsd_QName *                          operation_name = NULL;
1164 38174     xsd_QName *                          header_element = NULL;
1165 38174     xsd_int                              must = 0;
1166 38174     char *                               connection;
1167 38174     globus_xio_handle_t                  xio_handle;
1168 38174     static globus_byte_t                 buffer[1];
1169 38174     GlobusFuncName(globus_l_service_session_callback);
1170 38174     GlobusServiceEngineDebugEnter();
1171
1172 38174     callback_handle = (globus_l_session_callback_handle_t *) args;
1173
1174 38174     if(callback_handle->result != GLOBUS_SUCCESS)
1175     {
1176 1         if(!callback_handle->faulting)
1177         {
1178 0             result = callback_handle->result;
1179 0             goto error_send_fault;
1180         }
1181         else
1182         {
1183 1             char * errstr;
1184
1185 1             errstr = globus_error_print_friendly(
1186                     globus_error_peek(
1187                         callback_handle->result));
1188
1189 1             GlobusServiceEngineDebugPrintf(
1190                 GLOBUS_L_SERVICE_ENGINE_DEBUG_DEBUG,
1191                 ("error occurred while sending a fault: %s\n", 
1192                  errstr));
1193
1194 1             free(errstr);
1195
1196 1             callback_handle->result = GLOBUS_SUCCESS;
1197         }
1198     }
1199
1200 38174     GlobusServiceEngineDebugPrintf(
1201         GLOBUS_L_SERVICE_ENGINE_DEBUG_DEBUG,
1202         ("STATE: %s\n", 
1203  globus_l_service_engine_state_strings[callback_handle->state]));
1204
1205 38174     switch(callback_handle->state)
1206     {
1207
1208     case GLOBUS_L_SERVICE_ENGINE_REQUEST_READ_ANOTHER_MESSAGE:
1209 1058         result = globus_soap_message_get_transport_handle(
1210             callback_handle->message,
1211             &xio_handle);
1212 1058         if (result != GLOBUS_SUCCESS)
1213         {
1214 0             goto error_send_fault;
1215         }
1216 1058         result = globus_xio_handle_cntl(
1217                 xio_handle,
1218                 globus_i_soap_message_buffer_driver,
1219                 GLOBUS_XIO_BUFFER_ENABLE_READ_BUFFERING);
1220 1058         if (result != GLOBUS_SUCCESS)
1221         {
1222 0             goto error_send_fault;
1223         }
1224 1058         result = globus_i_soap_message_reset_reader(callback_handle->message);
1225 1058         if (result != GLOBUS_SUCCESS)
1226         {
1227 0             goto error_send_fault;
1228         }
1229         /* FALLSTHROUGH */
1230     case GLOBUS_L_SERVICE_ENGINE_REQUEST_READ_MESSAGE:
1231
1232 2123         callback_handle->state =
1233         GLOBUS_L_SERVICE_ENGINE_REQUEST_INIT_SERVICE_HANDLERS;
1234
1235 2123         if(callback_handle->result != GLOBUS_SUCCESS)
1236         {
1237 0             result = callback_handle->result;
1238 0             goto error_send_fault;
1239         }
1240
1241 2123         result = globus_soap_message_register_read_request(
1242             callback_handle->message,
1243             globus_l_service_session_result_callback,
1244             callback_handle);
1245 2123         if(result != GLOBUS_SUCCESS)
1246         {
1247 0             goto error_send_fault;
1248         }
1249
1250 2123         break;
1251
1252     case GLOBUS_L_SERVICE_ENGINE_REQUEST_INIT_SERVICE_HANDLERS:
1253
1254 2123 callback_handle->state =
1255 GLOBUS_L_SERVICE_ENGINE_REQUEST_INIT_HANDLERS;
1256
1257 2123 if(callback_handle->result != GLOBUS_SUCCESS)
1258 {
1259 0     result = callback_handle->result;
1260 0     goto error_send_fault;
1261 }
1262
1263 2123 ext =
1264         (globus_extension_handle_t)
1265         globus_soap_message_handle_get_attr(
1266             callback_handle->message,
1267             GLOBUS_I_SERVICE_DESCRIPTOR_KEY);
1268 2123         globus_assert_string(
1269             ext, "No SERVICE DESCRIPTOR attribute found!");
1270                 
1271 2123         service_desc = (globus_service_descriptor_t *) 
1272         globus_extension_reference(ext);
1273         
1274 2123         globus_assert_string(
1275             service_desc, "No SERVICE DESCRIPTOR attribute found!");
1276         
1277 2123         globus_mutex_lock(&service_desc->mutex);
1278 2123         if(service_desc->handlers)
1279         {
1280 0     globus_handler_chain_register_invoke(
1281     service_desc->handlers,
1282     GLOBUS_HANDLER_TYPE_REQUEST_INIT,
1283     callback_handle->message,
1284     globus_l_service_session_result_callback,
1285     callback_handle);
1286         
1287 0     globus_mutex_unlock(&service_desc->mutex);
1288 0     service_desc = NULL;
1289 0     globus_extension_release(ext);
1290 0     break;
1291 }
1292 2123 globus_mutex_unlock(&service_desc->mutex);
1293 2123 service_desc = NULL;
1294 2123 globus_extension_release(ext);
1295     
1296     case GLOBUS_L_SERVICE_ENGINE_REQUEST_INIT_HANDLERS:
1297
1298 2123 callback_handle->state =
1299 GLOBUS_L_SERVICE_ENGINE_START_DESERIALIZE;
1300
1301 2123 if(callback_handle->result != GLOBUS_SUCCESS)
1302 {
1303 0     result = callback_handle->result;
1304 0     goto error_send_fault;
1305 }
1306
1307 2123         globus_mutex_lock(&callback_handle->engine->mutex);
1308 2123         if(callback_handle->engine->handlers)
1309         {
1310 2123             globus_handler_chain_register_invoke(
1311                 callback_handle->engine->handlers,
1312 GLOBUS_HANDLER_TYPE_REQUEST_INIT,
1313                 callback_handle->message,
1314                 globus_l_service_session_result_callback,
1315                 callback_handle);
1316 2123     globus_mutex_unlock(&callback_handle->engine->mutex);
1317 2123     break;
1318         }
1319 0         globus_mutex_unlock(&callback_handle->engine->mutex);
1320
1321     case GLOBUS_L_SERVICE_ENGINE_START_DESERIALIZE:
1322
1323 2123         callback_handle->state = 
1324         GLOBUS_L_SERVICE_ENGINE_TRIGGER_INVOKE_HANDLERS;
1325
1326 2123         if(callback_handle->result != GLOBUS_SUCCESS)
1327         {
1328 0             result = callback_handle->result;
1329 0             goto error_send_fault;
1330         }
1331
1332 2123         result = globus_soap_message_deserialize_envelope(
1333             callback_handle->message);
1334 2123         if(result != GLOBUS_SUCCESS)
1335         {
1336 0             goto error_send_fault;
1337         }
1338
1339 2123         result = globus_soap_message_deserialize_element_begin_close(
1340             callback_handle->message);
1341 2123         if(result != GLOBUS_SUCCESS)
1342         {
1343 0             goto error_send_fault;
1344         }
1345
1346 2123         result = globus_soap_message_deserialize_header(
1347             callback_handle->message);
1348 2123         if(result != GLOBUS_SUCCESS)
1349         {
1350 0             if(GlobusSoapMessageStatusElementNotFoundCheck(result))
1351             {
1352 0                 globus_soap_message_deserialize_push_element(
1353                     callback_handle->message);
1354 0                 result = GLOBUS_SUCCESS;
1355 0                 callback_handle->state = 
1356                 GLOBUS_L_SERVICE_ENGINE_REQUEST_HEADER_FAILED;
1357 0                 callback_handle->result = result;
1358 0                 globus_l_service_session_callback(
1359                     callback_handle);
1360 0                 break;
1361             }
1362
1363 12690             goto error_send_fault;
1364         }
1365
1366     case GLOBUS_L_SERVICE_ENGINE_TRIGGER_INVOKE_HANDLERS:
1367
1368 12690         callback_handle->state = 
1369         GLOBUS_L_SERVICE_ENGINE_TRIGGER_INVOKE_HANDLERS;
1370
1371 12690         if(callback_handle->result != GLOBUS_SUCCESS)
1372         {
1373 0             result = callback_handle->result;
1374 0             goto error_send_fault;
1375         }
1376
1377 12690         xsd_QName_init(&header_element);
1378         
1379 12690         result = globus_soap_message_deserialize_element_unknown(
1380             callback_handle->message,
1381             header_element);
1382 12690         if(result != GLOBUS_SUCCESS)
1383         {
1384 2123             if(!GlobusSoapMessageStatusFailedElementCheck(result))
1385             {
1386 0                 xsd_QName_destroy(header_element);
1387 0                 goto error_send_fault;
1388             }
1389             else
1390             {
1391 2123                 callback_handle->state = 
1392                 GLOBUS_L_SERVICE_ENGINE_REQUEST_DESERIALIZE;
1393 2123                 globus_callback_register_oneshot(
1394                     NULL,
1395                     &globus_i_reltime_zero,
1396                     globus_l_service_session_callback,
1397                     (void *)callback_handle);
1398 2123                 xsd_QName_destroy(header_element);
1399 2123                 break;
1400             }
1401         }
1402
1403 10567         result = globus_soap_message_deserialize_int_attribute(
1404             callback_handle->message,
1405             &soap_mustUnderstand_qname,
1406             &must);
1407 10567         if(result == GLOBUS_SUCCESS && (must == 1))
1408         {
1409 0             globus_soap_message_add_required_header_element(
1410                 callback_handle->message,
1411                 header_element);
1412         }
1413 10567         else if(result != GLOBUS_SUCCESS &&
1414                 !GlobusSoapMessageStatusAttributeNotFoundCheck(result))
1415         {
1416 0             xsd_QName_destroy(header_element);
1417 0             goto error_send_fault;
1418         }
1419
1420 10567         globus_soap_message_deserialize_push_element(callback_handle->message);
1421
1422 10567 ext =
1423         (globus_extension_handle_t)
1424         globus_soap_message_handle_get_attr(
1425             callback_handle->message,
1426             GLOBUS_I_SERVICE_DESCRIPTOR_KEY);
1427 10567         globus_assert_string(
1428             ext, "No SERVICE DESCRIPTOR attribute found!");
1429                 
1430 10567         service_desc = (globus_service_descriptor_t *) 
1431         globus_extension_reference(ext);
1432         
1433 10567         globus_assert_string(
1434             service_desc, "No SERVICE DESCRIPTOR attribute found!");
1435         
1436 10567         globus_mutex_lock(&service_desc->mutex);
1437 10567         if(service_desc->handlers)
1438         {
1439 0             if(globus_handler_chain_has_trigger(
1440     service_desc->handlers, header_element))
1441     {
1442 0 result = globus_handler_chain_register_trigger(
1443     service_desc->handlers,
1444     callback_handle->message,
1445     header_element,
1446     globus_l_service_session_result_callback,
1447     callback_handle);
1448 0 if(result == GLOBUS_SUCCESS)
1449 {
1450 0     xsd_QName_destroy(header_element);
1451 0     globus_mutex_unlock(&service_desc->mutex);
1452 0     service_desc = NULL;
1453 0     globus_extension_release(ext);
1454 0     break;
1455 }
1456 0 else if(!GlobusHandlerStatusNotTriggeredCheck(result))
1457 {
1458 0     xsd_QName_destroy(header_element);
1459 0     globus_mutex_unlock(&service_desc->mutex);
1460 0     service_desc = NULL;
1461 0     globus_extension_release(ext);
1462 0     goto error_send_fault;
1463 }
1464     }
1465         }
1466 10567         globus_mutex_unlock(&service_desc->mutex);
1467 10567         service_desc = NULL;
1468 10567         globus_extension_release(ext);
1469
1470 10567         globus_mutex_lock(&callback_handle->engine->mutex);
1471 10567         if(callback_handle->engine->handlers)
1472         {
1473 10567             result = globus_handler_chain_register_trigger(
1474                 callback_handle->engine->handlers,
1475                 callback_handle->message,
1476                 header_element,
1477                 globus_l_service_session_result_callback,
1478                 callback_handle);
1479 10567             if(result == GLOBUS_SUCCESS)
1480             {
1481 10567                 xsd_QName_destroy(header_element);
1482 10567                 globus_mutex_unlock(&callback_handle->engine->mutex);
1483 10567                 break;
1484             }
1485 0             else if(!GlobusHandlerStatusNotTriggeredCheck(result))
1486             {
1487 0                 xsd_QName_destroy(header_element);
1488 0                 globus_mutex_unlock(&callback_handle->engine->mutex);
1489 0                 goto error_send_fault;
1490             }
1491         }
1492 0         globus_mutex_unlock(&callback_handle->engine->mutex);
1493         
1494 0         xsd_QName_destroy(header_element);
1495 0         result = globus_soap_message_deserialize_skip(
1496             callback_handle->message);
1497 0         if(result != GLOBUS_SUCCESS)
1498         {
1499 0             goto error_send_fault;
1500         }
1501
1502 0         globus_callback_register_oneshot(
1503             NULL,
1504             &globus_i_reltime_zero,
1505             globus_l_service_session_callback,
1506             (void *)callback_handle);
1507 0         break;
1508
1509     case GLOBUS_L_SERVICE_ENGINE_REQUEST_DESERIALIZE:
1510         
1511 2123         if(callback_handle->result != GLOBUS_SUCCESS)
1512         {
1513 0             result = callback_handle->result;
1514 0             goto error_send_fault;
1515         }
1516
1517 2123 result = globus_soap_message_check_required_headers(
1518     callback_handle->message);
1519 2123 if(result != GLOBUS_SUCCESS)
1520 {
1521 0     goto error_send_fault;
1522 }
1523
1524 2123         result = globus_soap_message_deserialize_header_end(
1525             callback_handle->message);
1526 2123         if(result != GLOBUS_SUCCESS)
1527         {
1528 0             goto error_send_fault;
1529         }
1530
1531     case GLOBUS_L_SERVICE_ENGINE_REQUEST_HEADER_FAILED:
1532
1533 2123         callback_handle->state = 
1534         GLOBUS_L_SERVICE_ENGINE_REQUEST_INVOKE_HANDLERS;
1535
1536 2123         if(callback_handle->result != GLOBUS_SUCCESS)
1537         {
1538 0             result = callback_handle->result;
1539 0             goto error_send_fault;
1540         }
1541
1542 2123         result = globus_soap_message_deserialize_body(
1543             callback_handle->message);
1544 2123         if(result != GLOBUS_SUCCESS)
1545         {
1546 0             goto error_send_fault;
1547         }
1548
1549 2123         xsd_QName_init(&operation_name);
1550
1551 2123         result = globus_soap_message_deserialize_element_unknown(
1552             callback_handle->message, operation_name);
1553 2123         if(result != GLOBUS_SUCCESS)
1554         {
1555 0             xsd_QName_destroy(operation_name);
1556 0             goto error_send_fault;
1557         }
1558
1559 2123         result = globus_soap_message_handle_set_attr(
1560             callback_handle->message,
1561             GLOBUS_I_SERVICE_OPERATION_QNAME_KEY,
1562             xsd_QName_copy_wrapper,
1563             xsd_QName_destroy_wrapper,
1564             operation_name);
1565 2123         if(result != GLOBUS_SUCCESS)
1566         {
1567 0             xsd_QName_destroy(operation_name);
1568 0             goto error_send_fault;
1569         }
1570
1571 2123         globus_soap_message_deserialize_push_element(
1572             callback_handle->message);
1573 2123         if(result != GLOBUS_SUCCESS)
1574         {
1575 0             goto error_send_fault;
1576         }
1577
1578 2123         ext = 
1579         (globus_extension_handle_t)
1580         globus_soap_message_handle_get_attr(
1581             callback_handle->message,
1582             GLOBUS_I_SERVICE_DESCRIPTOR_KEY);
1583 2123         globus_assert_string(
1584             ext, "No SERVICE DESCRIPTOR attribute found!");
1585
1586 2123         service_desc = (globus_service_descriptor_t *) 
1587         globus_extension_reference(ext);
1588
1589 2123         globus_assert_string(
1590             service_desc, "No SERVICE DESCRIPTOR attribute found!");
1591
1592         /* we use qn to map to operation deserialize function */
1593 2123         globus_mutex_lock(&service_desc->mutex);
1594 2123         if(service_desc->op_mapper)
1595         {
1596 2123             op_desc = (globus_service_operation_descriptor_t *)
1597             globus_hashtable_lookup(
1598                 &service_desc->op_mapper, 
1599                 (void *)operation_name);
1600         }
1601
1602 2123         if(!op_desc)
1603         {
1604 1             result = GlobusServiceEngineErrorOperationLookupFailed(
1605                 service_desc->name, operation_name);
1606 1             globus_mutex_unlock(&service_desc->mutex);
1607 1             service_desc = NULL;
1608 1             globus_extension_release(ext);
1609 1             goto error_send_fault;
1610         }
1611
1612 2122         result = op_desc->deserialize(
1613             callback_handle->engine,
1614             callback_handle->message,
1615             globus_l_service_session_result_callback,
1616             callback_handle);
1617 2122         if(result != GLOBUS_SUCCESS)
1618         {
1619 0             result = GlobusServiceEngineErrorOpDeserializeFailed(
1620                 result, operation_name);
1621 0             globus_mutex_unlock(&service_desc->mutex);
1622 0             goto error_send_fault;
1623         }
1624
1625 2122         globus_mutex_unlock(&service_desc->mutex);
1626 2122         service_desc = NULL;
1627 2122         globus_extension_release(ext);
1628
1629 2122         break;
1630
1631     case GLOBUS_L_SERVICE_ENGINE_REQUEST_INVOKE_HANDLERS:
1632
1633 2122         callback_handle->state = 
1634         GLOBUS_L_SERVICE_ENGINE_REQUEST_INVOKE_SERVICE_HANDLERS;
1635
1636 2122         if(callback_handle->result != GLOBUS_SUCCESS)
1637         {
1638 0             result = callback_handle->result;
1639 0             goto error_send_fault;
1640         }
1641
1642 2122         result = globus_soap_message_deserialize_body_end(
1643             callback_handle->message);
1644 2122         if(result != GLOBUS_SUCCESS)
1645         {
1646 0             goto error_send_fault;
1647         }
1648
1649 2122         result = globus_soap_message_deserialize_envelope_end(
1650             callback_handle->message);
1651 2122         if(result != GLOBUS_SUCCESS)
1652         {
1653 0             goto error_send_fault;
1654         }
1655
1656 2122         globus_mutex_lock(&callback_handle->engine->mutex);
1657 2122         if(callback_handle->engine->handlers)
1658         {        
1659 2122             globus_handler_chain_register_invoke(
1660                 callback_handle->engine->handlers,
1661                 GLOBUS_HANDLER_TYPE_REQUEST,
1662                 callback_handle->message,
1663                 globus_l_service_session_result_callback,
1664                 callback_handle);
1665 2122             globus_mutex_unlock(&callback_handle->engine->mutex);
1666 2122             break;
1667         }
1668 0         globus_mutex_unlock(&callback_handle->engine->mutex);
1669
1670     case GLOBUS_L_SERVICE_ENGINE_REQUEST_INVOKE_SERVICE_HANDLERS:
1671
1672 2122         callback_handle->state = 
1673         GLOBUS_L_SERVICE_ENGINE_REQUEST_DESTROY_HANDLERS;
1674
1675 2122         if(callback_handle->result != GLOBUS_SUCCESS)
1676         {
1677 0             result = callback_handle->result;
1678 0             goto error_send_fault;
1679         }
1680
1681 2122         ext =
1682         (globus_extension_handle_t)
1683         globus_soap_message_handle_get_attr(
1684             callback_handle->message,
1685             GLOBUS_I_SERVICE_DESCRIPTOR_KEY);
1686 2122         globus_assert_string(
1687             ext, "No SERVICE DESCRIPTOR attribute found!");
1688         
1689 2122         service_desc = (globus_service_descriptor_t *) 
1690         globus_extension_reference(ext);
1691         
1692 2122         globus_assert_string(
1693             service_desc, "No SERVICE DESCRIPTOR attribute found!");
1694         
1695 2122         globus_mutex_lock(&service_desc->mutex);
1696 2122         if(service_desc->handlers)
1697         {
1698 0             globus_handler_chain_register_invoke(
1699                 service_desc->handlers,
1700                 GLOBUS_HANDLER_TYPE_REQUEST,
1701                 callback_handle->message,
1702                 globus_l_service_session_result_callback,
1703                 callback_handle);
1704 0             globus_mutex_unlock(&service_desc->mutex);
1705 0             service_desc = NULL;
1706 0             globus_extension_release(ext);
1707 0             break;
1708         }
1709 2122         globus_mutex_unlock(&service_desc->mutex);
1710 2122         service_desc = NULL;
1711 2122         globus_extension_release(ext);
1712
1713     case GLOBUS_L_SERVICE_ENGINE_REQUEST_DESTROY_HANDLERS:
1714
1715 2122 callback_handle->state = 
1716     GLOBUS_L_SERVICE_ENGINE_REQUEST_DESTROY_SERVICE_HANDLERS;
1717
1718 2122 if(callback_handle->result != GLOBUS_SUCCESS)
1719 {
1720 0     result = callback_handle->result;
1721 0     goto error_send_fault;
1722 }
1723
1724 2122         globus_mutex_lock(&callback_handle->engine->mutex);
1725 2122         if(callback_handle->engine->handlers)
1726         {
1727 2122             globus_handler_chain_register_invoke(
1728                 callback_handle->engine->handlers,
1729 GLOBUS_HANDLER_TYPE_REQUEST_DESTROY,
1730                 callback_handle->message,
1731                 globus_l_service_session_result_callback,
1732                 callback_handle);
1733 2122     globus_mutex_unlock(&callback_handle->engine->mutex);
1734 2122     break;
1735         }
1736 0         globus_mutex_unlock(&callback_handle->engine->mutex);
1737
1738     case GLOBUS_L_SERVICE_ENGINE_REQUEST_DESTROY_SERVICE_HANDLERS:
1739
1740 2122         callback_handle->state = 
1741         GLOBUS_L_SERVICE_ENGINE_RESPONSE_INIT_SERVICE_HANDLERS;
1742
1743 2122         if(callback_handle->result != GLOBUS_SUCCESS)
1744         {
1745 0             result = callback_handle->result;
1746 0             goto error_send_fault;
1747 }
1748
1749 2122 ext =
1750         (globus_extension_handle_t)
1751         globus_soap_message_handle_get_attr(
1752             callback_handle->message,
1753             GLOBUS_I_SERVICE_DESCRIPTOR_KEY);
1754 2122         globus_assert_string(
1755             ext, "No SERVICE DESCRIPTOR attribute found!");
1756                 
1757 2122         service_desc = (globus_service_descriptor_t *) 
1758         globus_extension_reference(ext);
1759         
1760 2122         globus_assert_string(
1761             service_desc, "No SERVICE DESCRIPTOR attribute found!");
1762         
1763 2122         globus_mutex_lock(&service_desc->mutex);
1764 2122         if(service_desc->handlers)
1765         {
1766 0     globus_handler_chain_register_invoke(
1767     service_desc->handlers,
1768     GLOBUS_HANDLER_TYPE_REQUEST_DESTROY,
1769     callback_handle->message,
1770     globus_l_service_session_result_callback,
1771     callback_handle);
1772         
1773 0     globus_mutex_unlock(&service_desc->mutex);
1774 0     service_desc = NULL;
1775 0     globus_extension_release(ext);
1776 0     break;
1777 }
1778 2122 globus_mutex_unlock(&service_desc->mutex);
1779 2122 service_desc = NULL;
1780 2122 globus_extension_release(ext); 
1781
1782     case GLOBUS_L_SERVICE_ENGINE_RESPONSE_INIT_SERVICE_HANDLERS:
1783
1784 2122 if(callback_handle->result != GLOBUS_SUCCESS)
1785 {
1786 0     result = callback_handle->result;
1787 0     goto callback_exit;
1788 }
1789
1790 2122 callback_handle->state =
1791     GLOBUS_L_SERVICE_ENGINE_RESPONSE_INIT_HANDLERS;
1792
1793 2122         ext =
1794         (globus_extension_handle_t)
1795         globus_soap_message_handle_get_attr(
1796             callback_handle->message,
1797             GLOBUS_I_SERVICE_DESCRIPTOR_KEY);
1798 2122         globus_assert_string(
1799             ext, "No SERVICE DESCRIPTOR attribute found!");
1800
1801 2122         service_desc = 
1802         (globus_service_descriptor_t *) 
1803         globus_extension_reference(ext);
1804         
1805 2122         globus_assert_string(
1806             service_desc, "No SERVICE DESCRIPTOR attribute found!");
1807
1808 2122         globus_mutex_unlock(&service_desc->mutex);
1809 2122         if(service_desc->handlers)
1810         {
1811 0             globus_handler_chain_register_invoke(
1812                 service_desc->handlers,
1813                 GLOBUS_HANDLER_TYPE_RESPONSE_INIT,
1814                 callback_handle->message,
1815                 globus_l_service_session_result_callback,
1816                 callback_handle);
1817 0             globus_mutex_unlock(&service_desc->mutex);
1818 0             service_desc = NULL;
1819 0             globus_extension_release(ext);
1820 0             break;
1821         }
1822 2122         globus_mutex_unlock(&service_desc->mutex);
1823
1824 2122         service_desc = NULL;
1825 2122         globus_extension_release(ext);
1826
1827     case GLOBUS_L_SERVICE_ENGINE_RESPONSE_INIT_HANDLERS:
1828
1829 2122 if(callback_handle->result != GLOBUS_SUCCESS)
1830 {
1831 0     result = callback_handle->result;
1832 0     goto callback_exit;
1833 }
1834
1835 2122 callback_handle->state =
1836     GLOBUS_L_SERVICE_ENGINE_REQUEST_INVOKE_OPERATION;
1837
1838 2122         globus_mutex_lock(&callback_handle->engine->mutex);
1839 2122         if(callback_handle->engine->handlers)
1840         {
1841 2122             globus_handler_chain_register_invoke(
1842                 callback_handle->engine->handlers,
1843                 GLOBUS_HANDLER_TYPE_RESPONSE_INIT,
1844                 callback_handle->message,
1845                 globus_l_service_session_result_callback,
1846                 callback_handle);
1847 2122             globus_mutex_unlock(&callback_handle->engine->mutex);
1848 2122             break;
1849         }
1850 0         globus_mutex_unlock(&callback_handle->engine->mutex);
1851
1852
1853     case GLOBUS_L_SERVICE_ENGINE_REQUEST_INVOKE_OPERATION:
1854         
1855 2122         if(callback_handle->result != GLOBUS_SUCCESS)
1856         {
1857 0             result = callback_handle->result;
1858 0             goto error_send_fault;
1859         }
1860
1861 2122         callback_handle->state = 
1862         GLOBUS_L_SERVICE_ENGINE_RESPONSE_INVOKE_SERVICE_HANDLERS;
1863
1864 2122         operation_name = globus_soap_message_handle_get_attr(
1865             callback_handle->message,
1866             GLOBUS_I_SERVICE_OPERATION_QNAME_KEY);
1867 2122         globus_assert(operation_name);
1868
1869 2122         ext = 
1870         (globus_extension_handle_t)
1871         globus_soap_message_handle_get_attr(
1872             callback_handle->message,
1873             GLOBUS_I_SERVICE_DESCRIPTOR_KEY);
1874 2122         globus_assert_string(
1875             ext, "No SERVICE DESCRIPTOR attribute found!");
1876
1877 2122         service_desc = (globus_service_descriptor_t *) 
1878         globus_extension_reference(ext);
1879
1880 2122         globus_assert_string(
1881             service_desc, "No SERVICE DESCRIPTOR attribute found!");
1882
1883         /* we use qn to map to operation deserialize function */
1884 2122         globus_mutex_lock(&service_desc->mutex);
1885 2122         if(service_desc->op_mapper)
1886         {
1887 2122             op_desc = (globus_service_operation_descriptor_t *)
1888             globus_hashtable_lookup(
1889                 &service_desc->op_mapper, 
1890                 (void *)operation_name);
1891         }
1892
1893 2122         if(!op_desc)
1894         {
1895 0             result = GlobusServiceEngineErrorOperationLookupFailed(
1896                 service_desc->name, operation_name);
1897 0             globus_mutex_unlock(&service_desc->mutex);
1898 0             service_desc = NULL;
1899 0             globus_extension_release(ext);
1900 0             goto error_send_fault;
1901         }
1902
1903 2122         result = op_desc->invoke(
1904             callback_handle->engine,
1905             callback_handle->message,
1906             &callback_handle->response,
1907             globus_l_service_session_result_callback,
1908             callback_handle);
1909 2122         if(result != GLOBUS_SUCCESS)
1910         {
1911 0             result = GlobusServiceEngineErrorOpInvokeFailed(
1912                 result, 
1913                 operation_name);
1914 0             globus_mutex_unlock(&service_desc->mutex);
1915 0             goto error_send_fault;
1916         }
1917
1918 2122         if(callback_handle->response == GLOBUS_SERVICE_NO_RESPONSE)
1919         {
1920 0             callback_handle->state = GLOBUS_L_SERVICE_ENGINE_RESPONSE_SEND;
1921         }
1922
1923 2122         globus_mutex_unlock(&service_desc->mutex);
1924 2122         service_desc = NULL;
1925 2122         globus_extension_release(ext);
1926
1927 2122         break;
1928
1929     case GLOBUS_L_SERVICE_ENGINE_RESPONSE_INVOKE_SERVICE_HANDLERS:
1930      
1931 2122         if(callback_handle->result != GLOBUS_SUCCESS)
1932         {
1933 0             result = callback_handle->result;
1934 0             goto callback_exit;
1935         }
1936         
1937 2122         callback_handle->state = 
1938         GLOBUS_L_SERVICE_ENGINE_RESPONSE_INVOKE_HANDLERS;
1939         
1940 2122         result = globus_soap_message_set_write_position_to_marker(
1941             callback_handle->message, 
1942             GLOBUS_SOAP_MESSAGE_MARKER_HEADER_CONTENT);
1943 2122         if(result != GLOBUS_SUCCESS)
1944         {
1945 0             goto callback_exit;
1946         }
1947
1948 2122         ext =
1949         (globus_extension_handle_t)
1950         globus_soap_message_handle_get_attr(
1951             callback_handle->message,
1952             GLOBUS_I_SERVICE_DESCRIPTOR_KEY);
1953 2122         globus_assert_string(
1954             ext, "No SERVICE DESCRIPTOR attribute found!");
1955
1956 2122         service_desc = 
1957         (globus_service_descriptor_t *) 
1958         globus_extension_reference(ext);
1959         
1960 2122         globus_assert_string(
1961             service_desc, "No SERVICE DESCRIPTOR attribute found!");
1962
1963 2122         globus_mutex_unlock(&service_desc->mutex);
1964 2122         if(service_desc->handlers)
1965         {
1966 0             globus_handler_chain_register_invoke(
1967                 service_desc->handlers,
1968                 GLOBUS_HANDLER_TYPE_RESPONSE,
1969                 callback_handle->message,
1970                 globus_l_service_session_result_callback,
1971                 callback_handle);
1972 0             globus_mutex_unlock(&service_desc->mutex);
1973 0             service_desc = NULL;
1974 0             globus_extension_release(ext);
1975 0             break;
1976         }
1977 2122         globus_mutex_unlock(&service_desc->mutex);
1978
1979 2122         service_desc = NULL;
1980 2122         globus_extension_release(ext);
1981
1982     case GLOBUS_L_SERVICE_ENGINE_RESPONSE_INVOKE_HANDLERS:
1983         
1984 2124         callback_handle->state =
1985         GLOBUS_L_SERVICE_ENGINE_RESPONSE_DESTROY_SERVICE_HANDLERS;
1986             
1987 2124         if(callback_handle->result != GLOBUS_SUCCESS)
1988         {
1989 0             result = callback_handle->result;
1990 0             goto callback_exit;
1991         }
1992
1993 2124         globus_mutex_lock(&callback_handle->engine->mutex);
1994 2124         if(callback_handle->engine->handlers)
1995         {
1996 2124             globus_handler_chain_register_invoke(
1997                 callback_handle->engine->handlers,
1998                 GLOBUS_HANDLER_TYPE_RESPONSE,
1999                 callback_handle->message,
2000                 globus_l_service_session_result_callback,
2001                 callback_handle);
2002 2124             globus_mutex_unlock(&callback_handle->engine->mutex);
2003 2124             break;
2004         }
2005 0         globus_mutex_unlock(&callback_handle->engine->mutex);
2006         
2007     case GLOBUS_L_SERVICE_ENGINE_RESPONSE_DESTROY_SERVICE_HANDLERS:
2008
2009 2124 if(callback_handle->result != GLOBUS_SUCCESS)
2010 {
2011 0     result = callback_handle->result;
2012 0     goto callback_exit;
2013 }
2014
2015 2124 callback_handle->state =
2016     GLOBUS_L_SERVICE_ENGINE_RESPONSE_DESTROY_HANDLERS;
2017
2018 2124         if(callback_handle->response == GLOBUS_SERVICE_NO_RESPONSE)
2019         {
2020 0             result = globus_soap_message_setup_writer(
2021                 callback_handle->message);
2022 0             if(result != GLOBUS_SUCCESS)
2023             {
2024 0                 goto callback_exit;
2025             }
2026         }
2027
2028 2124         ext =
2029         (globus_extension_handle_t)
2030         globus_soap_message_handle_get_attr(
2031             callback_handle->message,
2032             GLOBUS_I_SERVICE_DESCRIPTOR_KEY);
2033
2034         /* If the user passes in an invalid service name, the extension
2035          * handle will be NULL. We'll just skip service-specific handler
2036          * invocation in this case.
2037          */
2038 2124         if (ext != NULL)
2039         {
2040 2123             service_desc = 
2041             (globus_service_descriptor_t *) 
2042             globus_extension_reference(ext);
2043             
2044 2123             globus_assert_string(
2045                 service_desc, "No SERVICE DESCRIPTOR attribute found!");
2046
2047 2123             globus_mutex_unlock(&service_desc->mutex);
2048 2123             if(service_desc->handlers)
2049             {
2050 0                 globus_handler_chain_register_invoke(
2051                     service_desc->handlers,
2052                     GLOBUS_HANDLER_TYPE_RESPONSE_DESTROY,
2053                     callback_handle->message,
2054                     globus_l_service_session_result_callback,
2055                     callback_handle);
2056 0                 globus_mutex_unlock(&service_desc->mutex);
2057 0                 service_desc = NULL;
2058 0                 globus_extension_release(ext);
2059 0                 break;
2060             }
2061 2123             globus_mutex_unlock(&service_desc->mutex);
2062
2063 2123             service_desc = NULL;
2064 2123             globus_extension_release(ext);
2065         }
2066
2067     case GLOBUS_L_SERVICE_ENGINE_RESPONSE_DESTROY_HANDLERS:
2068
2069 2124 if(callback_handle->result != GLOBUS_SUCCESS)
2070 {
2071 0     result = callback_handle->result;
2072 0     goto callback_exit;
2073 }
2074
2075 2124 callback_handle->state =
2076     GLOBUS_L_SERVICE_ENGINE_RESPONSE_SEND;
2077
2078 2124         globus_mutex_lock(&callback_handle->engine->mutex);
2079 2124         if(callback_handle->engine->handlers)
2080         {
2081 2124             globus_handler_chain_register_invoke(
2082                 callback_handle->engine->handlers,
2083                 GLOBUS_HANDLER_TYPE_RESPONSE_DESTROY,
2084                 callback_handle->message,
2085                 globus_l_service_session_result_callback,
2086                 callback_handle);
2087 2124             globus_mutex_unlock(&callback_handle->engine->mutex);
2088 2124             break;
2089         }
2090 0         globus_mutex_unlock(&callback_handle->engine->mutex);
2091
2092     case GLOBUS_L_SERVICE_ENGINE_RESPONSE_SEND:
2093
2094 2124         callback_handle->state = 
2095         GLOBUS_L_SERVICE_ENGINE_RESPONSE_CLOSE;
2096
2097         /* If there's no response, we setup the writer to clear the
2098          * buffer state so that we don't send the request back as
2099          * the unwanted response
2100          */
2101 2124         if(callback_handle->response == GLOBUS_SERVICE_NO_RESPONSE)
2102         {
2103 0             result = globus_soap_message_setup_writer(
2104                 callback_handle->message);
2105 0             if(result != GLOBUS_SUCCESS)
2106             {
2107 0                 goto callback_exit;
2108             }
2109         }
2110 2124         result = globus_soap_message_register_write_response(
2111             callback_handle->message,
2112             globus_l_service_session_result_callback,
2113             callback_handle);
2114 2124         if(result != GLOBUS_SUCCESS)
2115         {
2116 0             goto callback_exit;
2117         }
2118
2119 3189         break;
2120
2121     case GLOBUS_L_SERVICE_ENGINE_RESPONSE_CLOSE:
2122 3189         connection = globus_soap_message_handle_get_attr(
2123             callback_handle->message,
2124             GLOBUS_SOAP_MESSAGE_CONNECTION_KEY);
2125
2126 3189         if (callback_handle->result == GLOBUS_SUCCESS
2127             && ((!connection) || (strcmp(connection, "close"))))
2128         {
2129 2123             callback_handle->state =
2130                 GLOBUS_L_SERVICE_ENGINE_REQUEST_READ_ANOTHER_MESSAGE;
2131
2132 2123             result = globus_soap_message_handle_reset(
2133                 callback_handle->message);
2134
2135 2123             if (result != GLOBUS_SUCCESS)
2136             {
2137 0                 goto close_it;
2138             }
2139             /* Register a new metadata read */
2140 2123             result = globus_soap_message_get_transport_handle(
2141                 callback_handle->message,
2142                 &xio_handle);
2143
2144 2123             if (result != GLOBUS_SUCCESS)
2145             {
2146 0                 goto close_it;
2147             }
2148 2123             result = globus_xio_handle_cntl(
2149                     xio_handle,
2150                     globus_i_soap_message_buffer_driver,
2151                     GLOBUS_XIO_BUFFER_CLEAR);
2152 2123             if (result != GLOBUS_SUCCESS)
2153             {
2154 0                 goto close_it;
2155             }
2156 2123             result = globus_xio_handle_cntl(
2157                     xio_handle,
2158                     globus_i_soap_message_buffer_driver,
2159                     GLOBUS_XIO_BUFFER_DISABLE_BUFFERING);
2160 2123             if (result != GLOBUS_SUCCESS)
2161             {
2162 0                 goto close_it;
2163             }
2164
2165 2123             result = globus_xio_register_read(
2166                     xio_handle,
2167                     buffer,
2168                     0,
2169                     0,
2170                     NULL,
2171                     globus_l_service_engine_request_ready_callback,
2172                     callback_handle);
2173 2123             if (result == GLOBUS_SUCCESS)
2174             {
2175 2123                 break;
2176             }
2177         }
2178 close_it:
2179 1066         callback_handle->state = 
2180             GLOBUS_L_SERVICE_ENGINE_RESPONSE_DONE;
2181         
2182 1066         if(callback_handle->result != GLOBUS_SUCCESS)
2183         {
2184 0             result = callback_handle->result;
2185 0             goto exit;
2186         }
2187
2188 1066         result = globus_soap_message_register_close(
2189             callback_handle->message,
2190             globus_l_service_session_result_callback,
2191             callback_handle);
2192
2193 1066         if(result != GLOBUS_SUCCESS)
2194         {
2195 0             goto callback_exit;
2196         }
2197 1066         break;
2198
2199     case GLOBUS_L_SERVICE_ENGINE_RESPONSE_DONE:
2200
2201 1066         if(callback_handle->result != GLOBUS_SUCCESS)
2202         {
2203 0             result = callback_handle->result;
2204 0             goto exit;
2205         }
2206
2207 1         goto callback_exit;
2208     }
2209
2210 1     goto exit;
2211
2212  error_send_fault:
2213
2214 1     if(service_desc)
2215     {
2216 0         service_desc = NULL;
2217 0         globus_extension_release(ext);
2218     }
2219
2220 1     if(result != GLOBUS_SUCCESS)
2221     {
2222 1         char *                          error_str;
2223
2224 1         error_str = globus_error_print_chain(
2225             globus_error_peek(result));
2226 1         GlobusServiceEngineDebugPrintf(
2227             GLOBUS_L_SERVICE_ENGINE_DEBUG_ERROR,
2228             ("SOAP message processing failed:\n%s\n",
2229              error_str));
2230 1         globus_free(error_str);
2231
2232 1         callback_handle->result = result;
2233         /* need to send client FAULT as response */
2234 1         result = globus_callback_register_oneshot(
2235             NULL,
2236             &globus_i_reltime_zero,
2237             globus_l_service_engine_send_client_fault,
2238             callback_handle);
2239 1         if(result != GLOBUS_SUCCESS)
2240         {
2241 0             result = GlobusServiceEngineErrorFailedRequestProcess(
2242                 result, 
2243                 "Failed to register callback "
2244                 "to send client fault response");
2245         }
2246     }
2247
2248 0     goto exit;
2249
2250  callback_exit:
2251
2252 1066     if(result != GLOBUS_SUCCESS)
2253     {
2254 0         ext =
2255         (globus_extension_handle_t)
2256         globus_soap_message_handle_get_attr(
2257             callback_handle->message,
2258             GLOBUS_I_SERVICE_DESCRIPTOR_KEY);
2259 0         if(ext)
2260         {
2261 0             service_desc = 
2262             (globus_service_descriptor_t *) 
2263             globus_extension_reference(ext);
2264
2265 0             globus_assert_string(service_desc,
2266                                  "No SERVICE DESCRIPTOR attribute found!");
2267
2268 0             globus_mutex_lock(&service_desc->mutex);
2269 0             result = GlobusServiceEngineErrorSessionFailed(
2270                 result, service_desc->name);
2271 0             globus_mutex_unlock(&service_desc->mutex);
2272
2273 0             service_desc = NULL;
2274 0             globus_extension_release(ext);
2275         }
2276     }
2277
2278 1066     globus_mutex_lock(&callback_handle->engine->mutex);
2279 1066     callback_handle->process_callback(
2280         result ? result : callback_handle->callback_result,
2281         callback_handle->engine,
2282         callback_handle->message,
2283         callback_handle->process_args);
2284 1066     globus_mutex_unlock(&callback_handle->engine->mutex);
2285     
2286 1066     globus_l_service_session_callback_handle_destroy(callback_handle);
2287
2288  exit:
2289 38174     GlobusServiceEngineDebugExit();
2290 }
2291
2292 globus_result_t
2293 globus_service_session_begin_response(
2294     globus_soap_message_handle_t        message)
2295 2124 {
2296 2124     globus_result_t                     result = GLOBUS_SUCCESS;
2297 2124     GlobusFuncName(globus_service_session_begin_response);
2298 2124     GlobusServiceEngineDebugEnter();
2299
2300 2124     result = globus_soap_message_setup_writer(message);
2301 2124     if(result != GLOBUS_SUCCESS)
2302     {
2303 0         result = GlobusServiceEngineErrorTransportFailed(
2304             result, "Failed to setup message writer");
2305 0         goto exit;
2306     }
2307
2308 2124     result = globus_soap_message_serialize_envelope(message);
2309 2124     if(result != GLOBUS_SUCCESS)
2310     {
2311 0         result = GlobusServiceEngineErrorFailedResponse(result);
2312 0         goto exit;
2313     }
2314
2315 2124     result = globus_soap_message_serialize_header(message);
2316 2124     if(result != GLOBUS_SUCCESS)
2317     {
2318 0         result = GlobusServiceEngineErrorFailedResponse(result);
2319 0         goto exit;
2320     }
2321
2322 2124     result = globus_soap_message_serialize_header_begin_close(message);
2323 2124     if(result != GLOBUS_SUCCESS)
2324     {
2325 0         result = GlobusServiceEngineErrorFailedResponse(result);
2326 0         goto exit;
2327     }
2328
2329 2124     result = globus_soap_message_set_marker(
2330         message,
2331         GLOBUS_SOAP_MESSAGE_MARKER_HEADER_CONTENT);
2332 2124     if(result != GLOBUS_SUCCESS)
2333     {
2334 0         result = GlobusServiceEngineErrorFailedResponse(result);
2335 0         goto exit;
2336     }
2337
2338 2124     result = globus_soap_message_serialize_header_end(message);
2339 2124     if(result != GLOBUS_SUCCESS)
2340     {
2341 0         result = GlobusServiceEngineErrorFailedResponse(result);
2342 0         goto exit;
2343     }
2344
2345 2124     result = globus_soap_message_serialize_body(message);
2346 2124     if(result != GLOBUS_SUCCESS)
2347     {
2348 0         result = GlobusServiceEngineErrorFailedResponse(result);
2349 0         goto exit;
2350     }
2351
2352 2124     result = globus_soap_message_serialize_body_begin_close(
2353 message);
2354 2124     if(result != GLOBUS_SUCCESS)
2355     {
2356 0 result = GlobusServiceEngineErrorFailedResponse(result);
2357 goto exit;
2358     }
2359     
2360  exit:
2361
2362 2124     GlobusServiceEngineDebugExit();
2363 2124     return result;
2364 }
2365
2366 globus_result_t
2367 globus_service_session_end_response(
2368     globus_soap_message_handle_t        message)
2369 2124 {
2370 2124     globus_result_t                     result = GLOBUS_SUCCESS;
2371 2124     GlobusFuncName(globus_service_session_end_response);
2372 2124     GlobusServiceEngineDebugEnter();
2373     
2374 2124     result = globus_soap_message_serialize_body_end(message);
2375 2124     if(result != GLOBUS_SUCCESS)
2376     {
2377 0         result = GlobusServiceEngineErrorFailedResponse(result);
2378 0         goto exit;
2379     }
2380
2381 2124     result = globus_soap_message_serialize_envelope_end(message);
2382 2124     if(result != GLOBUS_SUCCESS)
2383     {
2384 0         result = GlobusServiceEngineErrorFailedResponse(result);
2385         goto exit;
2386     }
2387     
2388  exit:
2389
2390 2124     GlobusServiceEngineDebugExit();
2391 2124     return result;
2392 }
2393
2394 globus_result_t
2395 globus_service_session_serialize_fault_response(
2396     globus_soap_message_handle_t        message,
2397     globus_soap_message_fault_t         fault)
2398 69 {
2399 69     globus_result_t                     result = GLOBUS_SUCCESS;
2400 69     GlobusFuncName(globus_service_serialize_fault_response);
2401 69     GlobusServiceEngineDebugEnter();
2402
2403 69     result = globus_soap_message_serialize_fault(message, fault);
2404 69     if(result != GLOBUS_SUCCESS)
2405     {
2406 0         result = GlobusServiceEngineErrorSendingFault(result);
2407 0         goto exit;
2408     }
2409
2410 69     result = globus_service_session_end_response(message);
2411 69     if(result != GLOBUS_SUCCESS)
2412     {
2413 0         result = GlobusServiceEngineErrorSendingFault(result);
2414         goto exit;
2415     }
2416
2417  exit:
2418
2419 69     GlobusServiceEngineDebugExit();
2420 69     return result;
2421 }
2422
2423 static
2424 void
2425 globus_l_service_engine_send_client_fault(
2426     void *                              args)
2427 2 {
2428 2     globus_result_t                      result = GLOBUS_SUCCESS;
2429 2     globus_xio_handle_t                  xio_handle;
2430 2     globus_l_session_callback_handle_t * callback_handle;
2431 2     char *                               error_string;
2432 2     struct globus_soap_message_fault_s   fault;
2433 2     int                                  status_code = 200;
2434 2     GlobusFuncName(globus_l_service_engine_send_client_fault);
2435 2     GlobusServiceEngineDebugEnter();
2436
2437 2     callback_handle = (globus_l_session_callback_handle_t *) args;
2438 2     callback_handle->faulting = GLOBUS_TRUE;
2439
2440 2     fault.faultcode = "Client";
2441
2442 2     error_string = globus_error_print_friendly(
2443         globus_error_peek(
2444             callback_handle->result));
2445 2     callback_handle->callback_result = callback_handle->result;
2446 2     callback_handle->result = GLOBUS_SUCCESS;
2447 2     fault.faultstring = error_string;
2448 2     fault.faultactor = NULL;
2449 2     fault.detail = NULL;
2450  
2451 2     result = globus_service_session_begin_response(
2452                 callback_handle->message);
2453 2     if(result != GLOBUS_SUCCESS)
2454     {
2455 0         goto error_exit;
2456     }
2457
2458 2     result = globus_service_session_serialize_fault_response(
2459         callback_handle->message, &fault);
2460 2     if(result != GLOBUS_SUCCESS)
2461     {
2462 0         goto error_exit;
2463     }
2464
2465 2     if(GlobusServiceEngineErrorCheckMethodNotAllowed(
2466            callback_handle->result))
2467     {
2468 0         status_code = 405;
2469     }
2470 2     else if(GlobusServiceEngineErrorCheckUnsupportedMediaType(
2471                 callback_handle->result))
2472     {
2473 0         status_code = 415;
2474     }
2475     else
2476     {
2477 2         status_code = 400;
2478     }
2479
2480 2     result = globus_soap_message_get_transport_handle(
2481         callback_handle->message,
2482         &xio_handle);
2483 2     if(result != GLOBUS_SUCCESS)
2484     {
2485 0         goto error_exit;
2486     }
2487
2488 2     result = globus_xio_handle_cntl(
2489         xio_handle,
2490         globus_i_soap_message_http_driver,
2491         GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_STATUS_CODE,
2492         status_code);
2493 2     if(result != GLOBUS_SUCCESS)
2494     {
2495 0         goto error_exit;
2496     }
2497
2498 2     result = globus_soap_message_set_write_position_to_marker(
2499         callback_handle->message, 
2500         GLOBUS_SOAP_MESSAGE_MARKER_HEADER_CONTENT);
2501 2     if(result != GLOBUS_SUCCESS)
2502     {
2503 0         goto error_exit;
2504     }
2505
2506 2     result = globus_soap_message_handle_set_attr(
2507         callback_handle->message, 
2508         WSADDR_REQUEST_ENDPOINT_KEY,
2509         globus_soap_message_attr_copy_string,
2510         globus_libc_free,
2511         WSADDRESSING_ANON_NS);
2512 2     if(result != GLOBUS_SUCCESS)
2513     {
2514 0         goto error_exit;
2515     }
2516
2517 2     result = globus_soap_message_handle_set_attr(
2518         callback_handle->message,
2519         WSADDR_ACTION_RESPONSE_KEY,
2520         globus_soap_message_attr_copy_string,
2521         globus_libc_free,
2522         WSADDRESSING_FAULT_NS);
2523 2     if(result != GLOBUS_SUCCESS)
2524     {
2525 0         goto error_exit;
2526     }
2527
2528 2     callback_handle->state = GLOBUS_L_SERVICE_ENGINE_RESPONSE_INVOKE_HANDLERS;
2529
2530 2     result = globus_callback_register_oneshot(
2531         NULL,
2532         &globus_i_reltime_zero,
2533         globus_l_service_session_callback,
2534         callback_handle);
2535 2     if(result != GLOBUS_SUCCESS)
2536     {
2537 0         goto error_exit;
2538     }
2539     
2540 0     goto exit;
2541
2542  error_exit:
2543
2544 0     globus_mutex_lock(&callback_handle->engine->mutex);
2545 0     callback_handle->callback(result,
2546                               callback_handle->engine,
2547                               callback_handle->message,
2548                               callback_handle->args);
2549 0     globus_mutex_unlock(&callback_handle->engine->mutex);
2550 0     globus_l_service_session_callback_handle_destroy(callback_handle);
2551     
2552  exit:
2553
2554 2     GlobusServiceEngineDebugExit();
2555 }
2556
2557 globus_result_t
2558 globus_service_engine_register_process(
2559     globus_service_engine_t                engine,
2560     globus_soap_message_handle_t           message,
2561     globus_result_t                        fault_result,
2562     globus_service_session_callback_func_t callback,
2563     void *                                 user_args)
2564 1066 {
2565 1066     globus_result_t                     result = GLOBUS_SUCCESS;
2566 1066     globus_l_session_callback_handle_t * callback_handle;
2567
2568 1066     if(!message)
2569     {
2570 0         callback(fault_result, engine, NULL, user_args);
2571 0         goto exit;
2572     }
2573
2574 1066     callback_handle = globus_soap_message_handle_get_attr(
2575         message,
2576         GLOBUS_I_SESSION_HANDLE_KEY);
2577 1066     globus_assert_string(
2578         callback_handle, "Session handle lookup failed for callback handle");
2579
2580 1066     callback_handle->process_callback = callback;
2581 1066     callback_handle->process_args = user_args;
2582
2583 1066     if(fault_result != GLOBUS_SUCCESS)
2584     {
2585 1         char *                          error_str;
2586
2587 1         error_str = globus_error_print_chain(
2588             globus_error_peek(fault_result));
2589 1         GlobusServiceEngineDebugPrintf(
2590             GLOBUS_L_SERVICE_ENGINE_DEBUG_ERROR,
2591             ("Error occurred during session accept:\n%s\n",
2592              error_str));
2593 1         globus_free(error_str);
2594
2595 1         callback_handle->result = fault_result;
2596
2597         /* need to send client FAULT as response */
2598 1         result = globus_callback_register_oneshot(
2599             NULL,
2600             &globus_i_reltime_zero,
2601             globus_l_service_engine_send_client_fault,
2602             callback_handle);
2603 1         if(result != GLOBUS_SUCCESS)
2604         {
2605 0             result = GlobusServiceEngineErrorFailedRequestProcess(
2606                 result, 
2607                 "Failed to register callback "
2608                 "to send client fault response");
2609 0             goto exit;
2610         }
2611         
2612 1065         goto exit;
2613     }
2614     else
2615     {
2616 1065         callback_handle->state = 
2617         GLOBUS_L_SERVICE_ENGINE_REQUEST_READ_MESSAGE;
2618         
2619 1065         result = globus_callback_register_oneshot(
2620             NULL,
2621             &globus_i_reltime_zero,
2622             globus_l_service_session_callback,
2623             callback_handle);
2624 1065         if(result != GLOBUS_SUCCESS)
2625         {
2626 0             result = GlobusServiceEngineErrorFailedRequestProcess(
2627                 result, "Failed to register callback to invoke operation");
2628             goto exit;
2629         }
2630     }
2631     
2632  exit:
2633     
2634 1066     GlobusServiceEngineDebugExit();
2635 1066     return result;
2636 }
2637
2638 globus_result_t
2639 globus_service_engine_set_handlers(
2640     globus_service_engine_t             engine,
2641     globus_handler_chain_t              chain)
2642 0 {
2643 0     GlobusFuncName(globus_service_engine_set_handlers);
2644 0     GlobusServiceEngineDebugEnter();
2645
2646 0     if(engine->handlers)
2647     {
2648 0         globus_handler_chain_destroy(engine->handlers);
2649     }
2650
2651 0     engine->handlers = chain;
2652
2653 0     GlobusServiceEngineDebugExit();
2654 0     return GLOBUS_SUCCESS;
2655 }
2656
2657 static
2658 void 
2659 globus_l_service_engine_session_complete_callback(
2660     globus_result_t                     result,
2661     globus_service_engine_t             engine,
2662     globus_soap_message_handle_t        session,
2663     void *                              args)
2664 0 {
2665 0     globus_l_service_engine_callback_handle_t * callback_handle;
2666 0     GlobusFuncName(globus_l_service_engine_session_complete_callback);
2667 0     GlobusServiceEngineDebugEnter();
2668
2669 0     callback_handle = (globus_l_service_engine_callback_handle_t *) args;
2670
2671 0     if(result != GLOBUS_SUCCESS)
2672     {
2673 0         char *                          endpoint = NULL; 
2674 0         char *                          action = NULL;
2675
2676 0         if(session)
2677         {
2678 0             endpoint = globus_soap_message_handle_get_attr(
2679                 session,
2680                 GLOBUS_SOAP_MESSAGE_SERVICE_ENDPOINT_KEY);
2681             
2682 0             action = globus_soap_message_handle_get_attr(
2683                 session,
2684                 GLOBUS_SOAP_MESSAGE_SOAP_ACTION_KEY);
2685         }
2686
2687 0         GlobusServiceEngineDebugPrintError(result, endpoint, action);
2688     }
2689
2690 0     globus_mutex_lock(&engine->mutex);
2691 0     engine->session_count--;
2692 0     if(engine->stop_sessions && engine->session_count <= 0)
2693     {
2694 0         globus_mutex_unlock(&engine->mutex);
2695
2696 0         callback_handle->callback(
2697             GLOBUS_SUCCESS, engine, callback_handle->args);
2698
2699 0         globus_free(callback_handle);
2700     }
2701     else
2702     {
2703 0         globus_mutex_unlock(&engine->mutex);
2704     }
2705
2706 0     globus_soap_message_handle_destroy(session);
2707
2708 0     GlobusServiceEngineDebugExit();
2709 }
2710
2711 static
2712 void
2713 globus_l_service_engine_session_started_callback(
2714     globus_result_t                     result,
2715     globus_service_engine_t             engine,
2716     globus_soap_message_handle_t        session,
2717     void *                              args)
2718 2 {
2719 2     globus_result_t                     fault_result = GLOBUS_SUCCESS;
2720 2     globus_l_service_engine_callback_handle_t * callback_handle;
2721 2     GlobusFuncName(globus_l_service_engine_session_started_callback);
2722 2     GlobusServiceEngineDebugEnter();
2723
2724 2     callback_handle = (globus_l_service_engine_callback_handle_t *) args;
2725
2726 2     if(result != GLOBUS_SUCCESS)
2727     {
2728 2         result = GlobusServiceEngineErrorSessionStartFailed(result);
2729 2         goto error_exit;
2730     }
2731
2732 0     if(callback_handle->result != GLOBUS_SUCCESS)
2733     {
2734 0         fault_result = callback_handle->result;
2735     }
2736         
2737 0     globus_mutex_lock(&engine->mutex);
2738 0     engine->session_count++;
2739 0     if(!engine->stop_sessions)
2740     {
2741 0         result = globus_service_engine_register_session(
2742             engine,
2743             globus_l_service_engine_session_started_callback,
2744             callback_handle);
2745 0         if(result != GLOBUS_SUCCESS)
2746         {
2747 0             globus_mutex_unlock(&engine->mutex);
2748             /* no more sessions started */
2749 0             goto error_exit;
2750         }
2751     }
2752     
2753 0     globus_mutex_unlock(&engine->mutex);
2754
2755 0     result = globus_service_engine_register_process(
2756         engine,
2757         session,
2758         fault_result,
2759         globus_l_service_engine_session_complete_callback,
2760         args);
2761
2762 0     goto exit;
2763
2764  error_exit:
2765
2766 2     if(result != GLOBUS_SUCCESS)
2767     {
2768 2         char *                          endpoint = NULL; 
2769 2         char *                          action = NULL;
2770
2771 2         if(session)
2772         {
2773 0             endpoint = globus_soap_message_handle_get_attr(
2774                 session,
2775                 GLOBUS_SOAP_MESSAGE_SERVICE_ENDPOINT_KEY);
2776             
2777 0             action = globus_soap_message_handle_get_attr(
2778                 session,
2779                 GLOBUS_SOAP_MESSAGE_SOAP_ACTION_KEY);
2780         }
2781
2782 2         GlobusServiceEngineDebugPrintError(result, endpoint, action);
2783     }
2784
2785 2     if (globus_xio_error_is_canceled(result))
2786     {
2787 2         result = GLOBUS_SUCCESS;
2788     }
2789 2     callback_handle->callback(result,
2790                               engine, 
2791                               callback_handle->args);
2792     
2793 2     if(engine->session_count <= 0)
2794     {
2795 2         free(callback_handle);
2796     }
2797     
2798  exit:
2799
2800 2     GlobusServiceEngineDebugExit();
2801 }
2802
2803
2804 globus_result_t
2805 globus_service_engine_register_start(
2806     globus_service_engine_t               engine,
2807     globus_service_engine_callback_func_t stop_callback,
2808     void *                                args)
2809 2 {
2810 2     globus_l_service_engine_callback_handle_t * callback_handle;
2811 2     globus_result_t                     result = GLOBUS_SUCCESS;
2812 2     GlobusFuncName(globus_service_engine_register_start);
2813 2     GlobusServiceEngineDebugEnter();
2814
2815 2     if(engine->stop_sessions)
2816     {
2817 0         result = GlobusServiceEngineErrorAlreadyStarted();
2818 0         goto exit;
2819     }
2820
2821 2     callback_handle = globus_malloc(
2822         sizeof(globus_l_service_engine_callback_handle_t));
2823 2     if(!callback_handle)
2824     {
2825 0         result = GlobusServiceEngineErrorOutOfMemory;
2826 0         goto exit;
2827     }
2828 2     memset(callback_handle, 0, sizeof(globus_l_service_engine_callback_handle_t));
2829
2830 2     callback_handle->engine = engine;
2831 2     callback_handle->callback = stop_callback;
2832 2     callback_handle->args = args;
2833
2834 2     result = globus_service_engine_register_session(
2835         engine,
2836         globus_l_service_engine_session_started_callback,
2837         callback_handle);
2838 2     if(result != GLOBUS_SUCCESS)
2839     {
2840 0         result = GlobusServiceEngineErrorFailedStart(result);
2841     }
2842
2843  exit:
2844
2845 2     GlobusServiceEngineDebugExit();
2846 2     return result;
2847 }
2848
2849 globus_result_t
2850 globus_service_engine_register_stop(
2851     globus_service_engine_t               engine)
2852 1 {
2853 1     globus_result_t                     result = GLOBUS_SUCCESS;
2854 1     GlobusFuncName(globus_service_engine_register_stop);
2855 1     GlobusServiceEngineDebugEnter();
2856
2857 1     globus_mutex_lock(&engine->mutex);
2858 1     engine->stop_sessions = 1;
2859 1     globus_xio_server_cancel_accept(engine->server);
2860 1     globus_mutex_unlock(&engine->mutex);
2861
2862 1     GlobusServiceEngineDebugExit();
2863 1     return result;