PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/soap - soap.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 2128 2582 82.4 %
Date: 2015-05-17 Functions: 61 65 93.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 5                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2014 The PHP Group                                |
       6             :   +----------------------------------------------------------------------+
       7             :   | This source file is subject to version 3.01 of the PHP license,      |
       8             :   | that is bundled with this package in the file LICENSE, and is        |
       9             :   | available through the world-wide-web at the following url:           |
      10             :   | http://www.php.net/license/3_01.txt                                  |
      11             :   | If you did not receive a copy of the PHP license and are unable to   |
      12             :   | obtain it through the world-wide-web, please send a note to          |
      13             :   | license@php.net so we can mail you a copy immediately.               |
      14             :   +----------------------------------------------------------------------+
      15             :   | Authors: Brad Lafountain <rodif_bl@yahoo.com>                        |
      16             :   |          Shane Caraveo <shane@caraveo.com>                           |
      17             :   |          Dmitry Stogov <dmitry@zend.com>                             |
      18             :   +----------------------------------------------------------------------+
      19             : */
      20             : /* $Id$ */
      21             : 
      22             : #ifdef HAVE_CONFIG_H
      23             : #include "config.h"
      24             : #endif
      25             : #include "php_soap.h"
      26             : #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
      27             : #include "ext/session/php_session.h"
      28             : #endif
      29             : #include "zend_exceptions.h"
      30             : 
      31             : 
      32             : static int le_sdl = 0;
      33             : int le_url = 0;
      34             : static int le_service = 0;
      35             : static int le_typemap = 0;
      36             : 
      37             : typedef struct _soapHeader {
      38             :         sdlFunctionPtr                    function;
      39             :         zval                              function_name;
      40             :         int                               mustUnderstand;
      41             :         int                               num_params;
      42             :         zval                            **parameters;
      43             :         zval                              retval;
      44             :         sdlSoapBindingFunctionHeaderPtr   hdr;
      45             :         struct _soapHeader               *next;
      46             : } soapHeader;
      47             : 
      48             : /* Local functions */
      49             : static void function_to_string(sdlFunctionPtr function, smart_str *buf);
      50             : static void type_to_string(sdlTypePtr type, smart_str *buf, int level);
      51             : 
      52             : static void clear_soap_fault(zval *obj TSRMLS_DC);
      53             : static void set_soap_fault(zval *obj, char *fault_code_ns, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail, char *name TSRMLS_DC);
      54             : static void soap_server_fault(char* code, char* string, char *actor, zval* details, char *name TSRMLS_DC);
      55             : static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeader* hdr TSRMLS_DC);
      56             : 
      57             : static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, int);
      58             : static sdlFunctionPtr get_function(sdlPtr sdl, const char *function_name);
      59             : static sdlFunctionPtr get_doc_function(sdlPtr sdl, xmlNodePtr node);
      60             : 
      61             : static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, char* actor, zval *function_name, int *num_params, zval **parameters[], int *version, soapHeader **headers TSRMLS_DC);
      62             : static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function_name,char *uri,zval *ret, soapHeader *headers, int version TSRMLS_DC);
      63             : static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function, char *function_name, char *uri, zval **arguments, int arg_count, int version, HashTable *soap_headers TSRMLS_DC);
      64             : static xmlNodePtr serialize_parameter(sdlParamPtr param,zval *param_val,int index,char *name, int style, xmlNodePtr parent TSRMLS_DC);
      65             : static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName, int style, xmlNodePtr parent TSRMLS_DC);
      66             : 
      67             : static void delete_service(void *service);
      68             : static void delete_url(void *handle);
      69             : static void delete_hashtable(void *hashtable);
      70             : 
      71             : static void soap_error_handler(int error_num, const char *error_filename, const uint error_lineno, const char *format, va_list args);
      72             : 
      73             : #define SOAP_SERVER_BEGIN_CODE() \
      74             :         zend_bool _old_handler = SOAP_GLOBAL(use_soap_error_handler);\
      75             :         char* _old_error_code = SOAP_GLOBAL(error_code);\
      76             :         zval* _old_error_object = SOAP_GLOBAL(error_object);\
      77             :         int _old_soap_version = SOAP_GLOBAL(soap_version);\
      78             :         SOAP_GLOBAL(use_soap_error_handler) = 1;\
      79             :         SOAP_GLOBAL(error_code) = "Server";\
      80             :         SOAP_GLOBAL(error_object) = this_ptr;
      81             : 
      82             : #define SOAP_SERVER_END_CODE() \
      83             :         SOAP_GLOBAL(use_soap_error_handler) = _old_handler;\
      84             :         SOAP_GLOBAL(error_code) = _old_error_code;\
      85             :         SOAP_GLOBAL(error_object) = _old_error_object;\
      86             :         SOAP_GLOBAL(soap_version) = _old_soap_version;
      87             : 
      88             : #define SOAP_CLIENT_BEGIN_CODE() \
      89             :         zend_bool _old_handler = SOAP_GLOBAL(use_soap_error_handler);\
      90             :         char* _old_error_code = SOAP_GLOBAL(error_code);\
      91             :         zval* _old_error_object = SOAP_GLOBAL(error_object);\
      92             :         int _old_soap_version = SOAP_GLOBAL(soap_version);\
      93             :         zend_bool _old_in_compilation = CG(in_compilation); \
      94             :         zend_bool _old_in_execution = EG(in_execution); \
      95             :         zend_execute_data *_old_current_execute_data = EG(current_execute_data); \
      96             :         void **_old_stack_top = EG(argument_stack)->top; \
      97             :         int _bailout = 0;\
      98             :         SOAP_GLOBAL(use_soap_error_handler) = 1;\
      99             :         SOAP_GLOBAL(error_code) = "Client";\
     100             :         SOAP_GLOBAL(error_object) = this_ptr;\
     101             :         zend_try {
     102             : 
     103             : #define SOAP_CLIENT_END_CODE() \
     104             :         } zend_catch {\
     105             :                 CG(in_compilation) = _old_in_compilation; \
     106             :                 EG(in_execution) = _old_in_execution; \
     107             :                 EG(current_execute_data) = _old_current_execute_data; \
     108             :                 if (EG(exception) == NULL || \
     109             :                     Z_TYPE_P(EG(exception)) != IS_OBJECT || \
     110             :                     !instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {\
     111             :                         _bailout = 1;\
     112             :                 }\
     113             :                 if (_old_stack_top != EG(argument_stack)->top) { \
     114             :                         while (EG(argument_stack)->prev != NULL && \
     115             :                                ((char*)_old_stack_top < (char*)EG(argument_stack) || \
     116             :                                 (char*) _old_stack_top > (char*)EG(argument_stack)->end)) { \
     117             :                                 zend_vm_stack tmp = EG(argument_stack)->prev; \
     118             :                                 efree(EG(argument_stack)); \
     119             :                                 EG(argument_stack) = tmp; \
     120             :                         } \
     121             :                         EG(argument_stack)->top = _old_stack_top; \
     122             :                 } \
     123             :         } zend_end_try();\
     124             :         SOAP_GLOBAL(use_soap_error_handler) = _old_handler;\
     125             :         SOAP_GLOBAL(error_code) = _old_error_code;\
     126             :         SOAP_GLOBAL(error_object) = _old_error_object;\
     127             :         SOAP_GLOBAL(soap_version) = _old_soap_version;\
     128             :         if (_bailout) {\
     129             :                 zend_bailout();\
     130             :         }
     131             : 
     132             : #define FETCH_THIS_SDL(ss) \
     133             :         { \
     134             :                 zval **__tmp; \
     135             :                 if(FIND_SDL_PROPERTY(this_ptr,__tmp) != FAILURE) { \
     136             :                         FETCH_SDL_RES(ss,__tmp); \
     137             :                 } else { \
     138             :                         ss = NULL; \
     139             :                 } \
     140             :         }
     141             : 
     142             : #define FIND_SDL_PROPERTY(ss,tmp) zend_hash_find(Z_OBJPROP_P(ss), "sdl", sizeof("sdl"), (void **)&tmp)
     143             : #define FETCH_SDL_RES(ss,tmp) ss = (sdlPtr) zend_fetch_resource(tmp TSRMLS_CC, -1, "sdl", NULL, 1, le_sdl)
     144             : 
     145             : #define FIND_TYPEMAP_PROPERTY(ss,tmp) zend_hash_find(Z_OBJPROP_P(ss), "typemap", sizeof("typemap"), (void **)&tmp)
     146             : #define FETCH_TYPEMAP_RES(ss,tmp) ss = (HashTable*) zend_fetch_resource(tmp TSRMLS_CC, -1, "typemap", NULL, 1, le_typemap)
     147             : 
     148             : #define FETCH_THIS_SERVICE(ss) \
     149             :         { \
     150             :                 zval **tmp; \
     151             :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr),"service", sizeof("service"), (void **)&tmp) != FAILURE) { \
     152             :                         ss = (soapServicePtr)zend_fetch_resource(tmp TSRMLS_CC, -1, "service", NULL, 1, le_service); \
     153             :                 } else { \
     154             :                         ss = NULL; \
     155             :                 } \
     156             :         }
     157             : 
     158             : static zend_class_entry* soap_class_entry;
     159             : static zend_class_entry* soap_server_class_entry;
     160             : static zend_class_entry* soap_fault_class_entry;
     161             : static zend_class_entry* soap_header_class_entry;
     162             : static zend_class_entry* soap_param_class_entry;
     163             : zend_class_entry* soap_var_class_entry;
     164             : 
     165             : ZEND_DECLARE_MODULE_GLOBALS(soap)
     166             : 
     167             : static void (*old_error_handler)(int, const char *, const uint, const char*, va_list);
     168             : 
     169             : #ifdef va_copy
     170             : #define call_old_error_handler(error_num, error_filename, error_lineno, format, args) \
     171             : { \
     172             :         va_list copy; \
     173             :         va_copy(copy, args); \
     174             :         old_error_handler(error_num, error_filename, error_lineno, format, copy); \
     175             :         va_end(copy); \
     176             : }
     177             : #else
     178             : #define call_old_error_handler(error_num, error_filename, error_lineno, format, args) \
     179             : { \
     180             :         old_error_handler(error_num, error_filename, error_lineno, format, args); \
     181             : }
     182             : #endif
     183             : 
     184             : #define PHP_SOAP_SERVER_CLASSNAME "SoapServer"
     185             : #define PHP_SOAP_CLIENT_CLASSNAME "SoapClient"
     186             : #define PHP_SOAP_VAR_CLASSNAME    "SoapVar"
     187             : #define PHP_SOAP_FAULT_CLASSNAME  "SoapFault"
     188             : #define PHP_SOAP_PARAM_CLASSNAME  "SoapParam"
     189             : #define PHP_SOAP_HEADER_CLASSNAME "SoapHeader"
     190             : 
     191             : PHP_RINIT_FUNCTION(soap);
     192             : PHP_MINIT_FUNCTION(soap);
     193             : PHP_MSHUTDOWN_FUNCTION(soap);
     194             : PHP_MINFO_FUNCTION(soap);
     195             : 
     196             : /*
     197             :   Registry Functions
     198             :   TODO: this!
     199             : */
     200             : PHP_FUNCTION(soap_encode_to_xml);
     201             : PHP_FUNCTION(soap_encode_to_zval);
     202             : PHP_FUNCTION(use_soap_error_handler);
     203             : PHP_FUNCTION(is_soap_fault);
     204             : 
     205             : 
     206             : /* Server Functions */
     207             : PHP_METHOD(SoapServer, SoapServer);
     208             : PHP_METHOD(SoapServer, setClass);
     209             : PHP_METHOD(SoapServer, setObject);
     210             : PHP_METHOD(SoapServer, addFunction);
     211             : PHP_METHOD(SoapServer, getFunctions);
     212             : PHP_METHOD(SoapServer, handle);
     213             : PHP_METHOD(SoapServer, setPersistence);
     214             : PHP_METHOD(SoapServer, fault);
     215             : PHP_METHOD(SoapServer, addSoapHeader);
     216             : 
     217             : /* Client Functions */
     218             : PHP_METHOD(SoapClient, SoapClient);
     219             : PHP_METHOD(SoapClient, __call);
     220             : PHP_METHOD(SoapClient, __getLastRequest);
     221             : PHP_METHOD(SoapClient, __getLastResponse);
     222             : PHP_METHOD(SoapClient, __getLastRequestHeaders);
     223             : PHP_METHOD(SoapClient, __getLastResponseHeaders);
     224             : PHP_METHOD(SoapClient, __getFunctions);
     225             : PHP_METHOD(SoapClient, __getTypes);
     226             : PHP_METHOD(SoapClient, __doRequest);
     227             : PHP_METHOD(SoapClient, __setCookie);
     228             : PHP_METHOD(SoapClient, __getCookies);
     229             : PHP_METHOD(SoapClient, __setLocation);
     230             : PHP_METHOD(SoapClient, __setSoapHeaders);
     231             : 
     232             : /* SoapVar Functions */
     233             : PHP_METHOD(SoapVar, SoapVar);
     234             : 
     235             : /* SoapFault Functions */
     236             : PHP_METHOD(SoapFault, SoapFault);
     237             : PHP_METHOD(SoapFault, __toString);
     238             : 
     239             : /* SoapParam Functions */
     240             : PHP_METHOD(SoapParam, SoapParam);
     241             : 
     242             : /* SoapHeader Functions */
     243             : PHP_METHOD(SoapHeader, SoapHeader);
     244             : 
     245             : #define SOAP_CTOR(class_name, func_name, arginfo, flags) PHP_ME(class_name, func_name, arginfo, flags)
     246             : 
     247             : /* {{{ arginfo */
     248             : ZEND_BEGIN_ARG_INFO(arginfo_soap__void, 0)
     249             : ZEND_END_ARG_INFO()
     250             : 
     251             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapparam_soapparam, 0, 0, 2)
     252             :         ZEND_ARG_INFO(0, data)
     253             :         ZEND_ARG_INFO(0, name)
     254             : ZEND_END_ARG_INFO()
     255             : 
     256             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapheader_soapheader, 0, 0, 2)
     257             :         ZEND_ARG_INFO(0, namespace)
     258             :         ZEND_ARG_INFO(0, name)
     259             :         ZEND_ARG_INFO(0, data)
     260             :         ZEND_ARG_INFO(0, mustunderstand)
     261             :         ZEND_ARG_INFO(0, actor)
     262             : ZEND_END_ARG_INFO()
     263             : 
     264             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapfault_soapfault, 0, 0, 2)
     265             :         ZEND_ARG_INFO(0, faultcode)
     266             :         ZEND_ARG_INFO(0, faultstring)
     267             :         ZEND_ARG_INFO(0, faultactor)
     268             :         ZEND_ARG_INFO(0, detail)
     269             :         ZEND_ARG_INFO(0, faultname)
     270             :         ZEND_ARG_INFO(0, headerfault)
     271             : ZEND_END_ARG_INFO()
     272             : 
     273             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapvar_soapvar, 0, 0, 2)
     274             :         ZEND_ARG_INFO(0, data)
     275             :         ZEND_ARG_INFO(0, encoding)
     276             :         ZEND_ARG_INFO(0, type_name)
     277             :         ZEND_ARG_INFO(0, type_namespace)
     278             :         ZEND_ARG_INFO(0, node_name)
     279             :         ZEND_ARG_INFO(0, node_namespace)
     280             : ZEND_END_ARG_INFO()
     281             : 
     282             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_fault, 0, 0, 2)
     283             :         ZEND_ARG_INFO(0, code)
     284             :         ZEND_ARG_INFO(0, string)
     285             :         ZEND_ARG_INFO(0, actor)
     286             :         ZEND_ARG_INFO(0, details)
     287             :         ZEND_ARG_INFO(0, name)
     288             : ZEND_END_ARG_INFO()
     289             : 
     290             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_addsoapheader, 0, 0, 1)
     291             :         ZEND_ARG_INFO(0, object)
     292             : ZEND_END_ARG_INFO()
     293             : 
     294             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_soapserver, 0, 0, 1)
     295             :         ZEND_ARG_INFO(0, wsdl)
     296             :         ZEND_ARG_INFO(0, options)
     297             : ZEND_END_ARG_INFO()
     298             : 
     299             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_setpersistence, 0, 0, 1)
     300             :         ZEND_ARG_INFO(0, mode)
     301             : ZEND_END_ARG_INFO()
     302             : 
     303             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_setclass, 0, 0, 1)
     304             :         ZEND_ARG_INFO(0, class_name)
     305             :         ZEND_ARG_INFO(0, args)
     306             : ZEND_END_ARG_INFO()
     307             : 
     308             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_setobject, 0, 0, 1)
     309             :         ZEND_ARG_INFO(0, object)
     310             : ZEND_END_ARG_INFO()
     311             : 
     312             : ZEND_BEGIN_ARG_INFO(arginfo_soapserver_getfunctions, 0)
     313             : ZEND_END_ARG_INFO()
     314             : 
     315             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_addfunction, 0, 0, 1)
     316             :         ZEND_ARG_INFO(0, functions)
     317             : ZEND_END_ARG_INFO()
     318             : 
     319             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_handle, 0, 0, 0)
     320             :         ZEND_ARG_INFO(0, soap_request)
     321             : ZEND_END_ARG_INFO()
     322             : 
     323             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient_soapclient, 0, 0, 1)
     324             :         ZEND_ARG_INFO(0, wsdl)
     325             :         ZEND_ARG_INFO(0, options)
     326             : ZEND_END_ARG_INFO()
     327             : 
     328             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___call, 0, 0, 2)
     329             :         ZEND_ARG_INFO(0, function_name)
     330             :         ZEND_ARG_INFO(0, arguments)
     331             : ZEND_END_ARG_INFO()
     332             : 
     333             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___soapcall, 0, 0, 2)
     334             :         ZEND_ARG_INFO(0, function_name)
     335             :         ZEND_ARG_INFO(0, arguments)
     336             :         ZEND_ARG_INFO(0, options)
     337             :         ZEND_ARG_INFO(0, input_headers)
     338             :         ZEND_ARG_INFO(1, output_headers)
     339             : ZEND_END_ARG_INFO()
     340             : 
     341             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getfunctions, 0)
     342             : ZEND_END_ARG_INFO()
     343             : 
     344             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___gettypes, 0)
     345             : ZEND_END_ARG_INFO()
     346             : 
     347             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getlastrequest, 0)
     348             : ZEND_END_ARG_INFO()
     349             : 
     350             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getlastresponse, 0)
     351             : ZEND_END_ARG_INFO()
     352             : 
     353             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getlastrequestheaders, 0)
     354             : ZEND_END_ARG_INFO()
     355             : 
     356             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getlastresponseheaders, 0)
     357             : ZEND_END_ARG_INFO()
     358             : 
     359             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___dorequest, 0, 0, 4)
     360             :         ZEND_ARG_INFO(0, request)
     361             :         ZEND_ARG_INFO(0, location)
     362             :         ZEND_ARG_INFO(0, action)
     363             :         ZEND_ARG_INFO(0, version)
     364             :         ZEND_ARG_INFO(0, one_way)
     365             : ZEND_END_ARG_INFO()
     366             : 
     367             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___setcookie, 0, 0, 1)
     368             :         ZEND_ARG_INFO(0, name)
     369             :         ZEND_ARG_INFO(0, value)
     370             : ZEND_END_ARG_INFO()
     371             : 
     372             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getcookies, 0)
     373             : ZEND_END_ARG_INFO()
     374             : 
     375             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___setsoapheaders, 0, 0, 1)
     376             :         ZEND_ARG_INFO(0, soapheaders)
     377             : ZEND_END_ARG_INFO()
     378             : 
     379             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___setlocation, 0, 0, 0)
     380             :         ZEND_ARG_INFO(0, new_location)
     381             : ZEND_END_ARG_INFO()
     382             : 
     383             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soap_use_soap_error_handler, 0, 0, 0)
     384             :         ZEND_ARG_INFO(0, handler)
     385             : ZEND_END_ARG_INFO()
     386             : 
     387             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soap_is_soap_fault, 0, 0, 1)
     388             :         ZEND_ARG_INFO(0, object)
     389             : ZEND_END_ARG_INFO()
     390             : /* }}} */
     391             : 
     392             : static const zend_function_entry soap_functions[] = {
     393             :         PHP_FE(use_soap_error_handler,  arginfo_soap_use_soap_error_handler)
     394             :         PHP_FE(is_soap_fault,                   arginfo_soap_is_soap_fault)
     395             :         PHP_FE_END
     396             : };
     397             : 
     398             : static const zend_function_entry soap_fault_functions[] = {
     399             :         SOAP_CTOR(SoapFault, SoapFault, arginfo_soapfault_soapfault, 0)
     400             :         PHP_ME(SoapFault, __toString, arginfo_soap__void, 0)
     401             :         PHP_FE_END
     402             : };
     403             : 
     404             : static const zend_function_entry soap_server_functions[] = {
     405             :         SOAP_CTOR(SoapServer, SoapServer,       arginfo_soapserver_soapserver, 0)
     406             :         PHP_ME(SoapServer, setPersistence,      arginfo_soapserver_setpersistence, 0)
     407             :         PHP_ME(SoapServer, setClass,            arginfo_soapserver_setclass, 0)
     408             :         PHP_ME(SoapServer, setObject,           arginfo_soapserver_setobject, 0)
     409             :         PHP_ME(SoapServer, addFunction,         arginfo_soapserver_addfunction, 0)
     410             :         PHP_ME(SoapServer, getFunctions,        arginfo_soapserver_getfunctions, 0)
     411             :         PHP_ME(SoapServer, handle,                      arginfo_soapserver_handle, 0)
     412             :         PHP_ME(SoapServer, fault,                       arginfo_soapserver_fault, 0)
     413             :         PHP_ME(SoapServer, addSoapHeader,       arginfo_soapserver_addsoapheader, 0)
     414             :         PHP_FE_END
     415             : };
     416             : 
     417             : static const zend_function_entry soap_client_functions[] = {
     418             :         SOAP_CTOR(SoapClient, SoapClient, arginfo_soapclient_soapclient, 0)
     419             :         PHP_ME(SoapClient, __call,                                              arginfo_soapclient___call, 0)
     420             :         ZEND_NAMED_ME(__soapCall, ZEND_MN(SoapClient___call), arginfo_soapclient___soapcall, 0)
     421             :         PHP_ME(SoapClient, __getLastRequest,                    arginfo_soapclient___getlastrequest, 0)
     422             :         PHP_ME(SoapClient, __getLastResponse,                   arginfo_soapclient___getlastresponse, 0)
     423             :         PHP_ME(SoapClient, __getLastRequestHeaders,     arginfo_soapclient___getlastrequestheaders, 0)
     424             :         PHP_ME(SoapClient, __getLastResponseHeaders,    arginfo_soapclient___getlastresponseheaders, 0)
     425             :         PHP_ME(SoapClient, __getFunctions,                              arginfo_soapclient___getfunctions, 0)
     426             :         PHP_ME(SoapClient, __getTypes,                                  arginfo_soapclient___gettypes, 0)
     427             :         PHP_ME(SoapClient, __doRequest,                                 arginfo_soapclient___dorequest, 0)
     428             :         PHP_ME(SoapClient, __setCookie,                                 arginfo_soapclient___setcookie, 0)
     429             :         PHP_ME(SoapClient, __getCookies,                                arginfo_soapclient___getcookies, 0)
     430             :         PHP_ME(SoapClient, __setLocation,                               arginfo_soapclient___setlocation, 0)
     431             :         PHP_ME(SoapClient, __setSoapHeaders,                    arginfo_soapclient___setsoapheaders, 0)
     432             :         PHP_FE_END
     433             : };
     434             : 
     435             : static const zend_function_entry soap_var_functions[] = {
     436             :         SOAP_CTOR(SoapVar, SoapVar, arginfo_soapvar_soapvar, 0)
     437             :         PHP_FE_END
     438             : };
     439             : 
     440             : static const zend_function_entry soap_param_functions[] = {
     441             :         SOAP_CTOR(SoapParam, SoapParam, arginfo_soapparam_soapparam, 0)
     442             :         PHP_FE_END
     443             : };
     444             : 
     445             : static const zend_function_entry soap_header_functions[] = {
     446             :         SOAP_CTOR(SoapHeader, SoapHeader, arginfo_soapheader_soapheader, 0)
     447             :         PHP_FE_END
     448             : };
     449             : 
     450             : zend_module_entry soap_module_entry = {
     451             : #ifdef STANDARD_MODULE_HEADER
     452             :   STANDARD_MODULE_HEADER,
     453             : #endif
     454             :   "soap",
     455             :   soap_functions,
     456             :   PHP_MINIT(soap),
     457             :   PHP_MSHUTDOWN(soap),
     458             :   PHP_RINIT(soap),
     459             :   NULL,
     460             :   PHP_MINFO(soap),
     461             : #ifdef STANDARD_MODULE_HEADER
     462             :   NO_VERSION_YET,
     463             : #endif
     464             :   STANDARD_MODULE_PROPERTIES,
     465             : };
     466             : 
     467             : #ifdef COMPILE_DL_SOAP
     468             : ZEND_GET_MODULE(soap)
     469             : #endif
     470             : 
     471       20266 : ZEND_INI_MH(OnUpdateCacheMode)
     472             : {
     473             :         char *p;
     474             : #ifndef ZTS
     475       20266 :         char *base = (char *) mh_arg2;
     476             : #else
     477             :         char *base = (char *) ts_resource(*((int *) mh_arg2));
     478             : #endif
     479             : 
     480       20266 :         p = (char*) (base+(size_t) mh_arg1);
     481             : 
     482       20266 :         *p = (char)atoi(new_value);
     483             : 
     484       20266 :         return SUCCESS;
     485             : }
     486             : 
     487       20266 : static PHP_INI_MH(OnUpdateCacheDir)
     488             : {
     489             :         /* Only do the open_basedir check at runtime */
     490       20266 :         if (stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) {
     491             :                 char *p;
     492             : 
     493           0 :                 if (memchr(new_value, '\0', new_value_length) != NULL) {
     494           0 :                         return FAILURE;
     495             :                 }
     496             : 
     497             :                 /* we do not use zend_memrchr() since path can contain ; itself */
     498           0 :                 if ((p = strchr(new_value, ';'))) {
     499             :                         char *p2;
     500           0 :                         p++;
     501           0 :                         if ((p2 = strchr(p, ';'))) {
     502           0 :                                 p = p2 + 1;
     503             :                         }
     504             :                 } else {
     505           0 :                         p = new_value;
     506             :                 }
     507             : 
     508           0 :                 if (PG(open_basedir) && *p && php_check_open_basedir(p TSRMLS_CC)) {
     509           0 :                         return FAILURE;
     510             :                 }
     511             :         }
     512             : 
     513       20266 :         OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
     514       20266 :         return SUCCESS;
     515             : }
     516             : 
     517             : PHP_INI_BEGIN()
     518             : STD_PHP_INI_ENTRY("soap.wsdl_cache_enabled",     "1", PHP_INI_ALL, OnUpdateBool,
     519             :                   cache_enabled, zend_soap_globals, soap_globals)
     520             : STD_PHP_INI_ENTRY("soap.wsdl_cache_dir",         "/tmp", PHP_INI_ALL, OnUpdateCacheDir,
     521             :                   cache_dir, zend_soap_globals, soap_globals)
     522             : STD_PHP_INI_ENTRY("soap.wsdl_cache_ttl",         "86400", PHP_INI_ALL, OnUpdateLong,
     523             :                   cache_ttl, zend_soap_globals, soap_globals)
     524             : STD_PHP_INI_ENTRY("soap.wsdl_cache",             "1", PHP_INI_ALL, OnUpdateCacheMode,
     525             :                   cache_mode, zend_soap_globals, soap_globals)
     526             : STD_PHP_INI_ENTRY("soap.wsdl_cache_limit",       "5", PHP_INI_ALL, OnUpdateLong,
     527             :                   cache_limit, zend_soap_globals, soap_globals)
     528             : PHP_INI_END()
     529             : 
     530             : static HashTable defEnc, defEncIndex, defEncNs;
     531             : 
     532       20266 : static void php_soap_prepare_globals()
     533             : {
     534             :         int i;
     535             :         encodePtr enc;
     536             : 
     537       20266 :         zend_hash_init(&defEnc, 0, NULL, NULL, 1);
     538       20266 :         zend_hash_init(&defEncIndex, 0, NULL, NULL, 1);
     539       20266 :         zend_hash_init(&defEncNs, 0, NULL, NULL, 1);
     540             : 
     541       20266 :         i = 0;
     542             :         do {
     543     1519950 :                 enc = &defaultEncoding[i];
     544             : 
     545             :                 /* If has a ns and a str_type then index it */
     546     1519950 :                 if (defaultEncoding[i].details.type_str) {
     547     1499684 :                         if (defaultEncoding[i].details.ns != NULL) {
     548             :                                 char *ns_type;
     549     1499684 :                                 spprintf(&ns_type, 0, "%s:%s", defaultEncoding[i].details.ns, defaultEncoding[i].details.type_str);
     550     1499684 :                                 zend_hash_add(&defEnc, ns_type, strlen(ns_type) + 1, &enc, sizeof(encodePtr), NULL);
     551     1499684 :                                 efree(ns_type);
     552             :                         } else {
     553           0 :                                 zend_hash_add(&defEnc, defaultEncoding[i].details.type_str, strlen(defaultEncoding[i].details.type_str) + 1, &enc, sizeof(encodePtr), NULL);
     554             :                         }
     555             :                 }
     556             :                 /* Index everything by number */
     557     1519950 :                 if (!zend_hash_index_exists(&defEncIndex, defaultEncoding[i].details.type)) {
     558     1236226 :                         zend_hash_index_update(&defEncIndex, defaultEncoding[i].details.type, &enc, sizeof(encodePtr), NULL);
     559             :                 }
     560     1519950 :                 i++;
     561     1519950 :         } while (defaultEncoding[i].details.type != END_KNOWN_TYPES);
     562             : 
     563             :         /* hash by namespace */
     564       20266 :         zend_hash_add(&defEncNs, XSD_1999_NAMESPACE, sizeof(XSD_1999_NAMESPACE), XSD_NS_PREFIX, sizeof(XSD_NS_PREFIX), NULL);
     565       20266 :         zend_hash_add(&defEncNs, XSD_NAMESPACE, sizeof(XSD_NAMESPACE), XSD_NS_PREFIX, sizeof(XSD_NS_PREFIX), NULL);
     566       20266 :         zend_hash_add(&defEncNs, XSI_NAMESPACE, sizeof(XSI_NAMESPACE), XSI_NS_PREFIX, sizeof(XSI_NS_PREFIX), NULL);
     567       20266 :         zend_hash_add(&defEncNs, XML_NAMESPACE, sizeof(XML_NAMESPACE), XML_NS_PREFIX, sizeof(XML_NS_PREFIX), NULL);
     568       20266 :         zend_hash_add(&defEncNs, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE), SOAP_1_1_ENC_NS_PREFIX, sizeof(SOAP_1_1_ENC_NS_PREFIX), NULL);
     569       20266 :         zend_hash_add(&defEncNs, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE), SOAP_1_2_ENC_NS_PREFIX, sizeof(SOAP_1_2_ENC_NS_PREFIX), NULL);
     570       20266 : }
     571             : 
     572       20266 : static void php_soap_init_globals(zend_soap_globals *soap_globals TSRMLS_DC)
     573             : {
     574       20266 :         soap_globals->defEnc = defEnc;
     575       20266 :         soap_globals->defEncIndex = defEncIndex;
     576       20266 :         soap_globals->defEncNs = defEncNs;
     577       20266 :         soap_globals->typemap = NULL;
     578       20266 :         soap_globals->use_soap_error_handler = 0;
     579       20266 :         soap_globals->error_code = NULL;
     580       20266 :         soap_globals->error_object = NULL;
     581       20266 :         soap_globals->sdl = NULL;
     582       20266 :         soap_globals->soap_version = SOAP_1_1;
     583       20266 :         soap_globals->mem_cache = NULL;
     584       20266 :         soap_globals->ref_map = NULL;
     585       20266 : }
     586             : 
     587       20302 : PHP_MSHUTDOWN_FUNCTION(soap)
     588             : {
     589       20302 :         zend_error_cb = old_error_handler;
     590       20302 :         zend_hash_destroy(&SOAP_GLOBAL(defEnc));
     591       20302 :         zend_hash_destroy(&SOAP_GLOBAL(defEncIndex));
     592       20302 :         zend_hash_destroy(&SOAP_GLOBAL(defEncNs));
     593       20302 :         if (SOAP_GLOBAL(mem_cache)) {
     594           1 :                 zend_hash_destroy(SOAP_GLOBAL(mem_cache));
     595           1 :                 free(SOAP_GLOBAL(mem_cache));
     596             :         }
     597       20302 :         UNREGISTER_INI_ENTRIES();
     598       20302 :         return SUCCESS;
     599             : }
     600             : 
     601       20223 : PHP_RINIT_FUNCTION(soap)
     602             : {
     603       20223 :         SOAP_GLOBAL(typemap) = NULL;
     604       20223 :         SOAP_GLOBAL(use_soap_error_handler) = 0;
     605       20223 :         SOAP_GLOBAL(error_code) = NULL;
     606       20223 :         SOAP_GLOBAL(error_object) = NULL;
     607       20223 :         SOAP_GLOBAL(sdl) = NULL;
     608       20223 :         SOAP_GLOBAL(soap_version) = SOAP_1_1;
     609       20223 :         SOAP_GLOBAL(encoding) = NULL;
     610       20223 :         SOAP_GLOBAL(class_map) = NULL;
     611       20223 :         SOAP_GLOBAL(features) = 0;
     612       20223 :         SOAP_GLOBAL(ref_map) = NULL;
     613       20223 :         return SUCCESS;
     614             : }
     615             : 
     616       20266 : PHP_MINIT_FUNCTION(soap)
     617             : {
     618             :         zend_class_entry ce;
     619             : 
     620             :         /* TODO: add ini entry for always use soap errors */
     621       20266 :         php_soap_prepare_globals();
     622       20266 :         ZEND_INIT_MODULE_GLOBALS(soap, php_soap_init_globals, NULL);
     623       20266 :         REGISTER_INI_ENTRIES();
     624             : 
     625             :         /* Register SoapClient class */
     626             :         /* BIG NOTE : THIS EMITS AN COMPILATION WARNING UNDER ZE2 - handle_function_call deprecated.
     627             :                 soap_call_function_handler should be of type struct _zend_function, not (*handle_function_call).
     628             :         */
     629             :         {
     630             :                 zend_internal_function fe;
     631             : 
     632       20266 :                 fe.type = ZEND_INTERNAL_FUNCTION;
     633       20266 :                 fe.handler = ZEND_MN(SoapClient___call);
     634       20266 :                 fe.function_name = NULL;
     635       20266 :                 fe.scope = NULL;
     636       20266 :                 fe.fn_flags = 0;
     637       20266 :                 fe.prototype = NULL;
     638       20266 :                 fe.num_args = 2;
     639       20266 :                 fe.arg_info = NULL;
     640             : 
     641       20266 :                 INIT_OVERLOADED_CLASS_ENTRY(ce, PHP_SOAP_CLIENT_CLASSNAME, soap_client_functions,
     642             :                         (zend_function *)&fe, NULL, NULL);
     643       20266 :                 soap_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
     644             :         }
     645             :         /* Register SoapVar class */
     646       20266 :         INIT_CLASS_ENTRY(ce, PHP_SOAP_VAR_CLASSNAME, soap_var_functions);
     647       20266 :         soap_var_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
     648             : 
     649             :         /* Register SoapServer class */
     650       20266 :         INIT_CLASS_ENTRY(ce, PHP_SOAP_SERVER_CLASSNAME, soap_server_functions);
     651       20266 :         soap_server_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
     652             : 
     653             :         /* Register SoapFault class */
     654       20266 :         INIT_CLASS_ENTRY(ce, PHP_SOAP_FAULT_CLASSNAME, soap_fault_functions);
     655       20266 :         soap_fault_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
     656             : 
     657             :         /* Register SoapParam class */
     658       20266 :         INIT_CLASS_ENTRY(ce, PHP_SOAP_PARAM_CLASSNAME, soap_param_functions);
     659       20266 :         soap_param_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
     660             : 
     661       20266 :         INIT_CLASS_ENTRY(ce, PHP_SOAP_HEADER_CLASSNAME, soap_header_functions);
     662       20266 :         soap_header_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
     663             : 
     664       20266 :         le_sdl = register_list_destructors(delete_sdl, NULL);
     665       20266 :         le_url = register_list_destructors(delete_url, NULL);
     666       20266 :         le_service = register_list_destructors(delete_service, NULL);
     667       20266 :         le_typemap = register_list_destructors(delete_hashtable, NULL);
     668             : 
     669       20266 :         REGISTER_LONG_CONSTANT("SOAP_1_1", SOAP_1_1, CONST_CS | CONST_PERSISTENT);
     670       20266 :         REGISTER_LONG_CONSTANT("SOAP_1_2", SOAP_1_2, CONST_CS | CONST_PERSISTENT);
     671             : 
     672       20266 :         REGISTER_LONG_CONSTANT("SOAP_PERSISTENCE_SESSION", SOAP_PERSISTENCE_SESSION, CONST_CS | CONST_PERSISTENT);
     673       20266 :         REGISTER_LONG_CONSTANT("SOAP_PERSISTENCE_REQUEST", SOAP_PERSISTENCE_REQUEST, CONST_CS | CONST_PERSISTENT);
     674       20266 :         REGISTER_LONG_CONSTANT("SOAP_FUNCTIONS_ALL", SOAP_FUNCTIONS_ALL, CONST_CS | CONST_PERSISTENT);
     675             : 
     676       20266 :         REGISTER_LONG_CONSTANT("SOAP_ENCODED", SOAP_ENCODED, CONST_CS | CONST_PERSISTENT);
     677       20266 :         REGISTER_LONG_CONSTANT("SOAP_LITERAL", SOAP_LITERAL, CONST_CS | CONST_PERSISTENT);
     678             : 
     679       20266 :         REGISTER_LONG_CONSTANT("SOAP_RPC", SOAP_RPC, CONST_CS | CONST_PERSISTENT);
     680       20266 :         REGISTER_LONG_CONSTANT("SOAP_DOCUMENT", SOAP_DOCUMENT, CONST_CS | CONST_PERSISTENT);
     681             : 
     682       20266 :         REGISTER_LONG_CONSTANT("SOAP_ACTOR_NEXT", SOAP_ACTOR_NEXT, CONST_CS | CONST_PERSISTENT);
     683       20266 :         REGISTER_LONG_CONSTANT("SOAP_ACTOR_NONE", SOAP_ACTOR_NONE, CONST_CS | CONST_PERSISTENT);
     684       20266 :         REGISTER_LONG_CONSTANT("SOAP_ACTOR_UNLIMATERECEIVER", SOAP_ACTOR_UNLIMATERECEIVER, CONST_CS | CONST_PERSISTENT);
     685             : 
     686       20266 :         REGISTER_LONG_CONSTANT("SOAP_COMPRESSION_ACCEPT", SOAP_COMPRESSION_ACCEPT, CONST_CS | CONST_PERSISTENT);
     687       20266 :         REGISTER_LONG_CONSTANT("SOAP_COMPRESSION_GZIP", SOAP_COMPRESSION_GZIP, CONST_CS | CONST_PERSISTENT);
     688       20266 :         REGISTER_LONG_CONSTANT("SOAP_COMPRESSION_DEFLATE", SOAP_COMPRESSION_DEFLATE, CONST_CS | CONST_PERSISTENT);
     689             : 
     690       20266 :         REGISTER_LONG_CONSTANT("SOAP_AUTHENTICATION_BASIC", SOAP_AUTHENTICATION_BASIC, CONST_CS | CONST_PERSISTENT);
     691       20266 :         REGISTER_LONG_CONSTANT("SOAP_AUTHENTICATION_DIGEST", SOAP_AUTHENTICATION_DIGEST, CONST_CS | CONST_PERSISTENT);
     692             : 
     693       20266 :         REGISTER_LONG_CONSTANT("UNKNOWN_TYPE", UNKNOWN_TYPE, CONST_CS | CONST_PERSISTENT);
     694             : 
     695       20266 :         REGISTER_LONG_CONSTANT("XSD_STRING", XSD_STRING, CONST_CS | CONST_PERSISTENT);
     696       20266 :         REGISTER_LONG_CONSTANT("XSD_BOOLEAN", XSD_BOOLEAN, CONST_CS | CONST_PERSISTENT);
     697       20266 :         REGISTER_LONG_CONSTANT("XSD_DECIMAL", XSD_DECIMAL, CONST_CS | CONST_PERSISTENT);
     698       20266 :         REGISTER_LONG_CONSTANT("XSD_FLOAT", XSD_FLOAT, CONST_CS | CONST_PERSISTENT);
     699       20266 :         REGISTER_LONG_CONSTANT("XSD_DOUBLE", XSD_DOUBLE, CONST_CS | CONST_PERSISTENT);
     700       20266 :         REGISTER_LONG_CONSTANT("XSD_DURATION", XSD_DURATION, CONST_CS | CONST_PERSISTENT);
     701       20266 :         REGISTER_LONG_CONSTANT("XSD_DATETIME", XSD_DATETIME, CONST_CS | CONST_PERSISTENT);
     702       20266 :         REGISTER_LONG_CONSTANT("XSD_TIME", XSD_TIME, CONST_CS | CONST_PERSISTENT);
     703       20266 :         REGISTER_LONG_CONSTANT("XSD_DATE", XSD_DATE, CONST_CS | CONST_PERSISTENT);
     704       20266 :         REGISTER_LONG_CONSTANT("XSD_GYEARMONTH", XSD_GYEARMONTH, CONST_CS | CONST_PERSISTENT);
     705       20266 :         REGISTER_LONG_CONSTANT("XSD_GYEAR", XSD_GYEAR, CONST_CS | CONST_PERSISTENT);
     706       20266 :         REGISTER_LONG_CONSTANT("XSD_GMONTHDAY", XSD_GMONTHDAY, CONST_CS | CONST_PERSISTENT);
     707       20266 :         REGISTER_LONG_CONSTANT("XSD_GDAY", XSD_GDAY, CONST_CS | CONST_PERSISTENT);
     708       20266 :         REGISTER_LONG_CONSTANT("XSD_GMONTH", XSD_GMONTH, CONST_CS | CONST_PERSISTENT);
     709       20266 :         REGISTER_LONG_CONSTANT("XSD_HEXBINARY", XSD_HEXBINARY, CONST_CS | CONST_PERSISTENT);
     710       20266 :         REGISTER_LONG_CONSTANT("XSD_BASE64BINARY", XSD_BASE64BINARY, CONST_CS | CONST_PERSISTENT);
     711       20266 :         REGISTER_LONG_CONSTANT("XSD_ANYURI", XSD_ANYURI, CONST_CS | CONST_PERSISTENT);
     712       20266 :         REGISTER_LONG_CONSTANT("XSD_QNAME", XSD_QNAME, CONST_CS | CONST_PERSISTENT);
     713       20266 :         REGISTER_LONG_CONSTANT("XSD_NOTATION", XSD_NOTATION, CONST_CS | CONST_PERSISTENT);
     714       20266 :         REGISTER_LONG_CONSTANT("XSD_NORMALIZEDSTRING", XSD_NORMALIZEDSTRING, CONST_CS | CONST_PERSISTENT);
     715       20266 :         REGISTER_LONG_CONSTANT("XSD_TOKEN", XSD_TOKEN, CONST_CS | CONST_PERSISTENT);
     716       20266 :         REGISTER_LONG_CONSTANT("XSD_LANGUAGE", XSD_LANGUAGE, CONST_CS | CONST_PERSISTENT);
     717       20266 :         REGISTER_LONG_CONSTANT("XSD_NMTOKEN", XSD_NMTOKEN, CONST_CS | CONST_PERSISTENT);
     718       20266 :         REGISTER_LONG_CONSTANT("XSD_NAME", XSD_NAME, CONST_CS | CONST_PERSISTENT);
     719       20266 :         REGISTER_LONG_CONSTANT("XSD_NCNAME", XSD_NCNAME, CONST_CS | CONST_PERSISTENT);
     720       20266 :         REGISTER_LONG_CONSTANT("XSD_ID", XSD_ID, CONST_CS | CONST_PERSISTENT);
     721       20266 :         REGISTER_LONG_CONSTANT("XSD_IDREF", XSD_IDREF, CONST_CS | CONST_PERSISTENT);
     722       20266 :         REGISTER_LONG_CONSTANT("XSD_IDREFS", XSD_IDREFS, CONST_CS | CONST_PERSISTENT);
     723       20266 :         REGISTER_LONG_CONSTANT("XSD_ENTITY", XSD_ENTITY, CONST_CS | CONST_PERSISTENT);
     724       20266 :         REGISTER_LONG_CONSTANT("XSD_ENTITIES", XSD_ENTITIES, CONST_CS | CONST_PERSISTENT);
     725       20266 :         REGISTER_LONG_CONSTANT("XSD_INTEGER", XSD_INTEGER, CONST_CS | CONST_PERSISTENT);
     726       20266 :         REGISTER_LONG_CONSTANT("XSD_NONPOSITIVEINTEGER", XSD_NONPOSITIVEINTEGER, CONST_CS | CONST_PERSISTENT);
     727       20266 :         REGISTER_LONG_CONSTANT("XSD_NEGATIVEINTEGER", XSD_NEGATIVEINTEGER, CONST_CS | CONST_PERSISTENT);
     728       20266 :         REGISTER_LONG_CONSTANT("XSD_LONG", XSD_LONG, CONST_CS | CONST_PERSISTENT);
     729       20266 :         REGISTER_LONG_CONSTANT("XSD_INT", XSD_INT, CONST_CS | CONST_PERSISTENT);
     730       20266 :         REGISTER_LONG_CONSTANT("XSD_SHORT", XSD_SHORT, CONST_CS | CONST_PERSISTENT);
     731       20266 :         REGISTER_LONG_CONSTANT("XSD_BYTE", XSD_BYTE, CONST_CS | CONST_PERSISTENT);
     732       20266 :         REGISTER_LONG_CONSTANT("XSD_NONNEGATIVEINTEGER", XSD_NONNEGATIVEINTEGER, CONST_CS | CONST_PERSISTENT);
     733       20266 :         REGISTER_LONG_CONSTANT("XSD_UNSIGNEDLONG", XSD_UNSIGNEDLONG, CONST_CS | CONST_PERSISTENT);
     734       20266 :         REGISTER_LONG_CONSTANT("XSD_UNSIGNEDINT", XSD_UNSIGNEDINT, CONST_CS | CONST_PERSISTENT);
     735       20266 :         REGISTER_LONG_CONSTANT("XSD_UNSIGNEDSHORT", XSD_UNSIGNEDSHORT, CONST_CS | CONST_PERSISTENT);
     736       20266 :         REGISTER_LONG_CONSTANT("XSD_UNSIGNEDBYTE", XSD_UNSIGNEDBYTE, CONST_CS | CONST_PERSISTENT);
     737       20266 :         REGISTER_LONG_CONSTANT("XSD_POSITIVEINTEGER", XSD_POSITIVEINTEGER, CONST_CS | CONST_PERSISTENT);
     738       20266 :         REGISTER_LONG_CONSTANT("XSD_NMTOKENS", XSD_NMTOKENS, CONST_CS | CONST_PERSISTENT);
     739       20266 :         REGISTER_LONG_CONSTANT("XSD_ANYTYPE", XSD_ANYTYPE, CONST_CS | CONST_PERSISTENT);
     740       20266 :         REGISTER_LONG_CONSTANT("XSD_ANYXML", XSD_ANYXML, CONST_CS | CONST_PERSISTENT);
     741             : 
     742       20266 :         REGISTER_LONG_CONSTANT("APACHE_MAP", APACHE_MAP, CONST_CS | CONST_PERSISTENT);
     743             : 
     744       20266 :         REGISTER_LONG_CONSTANT("SOAP_ENC_OBJECT", SOAP_ENC_OBJECT, CONST_CS | CONST_PERSISTENT);
     745       20266 :         REGISTER_LONG_CONSTANT("SOAP_ENC_ARRAY", SOAP_ENC_ARRAY, CONST_CS | CONST_PERSISTENT);
     746             : 
     747       20266 :         REGISTER_LONG_CONSTANT("XSD_1999_TIMEINSTANT", XSD_1999_TIMEINSTANT, CONST_CS | CONST_PERSISTENT);
     748             : 
     749       20266 :         REGISTER_STRING_CONSTANT("XSD_NAMESPACE", XSD_NAMESPACE, CONST_CS | CONST_PERSISTENT);
     750       20266 :         REGISTER_STRING_CONSTANT("XSD_1999_NAMESPACE", XSD_1999_NAMESPACE,  CONST_CS | CONST_PERSISTENT);
     751             : 
     752       20266 :         REGISTER_LONG_CONSTANT("SOAP_SINGLE_ELEMENT_ARRAYS", SOAP_SINGLE_ELEMENT_ARRAYS, CONST_CS | CONST_PERSISTENT);
     753       20266 :         REGISTER_LONG_CONSTANT("SOAP_WAIT_ONE_WAY_CALLS", SOAP_WAIT_ONE_WAY_CALLS, CONST_CS | CONST_PERSISTENT);
     754       20266 :         REGISTER_LONG_CONSTANT("SOAP_USE_XSI_ARRAY_TYPE", SOAP_USE_XSI_ARRAY_TYPE, CONST_CS | CONST_PERSISTENT);
     755             : 
     756       20266 :         REGISTER_LONG_CONSTANT("WSDL_CACHE_NONE",   WSDL_CACHE_NONE,   CONST_CS | CONST_PERSISTENT);
     757       20266 :         REGISTER_LONG_CONSTANT("WSDL_CACHE_DISK",   WSDL_CACHE_DISK,   CONST_CS | CONST_PERSISTENT);
     758       20266 :         REGISTER_LONG_CONSTANT("WSDL_CACHE_MEMORY", WSDL_CACHE_MEMORY, CONST_CS | CONST_PERSISTENT);
     759       20266 :         REGISTER_LONG_CONSTANT("WSDL_CACHE_BOTH",   WSDL_CACHE_BOTH,   CONST_CS | CONST_PERSISTENT);
     760             : 
     761       20266 :         old_error_handler = zend_error_cb;
     762       20266 :         zend_error_cb = soap_error_handler;
     763             : 
     764       20266 :         return SUCCESS;
     765             : }
     766             : 
     767         148 : PHP_MINFO_FUNCTION(soap)
     768             : {
     769         148 :         php_info_print_table_start();
     770         148 :         php_info_print_table_row(2, "Soap Client", "enabled");
     771         148 :         php_info_print_table_row(2, "Soap Server", "enabled");
     772         148 :         php_info_print_table_end();
     773         148 :         DISPLAY_INI_ENTRIES();
     774         148 : }
     775             : 
     776             : 
     777             : /* {{{ proto object SoapParam::SoapParam ( mixed data, string name)
     778             :    SoapParam constructor */
     779          30 : PHP_METHOD(SoapParam, SoapParam)
     780             : {
     781             :         zval *data;
     782             :         char *name;
     783             :         int name_length;
     784             : 
     785          30 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &data, &name, &name_length) == FAILURE) {
     786           0 :                 return;
     787             :         }
     788          30 :         if (name_length == 0) {
     789           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter name");
     790           0 :                 return;
     791             :         }
     792             : 
     793          30 :         add_property_stringl(this_ptr, "param_name", name, name_length, 1);
     794          30 :         add_property_zval(this_ptr, "param_data", data);
     795             : }
     796             : /* }}} */
     797             : 
     798             : 
     799             : /* {{{ proto object SoapHeader::SoapHeader ( string namespace, string name [, mixed data [, bool mustUnderstand [, mixed actor]]])
     800             :    SoapHeader constructor */
     801          31 : PHP_METHOD(SoapHeader, SoapHeader)
     802             : {
     803          31 :         zval *data = NULL, *actor = NULL;
     804             :         char *name, *ns;
     805             :         int name_len, ns_len;
     806          31 :         zend_bool must_understand = 0;
     807             : 
     808          31 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|zbz", &ns, &ns_len, &name, &name_len, &data, &must_understand, &actor) == FAILURE) {
     809           0 :                 return;
     810             :         }
     811          31 :         if (ns_len == 0) {
     812           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid namespace");
     813           1 :                 return;
     814             :         }
     815          30 :         if (name_len == 0) {
     816           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid header name");
     817           0 :                 return;
     818             :         }
     819             : 
     820          30 :         add_property_stringl(this_ptr, "namespace", ns, ns_len, 1);
     821          30 :         add_property_stringl(this_ptr, "name", name, name_len, 1);
     822          30 :         if (data) {
     823          26 :                 add_property_zval(this_ptr, "data", data);
     824             :         }
     825          30 :         add_property_bool(this_ptr, "mustUnderstand", must_understand);
     826          30 :         if (actor == NULL) {
     827           6 :         } else if (Z_TYPE_P(actor) == IS_LONG &&
     828           2 :           (Z_LVAL_P(actor) == SOAP_ACTOR_NEXT ||
     829           0 :            Z_LVAL_P(actor) == SOAP_ACTOR_NONE ||
     830           0 :            Z_LVAL_P(actor) == SOAP_ACTOR_UNLIMATERECEIVER)) {
     831           2 :                 add_property_long(this_ptr, "actor", Z_LVAL_P(actor));
     832           0 :         } else if (Z_TYPE_P(actor) == IS_STRING && Z_STRLEN_P(actor) > 0) {
     833           0 :                 add_property_stringl(this_ptr, "actor", Z_STRVAL_P(actor), Z_STRLEN_P(actor), 1);
     834             :         } else {
     835           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid actor");
     836             :         }
     837             : }
     838             : 
     839             : /* {{{ proto object SoapFault::SoapFault ( string faultcode, string faultstring [, string faultactor [, mixed detail [, string faultname [, mixed headerfault]]]])
     840             :    SoapFault constructor */
     841          65 : PHP_METHOD(SoapFault, SoapFault)
     842             : {
     843          65 :         char *fault_string = NULL, *fault_code = NULL, *fault_actor = NULL, *name = NULL, *fault_code_ns = NULL;
     844          65 :         int fault_string_len, fault_actor_len = 0, name_len = 0, fault_code_len = 0;
     845          65 :         zval *code = NULL, *details = NULL, *headerfault = NULL;
     846             : 
     847          65 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs|s!z!s!z",
     848             :                 &code,
     849             :                 &fault_string, &fault_string_len,
     850             :                 &fault_actor, &fault_actor_len,
     851             :                 &details, &name, &name_len, &headerfault) == FAILURE) {
     852           0 :                 return;
     853             :         }
     854             : 
     855          65 :         if (Z_TYPE_P(code) == IS_NULL) {
     856          65 :         } else if (Z_TYPE_P(code) == IS_STRING) {
     857          65 :                 fault_code = Z_STRVAL_P(code);
     858          65 :                 fault_code_len = Z_STRLEN_P(code);
     859           0 :         } else if (Z_TYPE_P(code) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_P(code)) == 2) {
     860             :                 zval **t_ns, **t_code;
     861             : 
     862           0 :                 zend_hash_internal_pointer_reset(Z_ARRVAL_P(code));
     863           0 :                 zend_hash_get_current_data(Z_ARRVAL_P(code), (void**)&t_ns);
     864           0 :                 zend_hash_move_forward(Z_ARRVAL_P(code));
     865           0 :                 zend_hash_get_current_data(Z_ARRVAL_P(code), (void**)&t_code);
     866           0 :                 if (Z_TYPE_PP(t_ns) == IS_STRING && Z_TYPE_PP(t_code) == IS_STRING) {
     867           0 :                   fault_code_ns = Z_STRVAL_PP(t_ns);
     868           0 :                   fault_code = Z_STRVAL_PP(t_code);
     869           0 :                   fault_code_len = Z_STRLEN_PP(t_code);
     870             :                 } else {
     871           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid fault code");
     872           0 :                         return;
     873             :                 }
     874             :         } else  {
     875           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid fault code");
     876           0 :                 return;
     877             :         }
     878          65 :         if (fault_code != NULL && fault_code_len == 0) {
     879           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid fault code");
     880           0 :                 return;
     881             :         }
     882          65 :         if (name != NULL && name_len == 0) {
     883           0 :                 name = NULL;
     884             :         }
     885             : 
     886          65 :         set_soap_fault(this_ptr, fault_code_ns, fault_code, fault_string, fault_actor, details, name TSRMLS_CC);
     887          65 :         if (headerfault != NULL) {
     888           1 :                 add_property_zval(this_ptr, "headerfault", headerfault);
     889             :         }
     890             : }
     891             : /* }}} */
     892             : 
     893             : 
     894             : /* {{{ proto object SoapFault::SoapFault ( string faultcode, string faultstring [, string faultactor [, mixed detail [, string faultname [, mixed headerfault]]]])
     895             :    SoapFault constructor */
     896           1 : PHP_METHOD(SoapFault, __toString)
     897             : {
     898             :         zval *faultcode, *faultstring, *file, *line, *trace;
     899             :         char *str;
     900             :         int len;
     901             :         zend_fcall_info fci;
     902             :         zval fname;
     903             : 
     904           1 :         if (zend_parse_parameters_none() == FAILURE) {
     905           0 :                 return;
     906             :         }
     907             : 
     908           1 :         faultcode   = zend_read_property(soap_fault_class_entry, this_ptr, "faultcode", sizeof("faultcode")-1, 1 TSRMLS_CC);
     909           1 :         faultstring = zend_read_property(soap_fault_class_entry, this_ptr, "faultstring", sizeof("faultstring")-1, 1 TSRMLS_CC);
     910           1 :         file = zend_read_property(soap_fault_class_entry, this_ptr, "file", sizeof("file")-1, 1 TSRMLS_CC);
     911           1 :         line = zend_read_property(soap_fault_class_entry, this_ptr, "line", sizeof("line")-1, 1 TSRMLS_CC);
     912             : 
     913           1 :         ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1, 0);
     914             : 
     915           1 :         fci.size = sizeof(fci);
     916           1 :         fci.function_table = &Z_OBJCE_P(getThis())->function_table;
     917           1 :         fci.function_name = &fname;
     918           1 :         fci.symbol_table = NULL;
     919           1 :         fci.object_ptr = getThis();
     920           1 :         fci.retval_ptr_ptr = &trace;
     921           1 :         fci.param_count = 0;
     922           1 :         fci.params = NULL;
     923           1 :         fci.no_separation = 1;
     924             : 
     925           1 :         zend_call_function(&fci, NULL TSRMLS_CC);
     926             : 
     927           1 :         convert_to_string(faultcode);
     928           1 :         convert_to_string(faultstring);
     929           1 :         convert_to_string(file);
     930           1 :         convert_to_long(line);
     931           1 :         convert_to_string(trace);
     932             : 
     933           2 :         len = spprintf(&str, 0, "SoapFault exception: [%s] %s in %s:%ld\nStack trace:\n%s",
     934             :                        Z_STRVAL_P(faultcode), Z_STRVAL_P(faultstring), Z_STRVAL_P(file), Z_LVAL_P(line),
     935           2 :                        Z_STRLEN_P(trace) ? Z_STRVAL_P(trace) : "#0 {main}\n");
     936             : 
     937           1 :         zval_ptr_dtor(&trace);
     938             : 
     939           1 :         RETURN_STRINGL(str, len, 0);
     940             : }
     941             : /* }}} */
     942             : 
     943             : /* {{{ proto object SoapVar::SoapVar ( mixed data, int encoding [, string type_name [, string type_namespace [, string node_name [, string node_namespace]]]])
     944             :    SoapVar constructor */
     945         105 : PHP_METHOD(SoapVar, SoapVar)
     946             : {
     947             :         zval *data, *type;
     948         105 :         char *stype = NULL, *ns = NULL, *name = NULL, *namens = NULL;
     949         105 :         int stype_len = 0, ns_len = 0, name_len = 0, namens_len = 0;
     950             : 
     951         105 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!z|ssss", &data, &type, &stype, &stype_len, &ns, &ns_len, &name, &name_len, &namens, &namens_len) == FAILURE) {
     952           0 :                 return;
     953             :         }
     954             : 
     955         105 :         if (Z_TYPE_P(type) == IS_NULL) {
     956           2 :                 add_property_long(this_ptr, "enc_type", UNKNOWN_TYPE);
     957             :         } else {
     958         103 :                 if (zend_hash_index_exists(&SOAP_GLOBAL(defEncIndex), Z_LVAL_P(type))) {
     959         103 :                         add_property_long(this_ptr, "enc_type", Z_LVAL_P(type));
     960             :                 } else {
     961           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type ID");
     962           0 :                         return;
     963             :                 }
     964             :         }
     965             : 
     966         105 :         if (data) {
     967         103 :                 add_property_zval(this_ptr, "enc_value", data);
     968             :         }
     969             : 
     970         105 :         if (stype && stype_len > 0) {
     971          21 :                 add_property_stringl(this_ptr, "enc_stype", stype, stype_len, 1);
     972             :         }
     973         105 :         if (ns && ns_len > 0) {
     974          21 :                 add_property_stringl(this_ptr, "enc_ns", ns, ns_len, 1);
     975             :         }
     976         105 :         if (name && name_len > 0) {
     977          25 :                 add_property_stringl(this_ptr, "enc_name", name, name_len, 1);
     978             :         }
     979         105 :         if (namens && namens_len > 0) {
     980           2 :                 add_property_stringl(this_ptr, "enc_namens", namens, namens_len, 1);
     981             :         }
     982             : }
     983             : /* }}} */
     984             : 
     985             : 
     986          13 : static HashTable* soap_create_typemap(sdlPtr sdl, HashTable *ht TSRMLS_DC)
     987             : {
     988             :         zval **tmp;
     989             :         HashTable *ht2;
     990             :         HashPosition pos1, pos2;
     991          13 :         HashTable *typemap = NULL;
     992             :         
     993          13 :         zend_hash_internal_pointer_reset_ex(ht, &pos1);
     994          39 :         while (zend_hash_get_current_data_ex(ht, (void**)&tmp, &pos1) == SUCCESS) {
     995          13 :                 char *type_name = NULL;
     996          13 :                 char *type_ns = NULL;
     997          13 :                 zval *to_xml = NULL;
     998          13 :                 zval *to_zval = NULL;
     999             :                 encodePtr enc, new_enc;
    1000             : 
    1001          13 :                 if (Z_TYPE_PP(tmp) != IS_ARRAY) {
    1002           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong 'typemap' option");
    1003           0 :                         return NULL;
    1004             :                 }
    1005          13 :                 ht2 = Z_ARRVAL_PP(tmp);
    1006             : 
    1007          13 :                 zend_hash_internal_pointer_reset_ex(ht2, &pos2);
    1008          65 :                 while (zend_hash_get_current_data_ex(ht2, (void**)&tmp, &pos2) == SUCCESS) {
    1009          39 :                         char *name = NULL;
    1010             :                         unsigned int name_len;
    1011             :                         ulong index;
    1012             : 
    1013          39 :                         zend_hash_get_current_key_ex(ht2, &name, &name_len, &index, 0, &pos2);
    1014          39 :                         if (name) {
    1015          65 :                                 if (name_len == sizeof("type_name") &&
    1016          13 :                                     strncmp(name, "type_name", sizeof("type_name")-1) == 0) {
    1017          13 :                                         if (Z_TYPE_PP(tmp) == IS_STRING) {
    1018          13 :                                                 type_name = Z_STRVAL_PP(tmp);
    1019           0 :                                         } else if (Z_TYPE_PP(tmp) != IS_NULL) {
    1020             :                                         }
    1021          52 :                                 } else if (name_len == sizeof("type_ns") &&
    1022          13 :                                     strncmp(name, "type_ns", sizeof("type_ns")-1) == 0) {
    1023          13 :                                         if (Z_TYPE_PP(tmp) == IS_STRING) {
    1024          13 :                                                 type_ns = Z_STRVAL_PP(tmp);
    1025           0 :                                         } else if (Z_TYPE_PP(tmp) != IS_NULL) {
    1026             :                                         }
    1027          27 :                                 } else if (name_len == sizeof("to_xml") &&
    1028           7 :                                     strncmp(name, "to_xml", sizeof("to_xml")-1) == 0) {
    1029           7 :                                         to_xml = *tmp;
    1030          12 :                                 } else if (name_len == sizeof("from_xml") &&
    1031           6 :                                     strncmp(name, "from_xml", sizeof("from_xml")-1) == 0) {
    1032           6 :                                         to_zval = *tmp;
    1033             :                                 }
    1034             :                         }
    1035          39 :                         zend_hash_move_forward_ex(ht2, &pos2);
    1036             :                 }               
    1037             : 
    1038          13 :                 if (type_name) {
    1039          13 :                         smart_str nscat = {0};
    1040             : 
    1041          13 :                         if (type_ns) {
    1042          13 :                                 enc = get_encoder(sdl, type_ns, type_name);
    1043             :                         } else {
    1044           0 :                                 enc = get_encoder_ex(sdl, type_name, strlen(type_name));
    1045             :                         }
    1046             : 
    1047          13 :                         new_enc = emalloc(sizeof(encode));
    1048          13 :                         memset(new_enc, 0, sizeof(encode));
    1049             : 
    1050          13 :                         if (enc) {
    1051           9 :                                 new_enc->details.type = enc->details.type;
    1052           9 :                                 new_enc->details.ns = estrdup(enc->details.ns);
    1053           9 :                                 new_enc->details.type_str = estrdup(enc->details.type_str);
    1054           9 :                                 new_enc->details.sdl_type = enc->details.sdl_type;
    1055             :                         } else {
    1056           4 :                                 enc = get_conversion(UNKNOWN_TYPE);
    1057           4 :                                 new_enc->details.type = enc->details.type;
    1058           4 :                                 if (type_ns) {
    1059           4 :                                         new_enc->details.ns = estrdup(type_ns);
    1060             :                                 }
    1061           4 :                                 new_enc->details.type_str = estrdup(type_name);
    1062             :                         }
    1063          13 :                         new_enc->to_xml = enc->to_xml;
    1064          13 :                         new_enc->to_zval = enc->to_zval;
    1065          13 :                         new_enc->details.map = emalloc(sizeof(soapMapping));
    1066          13 :                         memset(new_enc->details.map, 0, sizeof(soapMapping));                        
    1067          13 :                         if (to_xml) {
    1068           7 :                                 zval_add_ref(&to_xml);
    1069           7 :                                 new_enc->details.map->to_xml = to_xml;
    1070           7 :                                 new_enc->to_xml = to_xml_user;
    1071           6 :                         } else if (enc->details.map && enc->details.map->to_xml) {
    1072           0 :                                 zval_add_ref(&enc->details.map->to_xml);
    1073           0 :                                 new_enc->details.map->to_xml = enc->details.map->to_xml;
    1074             :                         }
    1075          13 :                         if (to_zval) {
    1076           6 :                                 zval_add_ref(&to_zval);
    1077           6 :                                 new_enc->details.map->to_zval = to_zval;
    1078           6 :                                 new_enc->to_zval = to_zval_user;
    1079           7 :                         } else if (enc->details.map && enc->details.map->to_zval) {
    1080           0 :                                 zval_add_ref(&enc->details.map->to_zval);
    1081           0 :                                 new_enc->details.map->to_zval = enc->details.map->to_zval;
    1082             :                         }
    1083          13 :                         if (!typemap) {
    1084          13 :                                 typemap = emalloc(sizeof(HashTable));
    1085          13 :                                 zend_hash_init(typemap, 0, NULL, delete_encoder, 0);
    1086             :                         }
    1087             : 
    1088          13 :                         if (type_ns) {
    1089          13 :                                 smart_str_appends(&nscat, type_ns);
    1090          13 :                                 smart_str_appendc(&nscat, ':');
    1091             :                         }
    1092          13 :                         smart_str_appends(&nscat, type_name);
    1093          13 :                         smart_str_0(&nscat);
    1094          13 :                         zend_hash_update(typemap, nscat.c, nscat.len + 1, &new_enc, sizeof(encodePtr), NULL);
    1095          13 :                         smart_str_free(&nscat);
    1096             :                 }
    1097          13 :                 zend_hash_move_forward_ex(ht, &pos1);
    1098             :         }
    1099          13 :         return typemap;
    1100             : }
    1101             : 
    1102             : 
    1103             : /* {{{ proto object SoapServer::SoapServer ( mixed wsdl [, array options])
    1104             :    SoapServer constructor */
    1105         456 : PHP_METHOD(SoapServer, SoapServer)
    1106             : {
    1107             :         soapServicePtr service;
    1108         456 :         zval *wsdl = NULL, *options = NULL;
    1109             :         int ret;
    1110         456 :         int version = SOAP_1_1;
    1111             :         long cache_wsdl;
    1112         456 :         HashTable *typemap_ht = NULL;
    1113             : 
    1114         456 :         SOAP_SERVER_BEGIN_CODE();
    1115             : 
    1116         456 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z|a", &wsdl, &options) == FAILURE) {
    1117           0 :                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
    1118             :         }
    1119             : 
    1120         456 :         if (Z_TYPE_P(wsdl) != IS_STRING && Z_TYPE_P(wsdl) != IS_NULL) {
    1121           0 :                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
    1122             :         }
    1123             :         
    1124         456 :         service = emalloc(sizeof(soapService));
    1125         456 :         memset(service, 0, sizeof(soapService));
    1126         456 :         service->send_errors = 1;
    1127             : 
    1128         456 :         cache_wsdl = SOAP_GLOBAL(cache_enabled) ? SOAP_GLOBAL(cache_mode) : 0;
    1129             : 
    1130         456 :         if (options != NULL) {
    1131         233 :                 HashTable *ht = Z_ARRVAL_P(options);
    1132             :                 zval **tmp;
    1133             : 
    1134         233 :                 if (zend_hash_find(ht, "soap_version", sizeof("soap_version"), (void**)&tmp) == SUCCESS) {
    1135         300 :                         if (Z_TYPE_PP(tmp) == IS_LONG &&
    1136         150 :                             (Z_LVAL_PP(tmp) == SOAP_1_1 || Z_LVAL_PP(tmp) == SOAP_1_2)) {
    1137          75 :                                 version = Z_LVAL_PP(tmp);
    1138             :                         } else {
    1139           0 :                                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "'soap_version' option must be SOAP_1_1 or SOAP_1_2");
    1140             :                         }
    1141             :                 }
    1142             : 
    1143         327 :                 if (zend_hash_find(ht, "uri", sizeof("uri"), (void**)&tmp) == SUCCESS &&
    1144          47 :                     Z_TYPE_PP(tmp) == IS_STRING) {
    1145          47 :                         service->uri = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
    1146         186 :                 } else if (Z_TYPE_P(wsdl) == IS_NULL) {
    1147           0 :                         php_error_docref(NULL TSRMLS_CC, E_ERROR, "'uri' option is required in nonWSDL mode");
    1148             :                 }
    1149             : 
    1150         314 :                 if (zend_hash_find(ht, "actor", sizeof("actor"), (void**)&tmp) == SUCCESS &&
    1151          81 :                     Z_TYPE_PP(tmp) == IS_STRING) {
    1152          81 :                         service->actor = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
    1153             :                 }
    1154             : 
    1155         237 :                 if (zend_hash_find(ht, "encoding", sizeof("encoding"), (void**)&tmp) == SUCCESS &&
    1156           4 :                     Z_TYPE_PP(tmp) == IS_STRING) {
    1157             :                         xmlCharEncodingHandlerPtr encoding;
    1158             :                 
    1159           4 :                         encoding = xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp));
    1160           4 :                         if (encoding == NULL) {
    1161           0 :                                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid 'encoding' option - '%s'", Z_STRVAL_PP(tmp));
    1162             :                         } else {
    1163           4 :                           service->encoding = encoding;
    1164             :                         }
    1165             :                 }
    1166             : 
    1167         244 :                 if (zend_hash_find(ht, "classmap", sizeof("classmap"), (void**)&tmp) == SUCCESS &&
    1168          11 :                         Z_TYPE_PP(tmp) == IS_ARRAY) {
    1169             :                         zval *ztmp;
    1170             : 
    1171          11 :                         ALLOC_HASHTABLE(service->class_map);
    1172          11 :                         zend_hash_init(service->class_map, zend_hash_num_elements((*tmp)->value.ht), NULL, ZVAL_PTR_DTOR, 0);
    1173          11 :                         zend_hash_copy(service->class_map, (*tmp)->value.ht, (copy_ctor_func_t) zval_add_ref, (void *) &ztmp, sizeof(zval *));
    1174             :                 }
    1175             : 
    1176         247 :                 if (zend_hash_find(ht, "typemap", sizeof("typemap"), (void**)&tmp) == SUCCESS &&
    1177           7 :                         Z_TYPE_PP(tmp) == IS_ARRAY &&
    1178           7 :                         zend_hash_num_elements(Z_ARRVAL_PP(tmp)) > 0) {
    1179           7 :                         typemap_ht = Z_ARRVAL_PP(tmp);
    1180             :                 }
    1181             : 
    1182         321 :                 if (zend_hash_find(ht, "features", sizeof("features"), (void**)&tmp) == SUCCESS &&
    1183          88 :                         Z_TYPE_PP(tmp) == IS_LONG) {
    1184          88 :                         service->features = Z_LVAL_PP(tmp);
    1185             :                 }
    1186             : 
    1187         234 :                 if (zend_hash_find(ht, "cache_wsdl", sizeof("cache_wsdl"), (void**)&tmp) == SUCCESS &&
    1188           1 :                     Z_TYPE_PP(tmp) == IS_LONG) {
    1189           1 :                         cache_wsdl = Z_LVAL_PP(tmp);
    1190             :                 }
    1191             : 
    1192         235 :                 if (zend_hash_find(ht, "send_errors", sizeof("send_errors"), (void**)&tmp) == SUCCESS &&
    1193           2 :                     (Z_TYPE_PP(tmp) == IS_BOOL || Z_TYPE_PP(tmp) == IS_LONG)) {
    1194           1 :                         service->send_errors = Z_LVAL_PP(tmp);
    1195             :                 }
    1196             : 
    1197         223 :         } else if (Z_TYPE_P(wsdl) == IS_NULL) {
    1198           0 :                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "'uri' option is required in nonWSDL mode");
    1199             :         }
    1200             : 
    1201         456 :         service->version = version;
    1202         456 :         service->type = SOAP_FUNCTIONS;
    1203         456 :         service->soap_functions.functions_all = FALSE;
    1204         456 :         service->soap_functions.ft = emalloc(sizeof(HashTable));
    1205         456 :         zend_hash_init(service->soap_functions.ft, 0, NULL, ZVAL_PTR_DTOR, 0);
    1206             : 
    1207         456 :         if (Z_TYPE_P(wsdl) != IS_NULL) {
    1208         409 :                 service->sdl = get_sdl(this_ptr, Z_STRVAL_P(wsdl), cache_wsdl TSRMLS_CC);
    1209         409 :                 if (service->uri == NULL) {
    1210         409 :                         if (service->sdl->target_ns) {
    1211         409 :                                 service->uri = estrdup(service->sdl->target_ns);
    1212             :                         } else {
    1213             :                                 /*FIXME*/
    1214           0 :                                 service->uri = estrdup("http://unknown-uri/");
    1215             :                         }
    1216             :                 }
    1217             :         }
    1218             :         
    1219         456 :         if (typemap_ht) {
    1220           7 :                 service->typemap = soap_create_typemap(service->sdl, typemap_ht TSRMLS_CC);
    1221             :         }
    1222             : 
    1223         456 :         ret = zend_list_insert(service, le_service TSRMLS_CC);
    1224         456 :         add_property_resource(this_ptr, "service", ret);
    1225             : 
    1226         456 :         SOAP_SERVER_END_CODE();
    1227         456 : }
    1228             : /* }}} */
    1229             : 
    1230             : 
    1231             : /* {{{ proto object SoapServer::setPersistence ( int mode )
    1232             :    Sets persistence mode of SoapServer */
    1233           2 : PHP_METHOD(SoapServer, setPersistence)
    1234             : {
    1235             :         soapServicePtr service;
    1236             :         long value;
    1237             : 
    1238           2 :         SOAP_SERVER_BEGIN_CODE();
    1239             : 
    1240           2 :         FETCH_THIS_SERVICE(service);
    1241             : 
    1242           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) != FAILURE) {
    1243           2 :                 if (service->type == SOAP_CLASS) {
    1244           5 :                         if (value == SOAP_PERSISTENCE_SESSION ||
    1245           1 :                                 value == SOAP_PERSISTENCE_REQUEST) {
    1246           2 :                                 service->soap_class.persistance = value;
    1247             :                         } else {
    1248           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to set persistence with bogus value (%ld)", value);
    1249           0 :                                 return;
    1250             :                         }
    1251             :                 } else {
    1252           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to set persistence when you are using you SOAP SERVER in function mode, no persistence needed");
    1253           0 :                         return;
    1254             :                 }
    1255             :         }
    1256             : 
    1257           2 :         SOAP_SERVER_END_CODE();
    1258             : }
    1259             : /* }}} */
    1260             : 
    1261             : 
    1262             : /* {{{ proto void SoapServer::setClass(string class_name [, mixed args])
    1263             :    Sets class which will handle SOAP requests */
    1264         310 : PHP_METHOD(SoapServer, setClass)
    1265             : {
    1266             :         soapServicePtr service;
    1267             :         char *classname;
    1268             :         zend_class_entry **ce;
    1269             : 
    1270         310 :         int classname_len, found, num_args = 0;
    1271         310 :         zval ***argv = NULL;
    1272             : 
    1273         310 :         SOAP_SERVER_BEGIN_CODE();
    1274             : 
    1275         310 :         FETCH_THIS_SERVICE(service);
    1276             : 
    1277         310 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s*", &classname, &classname_len, &argv, &num_args) == FAILURE) {
    1278           0 :                 return;
    1279             :         }
    1280             : 
    1281         310 :         found = zend_lookup_class(classname, classname_len, &ce TSRMLS_CC);
    1282             : 
    1283         310 :         if (found != FAILURE) {
    1284         310 :                 service->type = SOAP_CLASS;
    1285         310 :                 service->soap_class.ce = *ce;
    1286             : 
    1287         310 :                 service->soap_class.persistance = SOAP_PERSISTENCE_REQUEST;
    1288         310 :                 service->soap_class.argc = num_args;
    1289         310 :                 if (service->soap_class.argc > 0) {
    1290             :                         int i;
    1291           1 :                         service->soap_class.argv = safe_emalloc(sizeof(zval), service->soap_class.argc, 0);
    1292           2 :                         for (i = 0;i < service->soap_class.argc;i++) {
    1293           1 :                                 service->soap_class.argv[i] = *(argv[i]);
    1294           1 :                                 zval_add_ref(&service->soap_class.argv[i]);
    1295             :                         }
    1296             :                 }
    1297             :         } else {
    1298           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to set a non existent class (%s)", classname);
    1299           0 :                 return;
    1300             :         }
    1301             : 
    1302         310 :         if (argv) {
    1303           1 :                 efree(argv);
    1304             :         }
    1305             : 
    1306         310 :         SOAP_SERVER_END_CODE();
    1307             : }
    1308             : /* }}} */
    1309             : 
    1310             : 
    1311             : /* {{{ proto void SoapServer::setObject(object)
    1312             :    Sets object which will handle SOAP requests */
    1313           4 : PHP_METHOD(SoapServer, setObject)
    1314             : {
    1315             :         soapServicePtr service;
    1316             :         zval *obj;
    1317             : 
    1318           4 :         SOAP_SERVER_BEGIN_CODE();
    1319             : 
    1320           4 :         FETCH_THIS_SERVICE(service);
    1321             : 
    1322           4 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
    1323           0 :                 return;
    1324             :         }
    1325             : 
    1326           4 :         service->type = SOAP_OBJECT;
    1327             : 
    1328           4 :         MAKE_STD_ZVAL(service->soap_object);
    1329          12 :         MAKE_COPY_ZVAL(&obj, service->soap_object);
    1330             : 
    1331           4 :         SOAP_SERVER_END_CODE();
    1332             : }
    1333             : /* }}} */
    1334             : 
    1335             : 
    1336             : /* {{{ proto array SoapServer::getFunctions(void)
    1337             :    Returns list of defined functions */
    1338           4 : PHP_METHOD(SoapServer, getFunctions)
    1339             : {
    1340             :         soapServicePtr  service;
    1341           4 :         HashTable      *ft = NULL;
    1342             : 
    1343           4 :         SOAP_SERVER_BEGIN_CODE();
    1344             : 
    1345           4 :         if (zend_parse_parameters_none() == FAILURE) {
    1346           0 :                 return;
    1347             :         }
    1348             :         
    1349           4 :         FETCH_THIS_SERVICE(service);
    1350             : 
    1351           4 :         array_init(return_value);
    1352           4 :         if (service->type == SOAP_OBJECT) {
    1353           1 :                 ft = &(Z_OBJCE_P(service->soap_object)->function_table);
    1354           3 :         } else if (service->type == SOAP_CLASS) {
    1355           2 :                 ft = &service->soap_class.ce->function_table;
    1356           1 :         } else if (service->soap_functions.functions_all == TRUE) {
    1357           0 :                 ft = EG(function_table);
    1358           1 :         } else if (service->soap_functions.ft != NULL) {
    1359             :                 zval **name;
    1360             :                 HashPosition pos;
    1361             : 
    1362           1 :                 zend_hash_internal_pointer_reset_ex(service->soap_functions.ft, &pos);
    1363           4 :                 while (zend_hash_get_current_data_ex(service->soap_functions.ft, (void **)&name, &pos) != FAILURE) {
    1364           2 :                         add_next_index_string(return_value, Z_STRVAL_PP(name), 1);
    1365           2 :                         zend_hash_move_forward_ex(service->soap_functions.ft, &pos);
    1366             :                 }
    1367             :         }
    1368           4 :         if (ft != NULL) {
    1369             :                 zend_function *f;
    1370             :                 HashPosition pos;
    1371           3 :                 zend_hash_internal_pointer_reset_ex(ft, &pos);
    1372          12 :                 while (zend_hash_get_current_data_ex(ft, (void **)&f, &pos) != FAILURE) {
    1373           6 :                         if ((service->type != SOAP_OBJECT && service->type != SOAP_CLASS) || (f->common.fn_flags & ZEND_ACC_PUBLIC)) {
    1374           5 :                                 add_next_index_string(return_value, f->common.function_name, 1);
    1375             :                         }
    1376           6 :                         zend_hash_move_forward_ex(ft, &pos);
    1377             :                 }
    1378             :         }
    1379             : 
    1380           4 :         SOAP_SERVER_END_CODE();
    1381             : }
    1382             : /* }}} */
    1383             : 
    1384             : 
    1385             : /* {{{ proto void SoapServer::addFunction(mixed functions)
    1386             :    Adds one or several functions those will handle SOAP requests */
    1387         141 : PHP_METHOD(SoapServer, addFunction)
    1388             : {
    1389             :         soapServicePtr service;
    1390             :         zval *function_name, *function_copy;
    1391             :         HashPosition pos;
    1392             : 
    1393         141 :         SOAP_SERVER_BEGIN_CODE();
    1394             : 
    1395         141 :         FETCH_THIS_SERVICE(service);
    1396             : 
    1397         141 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &function_name) == FAILURE) {
    1398           0 :                 return;
    1399             :         }
    1400             : 
    1401             :         /* TODO: could use zend_is_callable here */
    1402             : 
    1403         141 :         if (function_name->type == IS_ARRAY) {
    1404           3 :                 if (service->type == SOAP_FUNCTIONS) {
    1405             :                         zval **tmp_function, *function_copy;
    1406             : 
    1407           3 :                         if (service->soap_functions.ft == NULL) {
    1408           0 :                                 service->soap_functions.functions_all = FALSE;
    1409           0 :                                 service->soap_functions.ft = emalloc(sizeof(HashTable));
    1410           0 :                                 zend_hash_init(service->soap_functions.ft, zend_hash_num_elements(Z_ARRVAL_P(function_name)), NULL, ZVAL_PTR_DTOR, 0);
    1411             :                         }
    1412             : 
    1413           3 :                         zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(function_name), &pos);
    1414          12 :                         while (zend_hash_get_current_data_ex(Z_ARRVAL_P(function_name), (void **)&tmp_function, &pos) != FAILURE) {
    1415             :                                 char *key;
    1416             :                                 int   key_len;
    1417             :                                 zend_function *f;
    1418             : 
    1419           6 :                                 if (Z_TYPE_PP(tmp_function) != IS_STRING) {
    1420           0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to add a function that isn't a string");
    1421           0 :                                         return;
    1422             :                                 }
    1423             : 
    1424           6 :                                 key_len = Z_STRLEN_PP(tmp_function);
    1425           6 :                                 key = emalloc(key_len + 1);
    1426           6 :                                 zend_str_tolower_copy(key, Z_STRVAL_PP(tmp_function), key_len);
    1427             : 
    1428           6 :                                 if (zend_hash_find(EG(function_table), key, key_len+1, (void**)&f) == FAILURE) {
    1429           0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to add a non existent function '%s'", Z_STRVAL_PP(tmp_function));
    1430           0 :                                         return;
    1431             :                                 }
    1432             : 
    1433           6 :                                 MAKE_STD_ZVAL(function_copy);
    1434           6 :                                 ZVAL_STRING(function_copy, f->common.function_name, 1);
    1435           6 :                                 zend_hash_update(service->soap_functions.ft, key, key_len+1, &function_copy, sizeof(zval *), NULL);
    1436             : 
    1437           6 :                                 efree(key);
    1438           6 :                                 zend_hash_move_forward_ex(Z_ARRVAL_P(function_name), &pos);
    1439             :                         }
    1440             :                 }
    1441         138 :         } else if (function_name->type == IS_STRING) {
    1442             :                 char *key;
    1443             :                 int   key_len;
    1444             :                 zend_function *f;
    1445             : 
    1446         137 :                 key_len = Z_STRLEN_P(function_name);
    1447         137 :                 key = emalloc(key_len + 1);
    1448         137 :                 zend_str_tolower_copy(key, Z_STRVAL_P(function_name), key_len);
    1449             : 
    1450         137 :                 if (zend_hash_find(EG(function_table), key, key_len+1, (void**)&f) == FAILURE) {
    1451           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Tried to add a non existent function '%s'", Z_STRVAL_P(function_name));
    1452           0 :                         return;
    1453             :                 }
    1454         137 :                 if (service->soap_functions.ft == NULL) {
    1455           0 :                         service->soap_functions.functions_all = FALSE;
    1456           0 :                         service->soap_functions.ft = emalloc(sizeof(HashTable));
    1457           0 :                         zend_hash_init(service->soap_functions.ft, 0, NULL, ZVAL_PTR_DTOR, 0);
    1458             :                 }
    1459             : 
    1460         137 :                 MAKE_STD_ZVAL(function_copy);
    1461         137 :                 ZVAL_STRING(function_copy, f->common.function_name, 1);
    1462         137 :                 zend_hash_update(service->soap_functions.ft, key, key_len+1, &function_copy, sizeof(zval *), NULL);
    1463         137 :                 efree(key);
    1464           1 :         } else if (function_name->type == IS_LONG) {
    1465           1 :                 if (Z_LVAL_P(function_name) == SOAP_FUNCTIONS_ALL) {
    1466           1 :                         if (service->soap_functions.ft != NULL) {
    1467           1 :                                 zend_hash_destroy(service->soap_functions.ft);
    1468           1 :                                 efree(service->soap_functions.ft);
    1469           1 :                                 service->soap_functions.ft = NULL;
    1470             :                         }
    1471           1 :                         service->soap_functions.functions_all = TRUE;
    1472             :                 } else {
    1473           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value passed");
    1474           0 :                         return;
    1475             :                 }
    1476             :         }
    1477             : 
    1478         141 :         SOAP_SERVER_END_CODE();
    1479             : }
    1480             : /* }}} */
    1481             : 
    1482             : 
    1483             : /* {{{ proto void SoapServer::handle ( [string soap_request])
    1484             :    Handles a SOAP request */
    1485         475 : PHP_METHOD(SoapServer, handle)
    1486             : {
    1487             :         int soap_version, old_soap_version;
    1488         475 :         sdlPtr old_sdl = NULL;
    1489             :         soapServicePtr service;
    1490         475 :         xmlDocPtr doc_request=NULL, doc_return;
    1491             :         zval function_name, **params, *soap_obj, *retval;
    1492             :         char *fn_name, cont_len[30];
    1493         475 :         int num_params = 0, size, i, call_status = 0;
    1494             :         xmlChar *buf;
    1495             :         HashTable *function_table;
    1496         475 :         soapHeader *soap_headers = NULL;
    1497             :         sdlFunctionPtr function;
    1498         475 :         char *arg = NULL;
    1499         475 :         int arg_len = 0;
    1500             :         xmlCharEncodingHandlerPtr old_encoding;
    1501             :         HashTable *old_class_map, *old_typemap;
    1502             :         int old_features;
    1503             : 
    1504         475 :         SOAP_SERVER_BEGIN_CODE();
    1505             : 
    1506         475 :         FETCH_THIS_SERVICE(service);
    1507         475 :         SOAP_GLOBAL(soap_version) = service->version;
    1508             :         
    1509         475 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &arg, &arg_len) == FAILURE) {
    1510           0 :                 return;
    1511             :         }
    1512             : 
    1513         484 :         if (SG(request_info).request_method &&
    1514           5 :             strcmp(SG(request_info).request_method, "GET") == 0 &&
    1515           2 :             SG(request_info).query_string &&
    1516           2 :             stricmp(SG(request_info).query_string, "wsdl") == 0) {
    1517             : 
    1518           2 :                 if (service->sdl) {
    1519             : /*
    1520             :                         char *hdr = emalloc(sizeof("Location: ")+strlen(service->sdl->source));
    1521             :                         strcpy(hdr,"Location: ");
    1522             :                         strcat(hdr,service->sdl->source);
    1523             :                         sapi_add_header(hdr, sizeof("Location: ")+strlen(service->sdl->source)-1, 1);
    1524             :                         efree(hdr);
    1525             : */
    1526             :                         zval readfile, readfile_ret, *param;
    1527             : 
    1528           1 :                         INIT_ZVAL(readfile);
    1529           1 :                         INIT_ZVAL(readfile_ret);
    1530           1 :                         MAKE_STD_ZVAL(param);
    1531             : 
    1532           1 :                         sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1);
    1533           1 :                         ZVAL_STRING(param, service->sdl->source, 1);
    1534           1 :                         ZVAL_STRING(&readfile, "readfile", 1);
    1535           1 :                         if (call_user_function(EG(function_table), NULL, &readfile, &readfile_ret, 1, &param  TSRMLS_CC) == FAILURE) {
    1536           0 :                                 soap_server_fault("Server", "Couldn't find WSDL", NULL, NULL, NULL TSRMLS_CC);
    1537             :                         }
    1538             : 
    1539           1 :                         zval_ptr_dtor(&param);
    1540             :                         zval_dtor(&readfile);
    1541             :                         zval_dtor(&readfile_ret);
    1542             : 
    1543           1 :                         SOAP_SERVER_END_CODE();
    1544           1 :                         return;
    1545             :                 } else {
    1546           1 :                         soap_server_fault("Server", "WSDL generation is not supported yet", NULL, NULL, NULL TSRMLS_CC);
    1547             : /*
    1548             :                         sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8"), 1);
    1549             :                         PUTS("<?xml version=\"1.0\" ?>\n<definitions\n");
    1550             :                         PUTS("    xmlns=\"http://schemas.xmlsoap.org/wsdl/\"\n");
    1551             :                         PUTS("    targetNamespace=\"");
    1552             :                         PUTS(service->uri);
    1553             :                         PUTS("\">\n");
    1554             :                         PUTS("</definitions>");
    1555             : */
    1556           0 :                         SOAP_SERVER_END_CODE();
    1557           0 :                         return;
    1558             :                 }
    1559             :         }
    1560             : 
    1561         473 :         ALLOC_INIT_ZVAL(retval);
    1562             : 
    1563         473 :         if (php_output_start_default(TSRMLS_C) != SUCCESS) {
    1564           0 :                 php_error_docref(NULL TSRMLS_CC, E_ERROR,"ob_start failed");
    1565             :         }
    1566             : 
    1567         473 :         if (ZEND_NUM_ARGS() == 0) {
    1568           3 :                 if (SG(request_info).raw_post_data) {
    1569           3 :                         char *post_data = SG(request_info).raw_post_data;
    1570           3 :                         int post_data_length = SG(request_info).raw_post_data_length;
    1571             :                         zval **server_vars, **encoding;
    1572             : 
    1573           3 :                         zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC);
    1574          13 :                         if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &server_vars) == SUCCESS &&
    1575           3 :                             Z_TYPE_PP(server_vars) == IS_ARRAY &&
    1576           3 :                             zend_hash_find(Z_ARRVAL_PP(server_vars), "HTTP_CONTENT_ENCODING", sizeof("HTTP_CONTENT_ENCODING"), (void **) &encoding)==SUCCESS &&
    1577           2 :                             Z_TYPE_PP(encoding) == IS_STRING) {
    1578             :                                 zval func;
    1579             :                                 zval retval;
    1580             :                                 zval param;
    1581             :                                 zval *params[1];
    1582             : 
    1583           5 :                                 if ((strcmp(Z_STRVAL_PP(encoding),"gzip") == 0 ||
    1584           1 :                                      strcmp(Z_STRVAL_PP(encoding),"x-gzip") == 0) &&
    1585           1 :                                     zend_hash_exists(EG(function_table), "gzinflate", sizeof("gzinflate"))) {
    1586           1 :                                         ZVAL_STRING(&func, "gzinflate", 0);
    1587           1 :                                         params[0] = &param;
    1588           1 :                                         ZVAL_STRINGL(params[0], post_data+10, post_data_length-10, 0);
    1589           1 :                                         INIT_PZVAL(params[0]);
    1590           3 :                                 } else if (strcmp(Z_STRVAL_PP(encoding),"deflate") == 0 &&
    1591           1 :                            zend_hash_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress"))) {
    1592           1 :                                         ZVAL_STRING(&func, "gzuncompress", 0);
    1593           1 :                                         params[0] = &param;
    1594           1 :                                         ZVAL_STRINGL(params[0], post_data, post_data_length, 0);
    1595           1 :                                         INIT_PZVAL(params[0]);
    1596             :                                 } else {
    1597           0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING,"Request is compressed with unknown compression '%s'",Z_STRVAL_PP(encoding));
    1598           0 :                                         return;
    1599             :                                 }
    1600           6 :                                 if (call_user_function(CG(function_table), (zval**)NULL, &func, &retval, 1, params TSRMLS_CC) == SUCCESS &&
    1601           2 :                                     Z_TYPE(retval) == IS_STRING) {
    1602           2 :                                         doc_request = soap_xmlParseMemory(Z_STRVAL(retval),Z_STRLEN(retval));
    1603             :                                         zval_dtor(&retval);
    1604             :                                 } else {
    1605           0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING,"Can't uncompress compressed request");
    1606           0 :                                         return;
    1607             :                                 }
    1608             :                         } else {
    1609           1 :                                 doc_request = soap_xmlParseMemory(post_data, post_data_length);
    1610             :                         }
    1611             :                 } else {
    1612           0 :                         zval_ptr_dtor(&retval);
    1613           0 :                         return;
    1614             :                 }
    1615             :         } else {
    1616         470 :                 doc_request = soap_xmlParseMemory(arg,arg_len);
    1617             :         }
    1618             : 
    1619         473 :         if (doc_request == NULL) {
    1620           0 :                 soap_server_fault("Client", "Bad Request", NULL, NULL, NULL TSRMLS_CC);
    1621             :         }
    1622         473 :         if (xmlGetIntSubset(doc_request) != NULL) {
    1623           3 :                 xmlNodePtr env = get_node(doc_request->children,"Envelope");
    1624           3 :                 if (env && env->ns) {
    1625           3 :                         if (strcmp((char*)env->ns->href, SOAP_1_1_ENV_NAMESPACE) == 0) {
    1626           0 :                                 SOAP_GLOBAL(soap_version) = SOAP_1_1;
    1627           3 :                         } else if (strcmp((char*)env->ns->href,SOAP_1_2_ENV_NAMESPACE) == 0) {
    1628           3 :                                 SOAP_GLOBAL(soap_version) = SOAP_1_2;
    1629             :                         }
    1630             :                 }
    1631           3 :                 xmlFreeDoc(doc_request);
    1632           3 :                 soap_server_fault("Server", "DTD are not supported by SOAP", NULL, NULL, NULL TSRMLS_CC);
    1633             :         }
    1634             : 
    1635         470 :         old_sdl = SOAP_GLOBAL(sdl);
    1636         470 :         SOAP_GLOBAL(sdl) = service->sdl;
    1637         470 :         old_encoding = SOAP_GLOBAL(encoding);
    1638         470 :         SOAP_GLOBAL(encoding) = service->encoding;
    1639         470 :         old_class_map = SOAP_GLOBAL(class_map);
    1640         470 :         SOAP_GLOBAL(class_map) = service->class_map;
    1641         470 :         old_typemap = SOAP_GLOBAL(typemap);
    1642         470 :         SOAP_GLOBAL(typemap) = service->typemap;
    1643         470 :         old_features = SOAP_GLOBAL(features);
    1644         470 :         SOAP_GLOBAL(features) = service->features;
    1645         470 :         old_soap_version = SOAP_GLOBAL(soap_version);
    1646         470 :         function = deserialize_function_call(service->sdl, doc_request, service->actor, &function_name, &num_params, &params, &soap_version, &soap_headers TSRMLS_CC);
    1647         452 :         xmlFreeDoc(doc_request);
    1648             : 
    1649         452 :         if (EG(exception)) {
    1650           1 :                 php_output_discard(TSRMLS_C);
    1651           2 :                 if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
    1652           1 :                     instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
    1653           1 :                         soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
    1654             :                 }
    1655           1 :                 goto fail;
    1656             :         }
    1657             : 
    1658         451 :         service->soap_headers_ptr = &soap_headers;
    1659             : 
    1660         451 :         soap_obj = NULL;
    1661         451 :         if (service->type == SOAP_OBJECT) {
    1662           3 :                 soap_obj = service->soap_object;
    1663           3 :                 function_table = &((Z_OBJCE_P(soap_obj))->function_table);
    1664         448 :         } else if (service->type == SOAP_CLASS) {
    1665             : #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
    1666             :                 /* If persistent then set soap_obj from from the previous created session (if available) */
    1667         292 :                 if (service->soap_class.persistance == SOAP_PERSISTENCE_SESSION) {
    1668             :                         zval **tmp_soap;
    1669             : 
    1670           2 :                         if (PS(session_status) != php_session_active &&
    1671           0 :                             PS(session_status) != php_session_disabled) {
    1672           0 :                                 php_session_start(TSRMLS_C);
    1673             :                         }
    1674             : 
    1675             :                         /* Find the soap object and assign */
    1676           4 :                         if (zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), "_bogus_session_name", sizeof("_bogus_session_name"), (void **) &tmp_soap) == SUCCESS &&
    1677           1 :                             Z_TYPE_PP(tmp_soap) == IS_OBJECT &&
    1678           1 :                             Z_OBJCE_PP(tmp_soap) == service->soap_class.ce) {
    1679           1 :                                 soap_obj = *tmp_soap;
    1680             :                         }
    1681             :                 }
    1682             : #endif
    1683             :                 /* If new session or something weird happned */
    1684         292 :                 if (soap_obj == NULL) {
    1685             :                         zval *tmp_soap;
    1686             : 
    1687         291 :                         MAKE_STD_ZVAL(tmp_soap);
    1688         291 :                         object_init_ex(tmp_soap, service->soap_class.ce);
    1689             : 
    1690             :                         /* Call constructor */
    1691         291 :                         if (zend_hash_exists(&Z_OBJCE_P(tmp_soap)->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME))) {
    1692             :                                 zval c_ret, constructor;
    1693             : 
    1694           0 :                                 INIT_ZVAL(c_ret);
    1695           0 :                                 INIT_ZVAL(constructor);
    1696             : 
    1697           0 :                                 ZVAL_STRING(&constructor, ZEND_CONSTRUCTOR_FUNC_NAME, 1);
    1698           0 :                                 if (call_user_function(NULL, &tmp_soap, &constructor, &c_ret, service->soap_class.argc, service->soap_class.argv TSRMLS_CC) == FAILURE) {
    1699           0 :                                         php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error calling constructor");
    1700             :                                 }
    1701           0 :                                 if (EG(exception)) {
    1702           0 :                                         php_output_discard(TSRMLS_C);
    1703           0 :                                         if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
    1704           0 :                                             instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
    1705           0 :                                                 soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
    1706             :                                         }
    1707             :                                         zval_dtor(&constructor);
    1708             :                                         zval_dtor(&c_ret);
    1709           0 :                                         zval_ptr_dtor(&tmp_soap);
    1710           0 :                                         goto fail;
    1711             :                                 }
    1712             :                                 zval_dtor(&constructor);
    1713             :                                 zval_dtor(&c_ret);
    1714             :                         } else {
    1715         291 :                                 int class_name_len = strlen(service->soap_class.ce->name);
    1716         291 :                                 char *class_name = emalloc(class_name_len+1);
    1717             : 
    1718         291 :                                 memcpy(class_name, service->soap_class.ce->name,class_name_len+1);
    1719         291 :                                 if (zend_hash_exists(&Z_OBJCE_P(tmp_soap)->function_table, php_strtolower(class_name, class_name_len), class_name_len+1)) {
    1720             :                                         zval c_ret, constructor;
    1721             : 
    1722           1 :                                         INIT_ZVAL(c_ret);
    1723           1 :                                         INIT_ZVAL(constructor);
    1724             : 
    1725           1 :                                         ZVAL_STRING(&constructor, service->soap_class.ce->name, 1);
    1726           1 :                                         if (call_user_function(NULL, &tmp_soap, &constructor, &c_ret, service->soap_class.argc, service->soap_class.argv TSRMLS_CC) == FAILURE) {
    1727           0 :                                                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error calling constructor");
    1728             :                                         }
    1729             : 
    1730           1 :                                         if (EG(exception)) {
    1731           0 :                                                 php_output_discard(TSRMLS_C);
    1732           0 :                                                 if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
    1733           0 :                                                     instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
    1734           0 :                                                         soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
    1735             :                                                 }
    1736             :                                                 zval_dtor(&constructor);
    1737             :                                                 zval_dtor(&c_ret);
    1738           0 :                                                 efree(class_name);
    1739           0 :                                                 zval_ptr_dtor(&tmp_soap);
    1740           0 :                                                 goto fail;
    1741             :                                         }
    1742             : 
    1743             :                                         zval_dtor(&constructor);
    1744             :                                         zval_dtor(&c_ret);
    1745             :                                 }
    1746         291 :                                 efree(class_name);
    1747             :                         }
    1748             : #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
    1749             :                         /* If session then update session hash with new object */
    1750         291 :                         if (service->soap_class.persistance == SOAP_PERSISTENCE_SESSION) {
    1751             :                                 zval **tmp_soap_pp;
    1752           1 :                                 if (zend_hash_update(Z_ARRVAL_P(PS(http_session_vars)), "_bogus_session_name", sizeof("_bogus_session_name"), &tmp_soap, sizeof(zval *), (void **)&tmp_soap_pp) == SUCCESS) {
    1753           1 :                                         soap_obj = *tmp_soap_pp;
    1754             :                                 }
    1755             :                         } else {
    1756         290 :                                 soap_obj = tmp_soap;
    1757             :                         }
    1758             : #else
    1759             :                         soap_obj = tmp_soap;
    1760             : #endif
    1761             : 
    1762             :                 }
    1763         292 :                 function_table = &((Z_OBJCE_P(soap_obj))->function_table);
    1764             :         } else {
    1765         156 :                 if (service->soap_functions.functions_all == TRUE) {
    1766           1 :                         function_table = EG(function_table);
    1767             :                 } else {
    1768         155 :                         function_table = service->soap_functions.ft;
    1769             :                 }
    1770             :         }
    1771             : 
    1772         451 :         doc_return = NULL;
    1773             : 
    1774             :         /* Process soap headers */
    1775         451 :         if (soap_headers != NULL) {
    1776          38 :                 soapHeader *header = soap_headers;
    1777         112 :                 while (header != NULL) {
    1778          42 :                         soapHeader *h = header;
    1779             : 
    1780          42 :                         header = header->next;
    1781             : #if 0
    1782             :                         if (service->sdl && !h->function && !h->hdr) {
    1783             :                                 if (h->mustUnderstand) {
    1784             :                                         soap_server_fault("MustUnderstand","Header not understood", NULL, NULL, NULL TSRMLS_CC);
    1785             :                                 } else {
    1786             :                                         continue;
    1787             :                                 }
    1788             :                         }
    1789             : #endif
    1790          42 :                         fn_name = estrndup(Z_STRVAL(h->function_name),Z_STRLEN(h->function_name));
    1791          97 :                         if (zend_hash_exists(function_table, php_strtolower(fn_name, Z_STRLEN(h->function_name)), Z_STRLEN(h->function_name) + 1) ||
    1792          14 :                             ((service->type == SOAP_CLASS || service->type == SOAP_OBJECT) &&
    1793          14 :                              zend_hash_exists(function_table, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)))) {
    1794          56 :                                 if (service->type == SOAP_CLASS || service->type == SOAP_OBJECT) {
    1795          28 :                                         call_status = call_user_function(NULL, &soap_obj, &h->function_name, &h->retval, h->num_params, h->parameters TSRMLS_CC);
    1796             :                                 } else {
    1797           0 :                                         call_status = call_user_function(EG(function_table), NULL, &h->function_name, &h->retval, h->num_params, h->parameters TSRMLS_CC);
    1798             :                                 }
    1799          28 :                                 if (call_status != SUCCESS) {
    1800           0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function '%s' call failed", Z_STRVAL(h->function_name));
    1801           0 :                                         return;
    1802             :                                 }
    1803          36 :                                 if (Z_TYPE(h->retval) == IS_OBJECT &&
    1804           8 :                                     instanceof_function(Z_OBJCE(h->retval), soap_fault_class_entry TSRMLS_CC)) {
    1805           1 :                                         zval *headerfault = NULL, **tmp;
    1806             : 
    1807           2 :                                         if (zend_hash_find(Z_OBJPROP(h->retval), "headerfault", sizeof("headerfault"), (void**)&tmp) == SUCCESS &&
    1808           1 :                                             Z_TYPE_PP(tmp) != IS_NULL) {
    1809           1 :                                                 headerfault = *tmp;
    1810             :                                         }
    1811           1 :                                         php_output_discard(TSRMLS_C);
    1812           1 :                                         soap_server_fault_ex(function, &h->retval, h TSRMLS_CC);
    1813           1 :                                         efree(fn_name);
    1814           1 :                                         if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(&soap_obj);}
    1815           1 :                                         goto fail;
    1816          27 :                                 } else if (EG(exception)) {
    1817           0 :                                         php_output_discard(TSRMLS_C);
    1818           0 :                                         if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
    1819           0 :                                             instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
    1820           0 :                                                 zval *headerfault = NULL, **tmp;
    1821             : 
    1822           0 :                                                 if (zend_hash_find(Z_OBJPROP_P(EG(exception)), "headerfault", sizeof("headerfault"), (void**)&tmp) == SUCCESS &&
    1823           0 :                                                     Z_TYPE_PP(tmp) != IS_NULL) {
    1824           0 :                                                         headerfault = *tmp;
    1825             :                                                 }
    1826           0 :                                                 soap_server_fault_ex(function, EG(exception), h TSRMLS_CC);
    1827             :                                         }
    1828           0 :                                         efree(fn_name);
    1829           0 :                                         if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(&soap_obj);}
    1830           0 :                                         goto fail;
    1831             :                                 }
    1832          14 :                         } else if (h->mustUnderstand) {
    1833           5 :                                 soap_server_fault("MustUnderstand","Header not understood", NULL, NULL, NULL TSRMLS_CC);
    1834             :                         }
    1835          36 :                         efree(fn_name);
    1836             :                 }
    1837             :         }
    1838             : 
    1839         445 :         fn_name = estrndup(Z_STRVAL(function_name),Z_STRLEN(function_name));
    1840         887 :         if (zend_hash_exists(function_table, php_strtolower(fn_name, Z_STRLEN(function_name)), Z_STRLEN(function_name) + 1) ||
    1841           3 :             ((service->type == SOAP_CLASS || service->type == SOAP_OBJECT) &&
    1842           2 :              zend_hash_exists(function_table, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)))) {
    1843         734 :                 if (service->type == SOAP_CLASS || service->type == SOAP_OBJECT) {
    1844         289 :                         call_status = call_user_function(NULL, &soap_obj, &function_name, retval, num_params, params TSRMLS_CC);
    1845         289 :                         if (service->type == SOAP_CLASS) {
    1846             : #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
    1847         286 :                                 if (service->soap_class.persistance != SOAP_PERSISTENCE_SESSION) {
    1848         284 :                                         zval_ptr_dtor(&soap_obj);
    1849         284 :                                         soap_obj = NULL;
    1850             :                                 }
    1851             : #else
    1852             :                                 zval_ptr_dtor(&soap_obj);
    1853             :                                 soap_obj = NULL;
    1854             : #endif
    1855             :                         }
    1856             :                 } else {
    1857         156 :                         call_status = call_user_function(EG(function_table), NULL, &function_name, retval, num_params, params TSRMLS_CC);
    1858             :                 }
    1859             :         } else {
    1860           0 :                 php_error(E_ERROR, "Function '%s' doesn't exist", Z_STRVAL(function_name));
    1861             :         }
    1862         437 :         efree(fn_name);
    1863             : 
    1864         437 :         if (EG(exception)) {
    1865           4 :                 php_output_discard(TSRMLS_C);
    1866           8 :                 if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
    1867           4 :                     instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
    1868           3 :                         soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
    1869             :                 }
    1870           4 :                 if (service->type == SOAP_CLASS) {
    1871             : #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
    1872           1 :                         if (soap_obj && service->soap_class.persistance != SOAP_PERSISTENCE_SESSION) {
    1873             : #else
    1874             :                         if (soap_obj) {
    1875             : #endif
    1876           0 :                           zval_ptr_dtor(&soap_obj);
    1877             :                         }
    1878             :                 }
    1879           4 :                 goto fail;
    1880             :         }
    1881             : 
    1882         433 :         if (call_status == SUCCESS) {
    1883             :                 char *response_name;
    1884             : 
    1885         548 :                 if (Z_TYPE_P(retval) == IS_OBJECT &&
    1886         115 :                     instanceof_function(Z_OBJCE_P(retval), soap_fault_class_entry TSRMLS_CC)) {
    1887          57 :                         php_output_discard(TSRMLS_C);
    1888          57 :                         soap_server_fault_ex(function, retval, NULL TSRMLS_CC);
    1889          57 :                         goto fail;
    1890             :                 }
    1891             : 
    1892         621 :                 if (function && function->responseName) {
    1893         245 :                         response_name = estrdup(function->responseName);
    1894             :                 } else {
    1895         131 :                         response_name = emalloc(Z_STRLEN(function_name) + sizeof("Response"));
    1896         131 :                         memcpy(response_name,Z_STRVAL(function_name),Z_STRLEN(function_name));
    1897         131 :                         memcpy(response_name+Z_STRLEN(function_name),"Response",sizeof("Response"));
    1898             :                 }
    1899         376 :                 doc_return = serialize_response_call(function, response_name, service->uri, retval, soap_headers, soap_version TSRMLS_CC);
    1900         375 :                 efree(response_name);
    1901             :         } else {
    1902           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function '%s' call failed", Z_STRVAL(function_name));
    1903           0 :                 return;
    1904             :         }
    1905             : 
    1906         375 :         if (EG(exception)) {
    1907           1 :                 php_output_discard(TSRMLS_C);
    1908           2 :                 if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
    1909           1 :                     instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
    1910           1 :                         soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
    1911             :                 }
    1912           1 :                 if (service->type == SOAP_CLASS) {
    1913             : #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
    1914           1 :                         if (soap_obj && service->soap_class.persistance != SOAP_PERSISTENCE_SESSION) {
    1915             : #else
    1916             :                         if (soap_obj) {
    1917             : #endif
    1918           0 :                           zval_ptr_dtor(&soap_obj);
    1919             :                         }
    1920             :                 }
    1921           1 :                 goto fail;
    1922             :         }
    1923             : 
    1924             :         /* Flush buffer */
    1925         374 :         php_output_discard(TSRMLS_C);
    1926             : 
    1927         374 :         if (doc_return) {
    1928             :                 /* xmlDocDumpMemoryEnc(doc_return, &buf, &size, XML_CHAR_ENCODING_UTF8); */
    1929         292 :                 xmlDocDumpMemory(doc_return, &buf, &size);
    1930             : 
    1931         292 :                 if (size == 0) {
    1932           0 :                         php_error_docref(NULL TSRMLS_CC, E_ERROR, "Dump memory failed");
    1933             :                 }       
    1934             : 
    1935         292 :                 if (soap_version == SOAP_1_2) {
    1936          50 :                         sapi_add_header("Content-Type: application/soap+xml; charset=utf-8", sizeof("Content-Type: application/soap+xml; charset=utf-8")-1, 1);
    1937             :                 } else {
    1938         242 :                         sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1);
    1939             :                 }
    1940             : 
    1941         292 :                 xmlFreeDoc(doc_return);
    1942             : 
    1943         292 :                 if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0)) {
    1944           0 :                         sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1);
    1945             :                 } else {
    1946         292 :                         snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size);
    1947         292 :                         sapi_add_header(cont_len, strlen(cont_len), 1);
    1948             :                 }
    1949         292 :                 php_write(buf, size TSRMLS_CC);
    1950         292 :                 xmlFree(buf);
    1951             :         } else {
    1952          82 :                 sapi_add_header("HTTP/1.1 202 Accepted", sizeof("HTTP/1.1 202 Accepted")-1, 1);
    1953          82 :                 sapi_add_header("Content-Length: 0", sizeof("Content-Length: 0")-1, 1);
    1954             :         }
    1955             : 
    1956             : fail:
    1957         438 :         SOAP_GLOBAL(soap_version) = old_soap_version;
    1958         438 :         SOAP_GLOBAL(encoding) = old_encoding;
    1959         438 :         SOAP_GLOBAL(sdl) = old_sdl;
    1960         438 :         SOAP_GLOBAL(class_map) = old_class_map;
    1961         438 :         SOAP_GLOBAL(typemap) = old_typemap;
    1962         438 :         SOAP_GLOBAL(features) = old_features;
    1963             : 
    1964             :         /* Free soap headers */
    1965         438 :         zval_ptr_dtor(&retval);
    1966         919 :         while (soap_headers != NULL) {
    1967          43 :                 soapHeader *h = soap_headers;
    1968             :                 int i;
    1969             : 
    1970          43 :                 soap_headers = soap_headers->next;
    1971          43 :                 if (h->parameters) {
    1972          37 :                         i = h->num_params;
    1973         112 :                         while (i > 0) {
    1974          38 :                                 zval_ptr_dtor(&h->parameters[--i]);
    1975             :                         }
    1976          37 :                         efree(h->parameters);
    1977             :                 }
    1978          43 :                 zval_dtor(&h->function_name);
    1979          43 :                 zval_dtor(&h->retval);
    1980          43 :                 efree(h);
    1981             :         }
    1982         438 :         service->soap_headers_ptr = NULL;
    1983             : 
    1984             :         /* Free Memory */
    1985         438 :         if (num_params > 0) {
    1986         814 :                 for (i = 0; i < num_params;i++) {
    1987         444 :                         zval_ptr_dtor(&params[i]);
    1988             :                 }
    1989         370 :                 efree(params);
    1990             :         }
    1991             :         zval_dtor(&function_name);
    1992             : 
    1993         438 :         SOAP_SERVER_END_CODE();
    1994             : }
    1995             : /* }}} */
    1996             : 
    1997             : 
    1998             : /* {{{ proto SoapServer::fault ( staring code, string string [, string actor [, mixed details [, string name]]] )
    1999             :    Issue SoapFault indicating an error */
    2000           2 : PHP_METHOD(SoapServer, fault)
    2001             : {
    2002           2 :         char *code, *string, *actor=NULL, *name=NULL;
    2003           2 :         int code_len, string_len, actor_len = 0, name_len = 0;
    2004           2 :         zval* details = NULL;
    2005             :         soapServicePtr service;
    2006             :         xmlCharEncodingHandlerPtr old_encoding;
    2007             : 
    2008           2 :         SOAP_SERVER_BEGIN_CODE();
    2009           2 :         FETCH_THIS_SERVICE(service);
    2010           2 :         old_encoding = SOAP_GLOBAL(encoding);
    2011           2 :         SOAP_GLOBAL(encoding) = service->encoding;
    2012             : 
    2013           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|szs",
    2014             :             &code, &code_len, &string, &string_len, &actor, &actor_len, &details,
    2015             :             &name, &name_len) == FAILURE) {
    2016           0 :                 return;
    2017             :         }
    2018             : 
    2019           2 :         soap_server_fault(code, string, actor, details, name TSRMLS_CC);
    2020             : 
    2021           0 :         SOAP_GLOBAL(encoding) = old_encoding;
    2022           0 :         SOAP_SERVER_END_CODE();
    2023             : }
    2024             : /* }}} */
    2025             : 
    2026           6 : PHP_METHOD(SoapServer, addSoapHeader)
    2027             : {
    2028             :         soapServicePtr service;
    2029             :         zval *fault;
    2030             :         soapHeader **p;
    2031             : 
    2032           6 :         SOAP_SERVER_BEGIN_CODE();
    2033             : 
    2034           6 :         FETCH_THIS_SERVICE(service);
    2035             : 
    2036           6 :         if (!service || !service->soap_headers_ptr) {
    2037           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The SoapServer::addSoapHeader function may be called only during SOAP request processing");
    2038           0 :                 return;
    2039             :         }
    2040             : 
    2041           6 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &fault, soap_header_class_entry) == FAILURE) {
    2042           0 :                 return;
    2043             :         }
    2044             : 
    2045           6 :         p = service->soap_headers_ptr;
    2046          15 :         while (*p != NULL) {
    2047           3 :                 p = &(*p)->next;
    2048             :         }
    2049           6 :         *p = emalloc(sizeof(soapHeader));
    2050           6 :         memset(*p, 0, sizeof(soapHeader));
    2051           6 :         ZVAL_NULL(&(*p)->function_name);
    2052           6 :         (*p)->retval = *fault;
    2053           6 :         zval_copy_ctor(&(*p)->retval);
    2054             : 
    2055           6 :         SOAP_SERVER_END_CODE();
    2056             : }
    2057             : 
    2058          96 : static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeader *hdr TSRMLS_DC)
    2059             : {
    2060             :         int soap_version;
    2061             :         xmlChar *buf;
    2062             :         char cont_len[30];
    2063             :         int size;
    2064             :         xmlDocPtr doc_return;
    2065             :         zval **agent_name;
    2066          96 :         int use_http_error_status = 1;
    2067             : 
    2068          96 :         soap_version = SOAP_GLOBAL(soap_version);
    2069             : 
    2070          96 :         doc_return = serialize_response_call(function, NULL, NULL, fault, hdr, soap_version TSRMLS_CC);
    2071             : 
    2072          96 :         xmlDocDumpMemory(doc_return, &buf, &size);
    2073             : 
    2074          96 :         zend_is_auto_global("_SERVER", sizeof("_SERVER") - 1 TSRMLS_CC);
    2075         192 :         if (PG(http_globals)[TRACK_VARS_SERVER] &&
    2076          96 :                 zend_hash_find(PG(http_globals)[TRACK_VARS_SERVER]->value.ht, "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT"), (void **) &agent_name) == SUCCESS &&
    2077           0 :                 Z_TYPE_PP(agent_name) == IS_STRING) {
    2078           0 :                 if (strncmp(Z_STRVAL_PP(agent_name), "Shockwave Flash", sizeof("Shockwave Flash")-1) == 0) {
    2079           0 :                         use_http_error_status = 0;
    2080             :                 }
    2081             :         }
    2082             :         /*
    2083             :            Want to return HTTP 500 but apache wants to over write
    2084             :            our fault code with their own handling... Figure this out later
    2085             :         */
    2086          96 :         if (use_http_error_status) {
    2087          96 :                 sapi_add_header("HTTP/1.1 500 Internal Service Error", sizeof("HTTP/1.1 500 Internal Service Error")-1, 1);
    2088             :         }
    2089          96 :         if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0)) {
    2090           0 :                 sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1);
    2091             :         } else {
    2092          96 :                 snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size);
    2093          96 :                 sapi_add_header(cont_len, strlen(cont_len), 1);
    2094             :         }
    2095          96 :         if (soap_version == SOAP_1_2) {
    2096          25 :                 sapi_add_header("Content-Type: application/soap+xml; charset=utf-8", sizeof("Content-Type: application/soap+xml; charset=utf-8")-1, 1);
    2097             :         } else {
    2098          71 :                 sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1);
    2099             :         }
    2100             : 
    2101          96 :         php_write(buf, size TSRMLS_CC);
    2102             : 
    2103          96 :         xmlFreeDoc(doc_return);
    2104          96 :         xmlFree(buf);
    2105          96 :         zend_clear_exception(TSRMLS_C);
    2106          96 : }
    2107             : 
    2108          23 : static void soap_server_fault(char* code, char* string, char *actor, zval* details, char* name TSRMLS_DC)
    2109             : {
    2110             :         zval ret;
    2111             : 
    2112          23 :         INIT_ZVAL(ret);
    2113             : 
    2114          23 :         set_soap_fault(&ret, NULL, code, string, actor, details, name TSRMLS_CC);
    2115             :         /* TODO: Which function */
    2116          23 :         soap_server_fault_ex(NULL, &ret, NULL TSRMLS_CC);
    2117          23 :         zend_bailout();
    2118           0 : }
    2119             : 
    2120      321653 : static void soap_error_handler(int error_num, const char *error_filename, const uint error_lineno, const char *format, va_list args)
    2121             : {
    2122             :         zend_bool _old_in_compilation, _old_in_execution;
    2123             :         zend_execute_data *_old_current_execute_data;
    2124             :         int _old_http_response_code;
    2125             :         char *_old_http_status_line;
    2126             :         TSRMLS_FETCH();
    2127             : 
    2128      321653 :         _old_in_compilation = CG(in_compilation);
    2129      321653 :         _old_in_execution = EG(in_execution);
    2130      321653 :         _old_current_execute_data = EG(current_execute_data);
    2131      321653 :         _old_http_response_code = SG(sapi_headers).http_response_code;
    2132      321653 :         _old_http_status_line = SG(sapi_headers).http_status_line;
    2133             : 
    2134      321653 :         if (!SOAP_GLOBAL(use_soap_error_handler) || !EG(objects_store).object_buckets) {
    2135      321079 :                 call_old_error_handler(error_num, error_filename, error_lineno, format, args);
    2136      320414 :                 return;
    2137             :         }
    2138             : 
    2139        1726 :         if (SOAP_GLOBAL(error_object) &&
    2140         574 :             Z_TYPE_P(SOAP_GLOBAL(error_object)) == IS_OBJECT &&
    2141         574 :             instanceof_function(Z_OBJCE_P(SOAP_GLOBAL(error_object)), soap_class_entry TSRMLS_CC)) {
    2142             :                 zval **tmp;
    2143          11 :                 int use_exceptions = 0;
    2144             : 
    2145          15 :                 if (zend_hash_find(Z_OBJPROP_P(SOAP_GLOBAL(error_object)), "_exceptions", sizeof("_exceptions"), (void **) &tmp) != SUCCESS ||
    2146           4 :                      Z_TYPE_PP(tmp) != IS_BOOL || Z_LVAL_PP(tmp) != 0) {
    2147           9 :                      use_exceptions = 1;
    2148             :                 }
    2149             : 
    2150          11 :                 if ((error_num == E_USER_ERROR || 
    2151             :                      error_num == E_COMPILE_ERROR || 
    2152             :                      error_num == E_CORE_ERROR ||
    2153             :                      error_num == E_ERROR || 
    2154             :                      error_num == E_PARSE) &&
    2155             :                     use_exceptions) {
    2156             :                         zval *fault, *exception;
    2157           5 :                         char* code = SOAP_GLOBAL(error_code);
    2158             :                         char buffer[1024];
    2159             :                         int buffer_len;
    2160             :                         zval outbuf, outbuflen;
    2161             : #ifdef va_copy
    2162             :                         va_list argcopy;
    2163             : #endif
    2164             :                         zend_object_store_bucket *old_objects;
    2165           5 :                         int old = PG(display_errors);
    2166             : 
    2167           5 :                         INIT_ZVAL(outbuf);
    2168           5 :                         INIT_ZVAL(outbuflen);
    2169             : #ifdef va_copy
    2170           5 :                         va_copy(argcopy, args);
    2171           5 :                         buffer_len = vslprintf(buffer, sizeof(buffer)-1, format, argcopy);
    2172           5 :                         va_end(argcopy);
    2173             : #else
    2174             :                         buffer_len = vslprintf(buffer, sizeof(buffer)-1, format, args);
    2175             : #endif
    2176           5 :                         buffer[sizeof(buffer)-1]=0;
    2177           5 :                         if (buffer_len > sizeof(buffer) - 1 || buffer_len < 0) {
    2178           0 :                                 buffer_len = sizeof(buffer) - 1;
    2179             :                         }
    2180             : 
    2181           5 :                         if (code == NULL) {
    2182           0 :                                 code = "Client";
    2183             :                         }
    2184           5 :                         fault = add_soap_fault(SOAP_GLOBAL(error_object), code, buffer, NULL, NULL TSRMLS_CC);
    2185           5 :                         MAKE_STD_ZVAL(exception);
    2186           5 :                         MAKE_COPY_ZVAL(&fault, exception);
    2187           5 :                         zend_throw_exception_object(exception TSRMLS_CC);
    2188             : 
    2189           5 :                         old_objects = EG(objects_store).object_buckets;
    2190           5 :                         EG(objects_store).object_buckets = NULL;
    2191           5 :                         PG(display_errors) = 0;
    2192           5 :                         SG(sapi_headers).http_status_line = NULL;
    2193           5 :                         zend_try {
    2194           5 :                                 call_old_error_handler(error_num, error_filename, error_lineno, format, args);
    2195           5 :                         } zend_catch {
    2196           5 :                                 CG(in_compilation) = _old_in_compilation;
    2197           5 :                                 EG(in_execution) = _old_in_execution;
    2198           5 :                                 EG(current_execute_data) = _old_current_execute_data;
    2199           5 :                                 if (SG(sapi_headers).http_status_line) {
    2200           0 :                                         efree(SG(sapi_headers).http_status_line);
    2201             :                                 }
    2202           5 :                                 SG(sapi_headers).http_status_line = _old_http_status_line;
    2203           5 :                                 SG(sapi_headers).http_response_code = _old_http_response_code;
    2204           5 :                         } zend_end_try();
    2205           5 :                         EG(objects_store).object_buckets = old_objects;
    2206           5 :                         PG(display_errors) = old;
    2207           5 :                         zend_bailout();
    2208          14 :                 } else if (!use_exceptions ||
    2209           4 :                            !SOAP_GLOBAL(error_code) ||
    2210           4 :                            strcmp(SOAP_GLOBAL(error_code),"WSDL") != 0) {
    2211             :                         /* Ignore libxml warnings during WSDL parsing */
    2212           4 :                         call_old_error_handler(error_num, error_filename, error_lineno, format, args);
    2213             :                 }
    2214             :         } else {
    2215         563 :                 int old = PG(display_errors);
    2216         563 :                 int fault = 0;
    2217             :                 zval fault_obj;
    2218             : #ifdef va_copy
    2219             :                 va_list argcopy;
    2220             : #endif
    2221             : 
    2222         563 :                 if (error_num == E_USER_ERROR || 
    2223             :                     error_num == E_COMPILE_ERROR || 
    2224             :                     error_num == E_CORE_ERROR ||
    2225             :                     error_num == E_ERROR || 
    2226             :                     error_num == E_PARSE) {
    2227             : 
    2228          10 :                         char* code = SOAP_GLOBAL(error_code);
    2229             :                         char buffer[1024];
    2230          10 :                         zval *outbuf = NULL;
    2231             :                         zval **tmp;
    2232             :                         soapServicePtr service;
    2233             : 
    2234          10 :                         if (code == NULL) {
    2235           0 :                                 code = "Server";
    2236             :                         }
    2237          61 :                         if (SOAP_GLOBAL(error_object) &&
    2238          10 :                             Z_TYPE_P(SOAP_GLOBAL(error_object)) == IS_OBJECT &&
    2239          10 :                             instanceof_function(Z_OBJCE_P(SOAP_GLOBAL(error_object)), soap_server_class_entry TSRMLS_CC) &&
    2240          10 :                         zend_hash_find(Z_OBJPROP_P(SOAP_GLOBAL(error_object)), "service", sizeof("service"), (void **)&tmp) != FAILURE &&
    2241          10 :                                 (service = (soapServicePtr)zend_fetch_resource(tmp TSRMLS_CC, -1, "service", NULL, 1, le_service)) &&
    2242          10 :                                 !service->send_errors) {
    2243           1 :                                 strcpy(buffer, "Internal Error");
    2244             :                         } else {
    2245             :                                 int buffer_len;
    2246             :                                 zval outbuflen;
    2247             : 
    2248           9 :                                 INIT_ZVAL(outbuflen);
    2249             : 
    2250             : #ifdef va_copy
    2251           9 :                                 va_copy(argcopy, args);
    2252           9 :                                 buffer_len = vslprintf(buffer, sizeof(buffer)-1, format, argcopy);
    2253           9 :                                 va_end(argcopy);
    2254             : #else
    2255             :                                 buffer_len = vslprintf(buffer, sizeof(buffer)-1, format, args);
    2256             : #endif
    2257           9 :                                 buffer[sizeof(buffer)-1]=0;
    2258           9 :                                 if (buffer_len > sizeof(buffer) - 1 || buffer_len < 0) {
    2259           0 :                                         buffer_len = sizeof(buffer) - 1;
    2260             :                                 }
    2261             : 
    2262             :                                 /* Get output buffer and send as fault detials */
    2263           9 :                                 if (php_output_get_length(&outbuflen TSRMLS_CC) != FAILURE && Z_LVAL(outbuflen) != 0) {
    2264           0 :                                         ALLOC_INIT_ZVAL(outbuf);
    2265           0 :                                         php_output_get_contents(outbuf TSRMLS_CC);
    2266             :                                 }
    2267           9 :                                 php_output_discard(TSRMLS_C);
    2268             : 
    2269             :                         }
    2270          10 :                         INIT_ZVAL(fault_obj);
    2271          10 :                         set_soap_fault(&fault_obj, NULL, code, buffer, NULL, outbuf, NULL TSRMLS_CC);
    2272          10 :                         fault = 1;
    2273             :                 }
    2274             : 
    2275         563 :                 PG(display_errors) = 0;
    2276         563 :                 SG(sapi_headers).http_status_line = NULL;
    2277         563 :                 zend_try {
    2278         563 :                         call_old_error_handler(error_num, error_filename, error_lineno, format, args);
    2279          10 :                 } zend_catch {
    2280          10 :                         CG(in_compilation) = _old_in_compilation;
    2281          10 :                         EG(in_execution) = _old_in_execution;
    2282          10 :                         EG(current_execute_data) = _old_current_execute_data;
    2283          10 :                         if (SG(sapi_headers).http_status_line) {
    2284           0 :                                 efree(SG(sapi_headers).http_status_line);
    2285             :                         }
    2286          10 :                         SG(sapi_headers).http_status_line = _old_http_status_line;
    2287          10 :                         SG(sapi_headers).http_response_code = _old_http_response_code;
    2288         563 :                 } zend_end_try();
    2289         563 :                 PG(display_errors) = old;
    2290             : 
    2291         563 :                 if (fault) {
    2292          10 :                         soap_server_fault_ex(NULL, &fault_obj, NULL TSRMLS_CC);
    2293          10 :                         zend_bailout();
    2294             :                 }
    2295             :         }
    2296             : }
    2297             : 
    2298           0 : PHP_FUNCTION(use_soap_error_handler)
    2299             : {
    2300           0 :         zend_bool handler = 1;
    2301             : 
    2302           0 :         ZVAL_BOOL(return_value, SOAP_GLOBAL(use_soap_error_handler));
    2303           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &handler) == SUCCESS) {
    2304           0 :                 SOAP_GLOBAL(use_soap_error_handler) = handler;
    2305             :         }
    2306           0 : }
    2307             : 
    2308           0 : PHP_FUNCTION(is_soap_fault)
    2309             : {
    2310             :         zval *fault;
    2311             : 
    2312           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &fault) == SUCCESS &&
    2313           0 :             Z_TYPE_P(fault) == IS_OBJECT &&
    2314           0 :             instanceof_function(Z_OBJCE_P(fault), soap_fault_class_entry TSRMLS_CC)) {
    2315           0 :                 RETURN_TRUE;
    2316             :         }
    2317           0 :         RETURN_FALSE
    2318             : }
    2319             : 
    2320             : /* SoapClient functions */
    2321             : 
    2322             : /* {{{ proto object SoapClient::SoapClient ( mixed wsdl [, array options])
    2323             :    SoapClient constructor */
    2324         386 : PHP_METHOD(SoapClient, SoapClient)
    2325             : {
    2326             : 
    2327         386 :         zval *wsdl, *options = NULL;
    2328         386 :         int  soap_version = SOAP_1_1;
    2329         386 :         php_stream_context *context = NULL;
    2330             :         long cache_wsdl;
    2331         386 :         sdlPtr sdl = NULL;
    2332         386 :         HashTable *typemap_ht = NULL;
    2333             : 
    2334         386 :         SOAP_CLIENT_BEGIN_CODE();
    2335             : 
    2336         386 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z|a", &wsdl, &options) == FAILURE) {
    2337           0 :                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
    2338             :         }
    2339             : 
    2340         386 :         if (Z_TYPE_P(wsdl) != IS_STRING && Z_TYPE_P(wsdl) != IS_NULL) {
    2341           0 :                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "$wsdl must be string or null");
    2342             :         }
    2343             : 
    2344         386 :         cache_wsdl = SOAP_GLOBAL(cache_enabled) ? SOAP_GLOBAL(cache_mode) : 0;
    2345             : 
    2346         386 :         if (options != NULL) {
    2347         365 :                 HashTable *ht = Z_ARRVAL_P(options);
    2348             :                 zval **tmp;
    2349             : 
    2350         365 :                 if (Z_TYPE_P(wsdl) == IS_NULL) {
    2351             :                         /* Fetching non-WSDL mode options */
    2352         234 :                         if (zend_hash_find(ht, "uri", sizeof("uri"), (void**)&tmp) == SUCCESS &&
    2353          78 :                             Z_TYPE_PP(tmp) == IS_STRING) {
    2354          78 :                                 add_property_stringl(this_ptr, "uri", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
    2355             :                         } else {
    2356           0 :                                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "'uri' option is required in nonWSDL mode");
    2357             :                         }
    2358             : 
    2359          80 :                         if (zend_hash_find(ht, "style", sizeof("style"), (void**)&tmp) == SUCCESS &&
    2360           1 :                                         Z_TYPE_PP(tmp) == IS_LONG &&
    2361           1 :                                         (Z_LVAL_PP(tmp) == SOAP_RPC || Z_LVAL_PP(tmp) == SOAP_DOCUMENT)) {
    2362           1 :                                 add_property_long(this_ptr, "style", Z_LVAL_PP(tmp));
    2363             :                         }
    2364             : 
    2365          81 :                         if (zend_hash_find(ht, "use", sizeof("use"), (void**)&tmp) == SUCCESS &&
    2366           1 :                                         Z_TYPE_PP(tmp) == IS_LONG &&
    2367           2 :                                         (Z_LVAL_PP(tmp) == SOAP_LITERAL || Z_LVAL_PP(tmp) == SOAP_ENCODED)) {
    2368           1 :                                 add_property_long(this_ptr, "use", Z_LVAL_PP(tmp));
    2369             :                         }
    2370             :                 }
    2371             : 
    2372         366 :                 if (zend_hash_find(ht, "stream_context", sizeof("stream_context"), (void**)&tmp) == SUCCESS &&
    2373           1 :                                 Z_TYPE_PP(tmp) == IS_RESOURCE) {
    2374           1 :                         context = php_stream_context_from_zval(*tmp, 1);
    2375           1 :                         zend_list_addref(context->rsrc_id);
    2376             :                 }
    2377             : 
    2378         525 :                 if (zend_hash_find(ht, "location", sizeof("location"), (void**)&tmp) == SUCCESS &&
    2379          80 :                     Z_TYPE_PP(tmp) == IS_STRING) {
    2380          80 :                         add_property_stringl(this_ptr, "location", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
    2381         285 :                 } else if (Z_TYPE_P(wsdl) == IS_NULL) {
    2382           0 :                         php_error_docref(NULL TSRMLS_CC, E_ERROR, "'location' option is required in nonWSDL mode");
    2383             :                 }
    2384             : 
    2385         365 :                 if (zend_hash_find(ht, "soap_version", sizeof("soap_version"), (void**)&tmp) == SUCCESS) {
    2386           2 :                         if (Z_TYPE_PP(tmp) == IS_LONG ||
    2387           0 :                             (Z_LVAL_PP(tmp) == SOAP_1_1 && Z_LVAL_PP(tmp) == SOAP_1_2)) {
    2388           2 :                                 soap_version = Z_LVAL_PP(tmp);
    2389             :                         }
    2390             :                 }
    2391         366 :                 if (zend_hash_find(ht, "login", sizeof("login"), (void**)&tmp) == SUCCESS &&
    2392           1 :                     Z_TYPE_PP(tmp) == IS_STRING) {
    2393           1 :                         add_property_stringl(this_ptr, "_login", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
    2394           2 :                         if (zend_hash_find(ht, "password", sizeof("password"), (void**)&tmp) == SUCCESS &&
    2395           1 :                             Z_TYPE_PP(tmp) == IS_STRING) {
    2396           1 :                                 add_property_stringl(this_ptr, "_password", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
    2397             :                         }
    2398           1 :                         if (zend_hash_find(ht, "authentication", sizeof("authentication"), (void**)&tmp) == SUCCESS &&
    2399           0 :                             Z_TYPE_PP(tmp) == IS_LONG &&
    2400           0 :                             Z_LVAL_PP(tmp) == SOAP_AUTHENTICATION_DIGEST) {
    2401           0 :                                 add_property_null(this_ptr, "_digest");
    2402             :                         }
    2403             :                 }
    2404         366 :                 if (zend_hash_find(ht, "proxy_host", sizeof("proxy_host"), (void**)&tmp) == SUCCESS &&
    2405           1 :                     Z_TYPE_PP(tmp) == IS_STRING) {
    2406           1 :                         add_property_stringl(this_ptr, "_proxy_host", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
    2407           1 :                         if (zend_hash_find(ht, "proxy_port", sizeof("proxy_port"), (void**)&tmp) == SUCCESS) {
    2408           1 :                                 convert_to_long(*tmp);
    2409           1 :                                 add_property_long(this_ptr, "_proxy_port", Z_LVAL_PP(tmp));
    2410             :                         }
    2411           1 :                         if (zend_hash_find(ht, "proxy_login", sizeof("proxy_login"), (void**)&tmp) == SUCCESS &&
    2412           0 :                             Z_TYPE_PP(tmp) == IS_STRING) {
    2413           0 :                                 add_property_stringl(this_ptr, "_proxy_login", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
    2414           0 :                                 if (zend_hash_find(ht, "proxy_password", sizeof("proxy_password"), (void**)&tmp) == SUCCESS &&
    2415           0 :                                     Z_TYPE_PP(tmp) == IS_STRING) {
    2416           0 :                                         add_property_stringl(this_ptr, "_proxy_password", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
    2417             :                                 }
    2418             :                         }
    2419             :                 }
    2420         365 :                 if (zend_hash_find(ht, "local_cert", sizeof("local_cert"), (void**)&tmp) == SUCCESS &&
    2421           0 :                     Z_TYPE_PP(tmp) == IS_STRING) {
    2422           0 :                   if (!context) {
    2423           0 :                         context = php_stream_context_alloc(TSRMLS_C);
    2424             :                   }
    2425           0 :                         php_stream_context_set_option(context, "ssl", "local_cert", *tmp);
    2426           0 :                         if (zend_hash_find(ht, "passphrase", sizeof("passphrase"), (void**)&tmp) == SUCCESS &&
    2427           0 :                             Z_TYPE_PP(tmp) == IS_STRING) {
    2428           0 :                                 php_stream_context_set_option(context, "ssl", "passphrase", *tmp);
    2429             :                         }
    2430             :                 }
    2431        1345 :                 if (zend_hash_find(ht, "trace", sizeof("trace"), (void**)&tmp) == SUCCESS &&
    2432         652 :                     (Z_TYPE_PP(tmp) == IS_BOOL || Z_TYPE_PP(tmp) == IS_LONG) &&
    2433         328 :                                 Z_LVAL_PP(tmp) == 1) {
    2434         328 :                         add_property_long(this_ptr, "trace", 1);
    2435             :                 }
    2436             : 
    2437        1318 :                 if (zend_hash_find(ht, "exceptions", sizeof("exceptions"), (void**)&tmp) == SUCCESS &&
    2438         634 :                     (Z_TYPE_PP(tmp) == IS_BOOL || Z_TYPE_PP(tmp) == IS_LONG) &&
    2439         319 :                                 Z_LVAL_PP(tmp) == 0) {
    2440         319 :                         add_property_bool(this_ptr, "_exceptions", 0);
    2441             :                 }
    2442             : 
    2443         365 :                 if (zend_hash_find(ht, "compression", sizeof("compression"), (void**)&tmp) == SUCCESS &&
    2444           0 :                     Z_TYPE_PP(tmp) == IS_LONG &&
    2445           0 :               zend_hash_exists(EG(function_table), "gzinflate", sizeof("gzinflate")) &&
    2446           0 :               zend_hash_exists(EG(function_table), "gzdeflate", sizeof("gzdeflate")) &&
    2447           0 :               zend_hash_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress")) &&
    2448           0 :               zend_hash_exists(EG(function_table), "gzcompress", sizeof("gzcompress")) &&
    2449           0 :               zend_hash_exists(EG(function_table), "gzencode", sizeof("gzencode"))) {
    2450           0 :                         add_property_long(this_ptr, "compression", Z_LVAL_PP(tmp));
    2451             :                 }
    2452         378 :                 if (zend_hash_find(ht, "encoding", sizeof("encoding"), (void**)&tmp) == SUCCESS &&
    2453          13 :                     Z_TYPE_PP(tmp) == IS_STRING) {
    2454             :                         xmlCharEncodingHandlerPtr encoding;
    2455             :                 
    2456          13 :                         encoding = xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp));
    2457          13 :                         if (encoding == NULL) {
    2458           0 :                                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid 'encoding' option - '%s'", Z_STRVAL_PP(tmp));
    2459             :                         } else {
    2460          13 :                                 xmlCharEncCloseFunc(encoding);
    2461          13 :                                 add_property_stringl(this_ptr, "_encoding", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);                   
    2462             :                         }
    2463             :                 }
    2464         375 :                 if (zend_hash_find(ht, "classmap", sizeof("classmap"), (void**)&tmp) == SUCCESS &&
    2465          10 :                         Z_TYPE_PP(tmp) == IS_ARRAY) {
    2466             :                         zval *class_map;
    2467             : 
    2468          10 :                         MAKE_STD_ZVAL(class_map);
    2469          10 :                         MAKE_COPY_ZVAL(tmp, class_map);
    2470             :                         Z_DELREF_P(class_map);
    2471             : 
    2472          10 :                         add_property_zval(this_ptr, "_classmap", class_map);
    2473             :                 }
    2474             : 
    2475         377 :                 if (zend_hash_find(ht, "typemap", sizeof("typemap"), (void**)&tmp) == SUCCESS &&
    2476           6 :                         Z_TYPE_PP(tmp) == IS_ARRAY &&
    2477           6 :                         zend_hash_num_elements(Z_ARRVAL_PP(tmp)) > 0) {
    2478           6 :                         typemap_ht = Z_ARRVAL_PP(tmp);
    2479             :                 }
    2480             : 
    2481         452 :                 if (zend_hash_find(ht, "features", sizeof("features"), (void**)&tmp) == SUCCESS &&
    2482          87 :                         Z_TYPE_PP(tmp) == IS_LONG) {
    2483          87 :                         add_property_long(this_ptr, "_features", Z_LVAL_PP(tmp));
    2484             :             }
    2485             : 
    2486         365 :                 if (zend_hash_find(ht, "connection_timeout", sizeof("connection_timeout"), (void**)&tmp) == SUCCESS) {
    2487           0 :                         convert_to_long(*tmp);
    2488           0 :                         if (Z_LVAL_PP(tmp) > 0) {
    2489           0 :                                 add_property_long(this_ptr, "_connection_timeout", Z_LVAL_PP(tmp));
    2490             :                         }
    2491             :                 }
    2492             : 
    2493         365 :                 if (context) {
    2494           1 :                         add_property_resource(this_ptr, "_stream_context", context->rsrc_id);
    2495             :                 }
    2496             :         
    2497         376 :                 if (zend_hash_find(ht, "cache_wsdl", sizeof("cache_wsdl"), (void**)&tmp) == SUCCESS &&
    2498          11 :                     Z_TYPE_PP(tmp) == IS_LONG) {
    2499          11 :                         cache_wsdl = Z_LVAL_PP(tmp);
    2500             :                 }
    2501             : 
    2502         365 :                 if (zend_hash_find(ht, "user_agent", sizeof("user_agent"), (void**)&tmp) == SUCCESS &&
    2503           0 :                     Z_TYPE_PP(tmp) == IS_STRING) {
    2504           0 :                         add_property_stringl(this_ptr, "_user_agent", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
    2505             :                 }
    2506             :                 
    2507         365 :                 if (zend_hash_find(ht, "keep_alive", sizeof("keep_alive"), (void**)&tmp) == SUCCESS &&
    2508           0 :                                 (Z_TYPE_PP(tmp) == IS_BOOL || Z_TYPE_PP(tmp) == IS_LONG) && Z_LVAL_PP(tmp) == 0) {
    2509           0 :                         add_property_long(this_ptr, "_keep_alive", 0);
    2510             :                 }
    2511          21 :         } else if (Z_TYPE_P(wsdl) == IS_NULL) {
    2512           0 :                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "'location' and 'uri' options are required in nonWSDL mode");
    2513             :         }
    2514             : 
    2515         386 :         add_property_long(this_ptr, "_soap_version", soap_version);
    2516             : 
    2517         386 :         if (Z_TYPE_P(wsdl) != IS_NULL) {
    2518             :                 int    old_soap_version, ret;
    2519             : 
    2520         308 :                 old_soap_version = SOAP_GLOBAL(soap_version);
    2521         308 :                 SOAP_GLOBAL(soap_version) = soap_version;
    2522             : 
    2523         308 :                 sdl = get_sdl(this_ptr, Z_STRVAL_P(wsdl), cache_wsdl TSRMLS_CC);
    2524         303 :                 ret = zend_list_insert(sdl, le_sdl TSRMLS_CC);
    2525             : 
    2526         303 :                 add_property_resource(this_ptr, "sdl", ret);
    2527             : 
    2528         303 :                 SOAP_GLOBAL(soap_version) = old_soap_version;
    2529             :         }
    2530             : 
    2531         381 :         if (typemap_ht) {
    2532           6 :                 HashTable *typemap = soap_create_typemap(sdl, typemap_ht TSRMLS_CC);
    2533           6 :                 if (typemap) {
    2534             :                         int ret;
    2535             : 
    2536           6 :                         ret = zend_list_insert(typemap, le_typemap TSRMLS_CC);
    2537           6 :                         add_property_resource(this_ptr, "typemap", ret);
    2538             :                 }
    2539             :         }
    2540           5 :         SOAP_CLIENT_END_CODE();
    2541         385 : }
    2542             : /* }}} */
    2543             : 
    2544         397 : static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *action, int version, int one_way, zval *response TSRMLS_DC)
    2545             : {
    2546         397 :         int    ret = TRUE;
    2547             :         char  *buf;
    2548             :         int    buf_size;
    2549             :         zval   func, param0, param1, param2, param3, param4;
    2550             :         zval  *params[5];
    2551             :         zval **trace;
    2552             :         zval **fault;
    2553             : 
    2554         397 :         INIT_ZVAL(*response);
    2555             : 
    2556         397 :         xmlDocDumpMemory(request, (xmlChar**)&buf, &buf_size);
    2557         397 :         if (!buf) {
    2558           0 :                 add_soap_fault(this_ptr, "HTTP", "Error build soap request", NULL, NULL TSRMLS_CC);
    2559           0 :                 return FALSE;
    2560             :         }
    2561             : 
    2562        1408 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
    2563        1011 :             (Z_TYPE_PP(trace) == IS_BOOL || Z_TYPE_PP(trace) == IS_LONG) && Z_LVAL_PP(trace) != 0) {
    2564         337 :                 add_property_stringl(this_ptr, "__last_request", buf, buf_size, 1);
    2565             :         }
    2566             : 
    2567         397 :         INIT_ZVAL(func);
    2568         397 :         ZVAL_STRINGL(&func,"__doRequest",sizeof("__doRequest")-1,0);
    2569         397 :         INIT_ZVAL(param0);
    2570         397 :         params[0] = &param0;
    2571         397 :         ZVAL_STRINGL(params[0], buf, buf_size, 0);
    2572         397 :         INIT_ZVAL(param1);
    2573         397 :         params[1] = &param1;
    2574         397 :         if (location == NULL) {
    2575           0 :                 ZVAL_NULL(params[1]);
    2576             :         } else {
    2577         397 :                 ZVAL_STRING(params[1], location, 0);
    2578             :         }
    2579         397 :         INIT_ZVAL(param2);
    2580         397 :         params[2] = &param2;
    2581         397 :         if (action == NULL) {
    2582           4 :                 ZVAL_NULL(params[2]);
    2583             :         } else {
    2584         393 :                 ZVAL_STRING(params[2], action, 0);
    2585             :         }
    2586         397 :         INIT_ZVAL(param3);
    2587         397 :         params[3] = &param3;
    2588         397 :         ZVAL_LONG(params[3], version);
    2589             : 
    2590         397 :         INIT_ZVAL(param4);
    2591         397 :         params[4] = &param4;
    2592         397 :         ZVAL_LONG(params[4], one_way);
    2593             : 
    2594         397 :         if (call_user_function(NULL, &this_ptr, &func, response, 5, params TSRMLS_CC) != SUCCESS) {
    2595           1 :                 add_soap_fault(this_ptr, "Client", "SoapClient::__doRequest() failed", NULL, NULL TSRMLS_CC);
    2596           1 :                 ret = FALSE;
    2597         388 :         } else if (Z_TYPE_P(response) != IS_STRING) {
    2598         316 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == FAILURE) {
    2599           0 :                         add_soap_fault(this_ptr, "Client", "SoapClient::__doRequest() returned non string value", NULL, NULL TSRMLS_CC);
    2600             :                 }
    2601         316 :                 ret = FALSE;
    2602         129 :         } else if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
    2603          57 :                    (Z_TYPE_PP(trace) == IS_BOOL || Z_TYPE_PP(trace) == IS_LONG) && Z_LVAL_PP(trace) != 0) {
    2604          19 :                 add_property_stringl(this_ptr, "__last_response", Z_STRVAL_P(response), Z_STRLEN_P(response), 1);
    2605             :         }
    2606         389 :         xmlFree(buf);
    2607         389 :         if (ret && zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
    2608           0 :           return FALSE;
    2609             :         }         
    2610         389 :   return ret;
    2611             : }
    2612             : 
    2613         398 : static void do_soap_call(zval* this_ptr,
    2614             :                          char* function,
    2615             :                          int function_len,
    2616             :                          int arg_count,
    2617             :                          zval** real_args,
    2618             :                          zval* return_value,
    2619             :                          char* location,
    2620             :                          char* soap_action,
    2621             :                          char* call_uri,
    2622             :                          HashTable* soap_headers,
    2623             :                          zval* output_headers
    2624             :                          TSRMLS_DC)
    2625             : {
    2626             :         zval **tmp;
    2627             :         zval **trace;
    2628         398 :         sdlPtr sdl = NULL;
    2629         398 :         sdlPtr old_sdl = NULL;
    2630             :         sdlFunctionPtr fn;
    2631         398 :         xmlDocPtr request = NULL;
    2632         398 :         int ret = FALSE;
    2633             :         int soap_version;
    2634             :         zval response;
    2635             :         xmlCharEncodingHandlerPtr old_encoding;
    2636             :         HashTable *old_class_map;
    2637             :         int old_features;
    2638         398 :         HashTable *old_typemap, *typemap = NULL;
    2639             : 
    2640         398 :         SOAP_CLIENT_BEGIN_CODE();
    2641             : 
    2642        1412 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
    2643        1014 :             (Z_TYPE_PP(trace) == IS_BOOL || Z_TYPE_PP(trace) == IS_LONG) && Z_LVAL_PP(trace) != 0) {
    2644         338 :                 zend_hash_del(Z_OBJPROP_P(this_ptr), "__last_request", sizeof("__last_request"));
    2645         338 :                 zend_hash_del(Z_OBJPROP_P(this_ptr), "__last_response", sizeof("__last_response"));
    2646             :         }
    2647        1196 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_soap_version", sizeof("_soap_version"), (void **) &tmp) == SUCCESS &&
    2648         796 :                 Z_TYPE_PP(tmp) == IS_LONG && Z_LVAL_PP(tmp) == SOAP_1_2) {
    2649           2 :                 soap_version = SOAP_1_2;
    2650             :         } else {
    2651         396 :                 soap_version = SOAP_1_1;
    2652             :         }
    2653             : 
    2654         398 :         if (location == NULL) {
    2655         501 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &tmp) == SUCCESS &&
    2656         104 :                     Z_TYPE_PP(tmp) == IS_STRING) {
    2657         104 :                   location = Z_STRVAL_PP(tmp);
    2658             :                 }
    2659             :         }
    2660             : 
    2661         398 :         if (FIND_SDL_PROPERTY(this_ptr,tmp) != FAILURE) {
    2662         300 :                 FETCH_SDL_RES(sdl,tmp);
    2663             :         }
    2664         398 :         if (FIND_TYPEMAP_PROPERTY(this_ptr,tmp) != FAILURE) {
    2665           6 :                 FETCH_TYPEMAP_RES(typemap,tmp);
    2666             :         }
    2667             : 
    2668         398 :         clear_soap_fault(this_ptr TSRMLS_CC);
    2669             : 
    2670         398 :         SOAP_GLOBAL(soap_version) = soap_version;
    2671         398 :         old_sdl = SOAP_GLOBAL(sdl);
    2672         398 :         SOAP_GLOBAL(sdl) = sdl;
    2673         398 :         old_encoding = SOAP_GLOBAL(encoding);
    2674         424 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_encoding", sizeof("_encoding"), (void **) &tmp) == SUCCESS &&
    2675          13 :             Z_TYPE_PP(tmp) == IS_STRING) {
    2676          13 :                 SOAP_GLOBAL(encoding) = xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp));
    2677             :         } else {
    2678         385 :                 SOAP_GLOBAL(encoding) = NULL;
    2679             :         }
    2680         398 :         old_class_map = SOAP_GLOBAL(class_map);
    2681         418 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_classmap", sizeof("_classmap"), (void **) &tmp) == SUCCESS &&
    2682          10 :             Z_TYPE_PP(tmp) == IS_ARRAY) {
    2683          10 :                 SOAP_GLOBAL(class_map) = (*tmp)->value.ht;
    2684             :         } else {
    2685         388 :                 SOAP_GLOBAL(class_map) = NULL;
    2686             :         }
    2687         398 :         old_typemap = SOAP_GLOBAL(typemap);
    2688         398 :         SOAP_GLOBAL(typemap) = typemap;
    2689         398 :         old_features = SOAP_GLOBAL(features);
    2690         572 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_features", sizeof("_features"), (void **) &tmp) == SUCCESS &&
    2691          87 :             Z_TYPE_PP(tmp) == IS_LONG) {
    2692          87 :                 SOAP_GLOBAL(features) = Z_LVAL_PP(tmp);
    2693             :         } else {
    2694         311 :                 SOAP_GLOBAL(features) = 0;
    2695             :         }
    2696             : 
    2697         398 :         if (sdl != NULL) {
    2698         300 :                 fn = get_function(sdl, function);
    2699         300 :                 if (fn != NULL) {
    2700         300 :                         sdlBindingPtr binding = fn->binding;
    2701         300 :                         int one_way = 0;
    2702             : 
    2703         387 :                         if (fn->responseName == NULL &&
    2704          87 :                             fn->responseParameters == NULL &&
    2705             :                             soap_headers == NULL) {
    2706          87 :                                 one_way = 1;
    2707             :                         }
    2708             : 
    2709         300 :                         if (location == NULL) {
    2710         293 :                                 location = binding->location;
    2711             :                         }
    2712         300 :                         if (binding->bindingType == BINDING_SOAP) {
    2713         299 :                                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
    2714         299 :                                 request = serialize_function_call(this_ptr, fn, NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
    2715         298 :                                 ret = do_request(this_ptr, request, location, fnb->soapAction, soap_version, one_way, &response TSRMLS_CC);
    2716             :                         }       else {
    2717           1 :                                 request = serialize_function_call(this_ptr, fn, NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
    2718           1 :                                 ret = do_request(this_ptr, request, location, NULL, soap_version, one_way, &response TSRMLS_CC);
    2719             :                         }
    2720             : 
    2721         294 :                         xmlFreeDoc(request);
    2722             : 
    2723         294 :                         if (ret && Z_TYPE(response) == IS_STRING) {
    2724          49 :                                 encode_reset_ns();
    2725          49 :                                 ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers TSRMLS_CC);
    2726          49 :                                 encode_finish();
    2727             :                         }
    2728             : 
    2729             :                         zval_dtor(&response);
    2730             : 
    2731             :                 } else {
    2732           0 :                         smart_str error = {0};
    2733           0 :                         smart_str_appends(&error,"Function (\"");
    2734           0 :                         smart_str_appends(&error,function);
    2735           0 :                         smart_str_appends(&error,"\") is not a valid method for this service");
    2736           0 :                         smart_str_0(&error);
    2737           0 :                         add_soap_fault(this_ptr, "Client", error.c, NULL, NULL TSRMLS_CC);
    2738           0 :                         smart_str_free(&error);
    2739             :                 }
    2740             :         } else {
    2741             :                 zval **uri;
    2742          98 :                 smart_str action = {0};
    2743             : 
    2744          98 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "uri", sizeof("uri"), (void *)&uri) == FAILURE || Z_TYPE_PP(uri) != IS_STRING) {
    2745           0 :                         add_soap_fault(this_ptr, "Client", "Error finding \"uri\" property", NULL, NULL TSRMLS_CC);
    2746          98 :                 } else if (location == NULL) {
    2747           0 :                         add_soap_fault(this_ptr, "Client", "Error could not find \"location\" property", NULL, NULL TSRMLS_CC);
    2748             :                 } else {
    2749          98 :                         if (call_uri == NULL) {
    2750          39 :                                 call_uri = Z_STRVAL_PP(uri);
    2751             :                         }
    2752          98 :                         request = serialize_function_call(this_ptr, NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
    2753             : 
    2754          98 :                         if (soap_action == NULL) {
    2755          40 :                                 smart_str_appends(&action, call_uri);
    2756          40 :                                 smart_str_appendc(&action, '#');
    2757          40 :                                 smart_str_appends(&action, function);
    2758             :                         } else {
    2759          58 :                                 smart_str_appends(&action, soap_action);
    2760             :                         }
    2761          98 :                         smart_str_0(&action);
    2762             : 
    2763          98 :                         ret = do_request(this_ptr, request, location, action.c, soap_version, 0, &response TSRMLS_CC);
    2764             : 
    2765          95 :                         smart_str_free(&action);
    2766          95 :                         xmlFreeDoc(request);
    2767             : 
    2768          95 :                         if (ret && Z_TYPE(response) == IS_STRING) {
    2769          23 :                                 encode_reset_ns();
    2770          23 :                                 ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value, output_headers TSRMLS_CC);
    2771          23 :                                 encode_finish();
    2772             :                         }
    2773             : 
    2774             :                         zval_dtor(&response);
    2775             :                 }
    2776             :         }
    2777             : 
    2778         389 :         if (!ret) {
    2779             :                 zval** fault;
    2780         321 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
    2781         321 :                         *return_value = **fault;
    2782         321 :                         zval_copy_ctor(return_value);
    2783             :                 } else {
    2784           0 :                         *return_value = *add_soap_fault(this_ptr, "Client", "Unknown Error", NULL, NULL TSRMLS_CC);
    2785           0 :                         zval_copy_ctor(return_value);
    2786             :                 }
    2787             :         } else {
    2788             :                 zval** fault;
    2789          68 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
    2790           0 :                         *return_value = **fault;
    2791           0 :                         zval_copy_ctor(return_value);
    2792             :                 }
    2793             :         }
    2794             : 
    2795        2080 :         if (!EG(exception) &&
    2796         387 :             Z_TYPE_P(return_value) == IS_OBJECT &&
    2797         346 :             instanceof_function(Z_OBJCE_P(return_value), soap_fault_class_entry TSRMLS_CC) &&
    2798         320 :             (zend_hash_find(Z_OBJPROP_P(this_ptr), "_exceptions", sizeof("_exceptions"), (void **) &tmp) != SUCCESS ||
    2799         638 :                    Z_TYPE_PP(tmp) != IS_BOOL || Z_LVAL_PP(tmp) != 0)) {
    2800             :                 zval *exception;
    2801             : 
    2802           1 :                 MAKE_STD_ZVAL(exception);
    2803           1 :                 MAKE_COPY_ZVAL(&return_value, exception);
    2804           1 :                 zend_throw_exception_object(exception TSRMLS_CC);
    2805             :         }
    2806             : 
    2807         389 :         if (SOAP_GLOBAL(encoding) != NULL) {
    2808          13 :                 xmlCharEncCloseFunc(SOAP_GLOBAL(encoding));
    2809             :         }
    2810         389 :         SOAP_GLOBAL(features) = old_features;
    2811         389 :         SOAP_GLOBAL(typemap) = old_typemap;
    2812         389 :         SOAP_GLOBAL(class_map) = old_class_map;
    2813         389 :         SOAP_GLOBAL(encoding) = old_encoding;
    2814         389 :         SOAP_GLOBAL(sdl) = old_sdl;
    2815           9 :         SOAP_CLIENT_END_CODE();
    2816         390 : }
    2817             : 
    2818           4 : static void verify_soap_headers_array(HashTable *ht TSRMLS_DC)
    2819             : {
    2820             :         zval **tmp;
    2821             : 
    2822           4 :         zend_hash_internal_pointer_reset(ht);
    2823          14 :         while (zend_hash_get_current_data(ht, (void**)&tmp) == SUCCESS) {
    2824          12 :                 if (Z_TYPE_PP(tmp) != IS_OBJECT ||
    2825           6 :                     !instanceof_function(Z_OBJCE_PP(tmp), soap_header_class_entry TSRMLS_CC)) {
    2826           0 :                         php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid SOAP header");
    2827             :                 }
    2828           6 :                 zend_hash_move_forward(ht);
    2829             :         }
    2830           4 : }
    2831             : 
    2832             : 
    2833             : /* {{{ proto mixed SoapClient::__call ( string function_name, array arguments [, array options [, array input_headers [, array output_headers]]])
    2834             :    Calls a SOAP function */
    2835         398 : PHP_METHOD(SoapClient, __call)
    2836             : {
    2837         398 :         char *function, *location=NULL, *soap_action = NULL, *uri = NULL;
    2838         398 :         int function_len, i = 0;
    2839         398 :         HashTable* soap_headers = NULL;
    2840         398 :         zval *options = NULL;
    2841         398 :         zval *headers = NULL;
    2842         398 :         zval *output_headers = NULL;
    2843             :         zval *args;
    2844         398 :         zval **real_args = NULL;
    2845             :         zval **param;
    2846             :         int arg_count;
    2847             :         zval **tmp;
    2848         398 :         zend_bool free_soap_headers = 0;
    2849             : 
    2850             :         HashPosition pos;
    2851             : 
    2852         398 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|a!zz",
    2853             :                 &function, &function_len, &args, &options, &headers, &output_headers) == FAILURE) {
    2854           0 :                 return;
    2855             :         }
    2856             : 
    2857         398 :         if (options) {
    2858          60 :                 HashTable *hto = Z_ARRVAL_P(options);
    2859          61 :                 if (zend_hash_find(hto, "location", sizeof("location"), (void**)&tmp) == SUCCESS &&
    2860           1 :                         Z_TYPE_PP(tmp) == IS_STRING) {
    2861           1 :                         location = Z_STRVAL_PP(tmp);
    2862             :                 }
    2863             : 
    2864         118 :                 if (zend_hash_find(hto, "soapaction", sizeof("soapaction"), (void**)&tmp) == SUCCESS &&
    2865          58 :                         Z_TYPE_PP(tmp) == IS_STRING) {
    2866          58 :                         soap_action = Z_STRVAL_PP(tmp);
    2867             :                 }
    2868             : 
    2869         119 :                 if (zend_hash_find(hto, "uri", sizeof("uri"), (void**)&tmp) == SUCCESS &&
    2870          59 :                         Z_TYPE_PP(tmp) == IS_STRING) {
    2871          59 :                         uri = Z_STRVAL_PP(tmp);
    2872             :                 }
    2873             :         }
    2874             : 
    2875         398 :         if (headers == NULL || Z_TYPE_P(headers) == IS_NULL) {
    2876          12 :         } else if (Z_TYPE_P(headers) == IS_ARRAY) {
    2877           2 :                 soap_headers = Z_ARRVAL_P(headers);
    2878           2 :                 verify_soap_headers_array(soap_headers TSRMLS_CC);
    2879           2 :                 free_soap_headers = 0;
    2880          30 :         } else if (Z_TYPE_P(headers) == IS_OBJECT &&
    2881          10 :                    instanceof_function(Z_OBJCE_P(headers), soap_header_class_entry TSRMLS_CC)) {
    2882          10 :             soap_headers = emalloc(sizeof(HashTable));
    2883          10 :                 zend_hash_init(soap_headers, 0, NULL, ZVAL_PTR_DTOR, 0);
    2884          10 :                 zend_hash_next_index_insert(soap_headers, &headers, sizeof(zval*), NULL);
    2885          10 :                 Z_ADDREF_P(headers);
    2886          10 :                 free_soap_headers = 1;
    2887             :         } else{
    2888           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid SOAP header");
    2889           0 :                 return;
    2890             :         }
    2891             : 
    2892             :         /* Add default headers */
    2893         403 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers"), (void **) &tmp)==SUCCESS &&
    2894           5 :             Z_TYPE_PP(tmp) == IS_ARRAY) {
    2895           5 :                 HashTable *default_headers = Z_ARRVAL_P(*tmp);
    2896           5 :                 if (soap_headers) {
    2897           1 :                         if (!free_soap_headers) {
    2898           1 :                                 HashTable *t =  emalloc(sizeof(HashTable));
    2899           1 :                                 zend_hash_init(t, 0, NULL, ZVAL_PTR_DTOR, 0);
    2900           1 :                                 zend_hash_copy(t, soap_headers, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
    2901           1 :                                 soap_headers = t;
    2902           1 :                                 free_soap_headers = 1;
    2903             :                         }
    2904           1 :                         zend_hash_internal_pointer_reset(default_headers);
    2905           4 :                         while (zend_hash_get_current_data(default_headers, (void**)&tmp) == SUCCESS) {
    2906           2 :                                 Z_ADDREF_PP(tmp);
    2907           2 :                                 zend_hash_next_index_insert(soap_headers, tmp, sizeof(zval *), NULL);
    2908           2 :                                 zend_hash_move_forward(default_headers);
    2909             :                         }
    2910             :                 } else {
    2911           4 :                         soap_headers = Z_ARRVAL_P(*tmp);
    2912           4 :                         free_soap_headers = 0;
    2913             :                 }
    2914             :         }
    2915             :         
    2916         398 :         arg_count = zend_hash_num_elements(Z_ARRVAL_P(args));
    2917             : 
    2918         398 :         if (arg_count > 0) {
    2919         355 :                 real_args = safe_emalloc(sizeof(zval *), arg_count, 0);
    2920        1155 :                 for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(args), &pos);
    2921         800 :                         zend_hash_get_current_data_ex(Z_ARRVAL_P(args), (void **) &param, &pos) == SUCCESS;
    2922         445 :                         zend_hash_move_forward_ex(Z_ARRVAL_P(args), &pos)) {
    2923             :                                 /*zval_add_ref(param);*/
    2924         445 :                                 real_args[i++] = *param;
    2925             :                 }
    2926             :         }
    2927         398 :         if (output_headers) {
    2928           0 :                 array_init(output_headers);
    2929             :         }
    2930         398 :         do_soap_call(this_ptr, function, function_len, arg_count, real_args, return_value, location, soap_action, uri, soap_headers, output_headers TSRMLS_CC);
    2931         390 :         if (arg_count > 0) {
    2932         347 :                 efree(real_args);
    2933             :         }
    2934             : 
    2935         390 :         if (soap_headers && free_soap_headers) {
    2936          11 :                 zend_hash_destroy(soap_headers);
    2937          11 :                 efree(soap_headers);
    2938             :         }
    2939             : }
    2940             : /* }}} */
    2941             : 
    2942             : 
    2943             : /* {{{ proto array SoapClient::__getFunctions ( void )
    2944             :    Returns list of SOAP functions */
    2945           4 : PHP_METHOD(SoapClient, __getFunctions)
    2946             : {
    2947             :         sdlPtr sdl;
    2948             :         HashPosition pos;
    2949             : 
    2950           4 :         FETCH_THIS_SDL(sdl);
    2951             : 
    2952           4 :         if (zend_parse_parameters_none() == FAILURE) {
    2953           0 :                 return;
    2954             :         }
    2955             : 
    2956           4 :         if (sdl) {
    2957           4 :                 smart_str buf = {0};
    2958             :                 sdlFunctionPtr *function;
    2959             : 
    2960           4 :                 array_init(return_value);
    2961           4 :                 zend_hash_internal_pointer_reset_ex(&sdl->functions, &pos);
    2962          15 :                 while (zend_hash_get_current_data_ex(&sdl->functions, (void **)&function, &pos) != FAILURE) {
    2963           7 :                         function_to_string((*function), &buf);
    2964           7 :                         add_next_index_stringl(return_value, buf.c, buf.len, 1);
    2965           7 :                         smart_str_free(&buf);
    2966           7 :                         zend_hash_move_forward_ex(&sdl->functions, &pos);
    2967             :                 }
    2968             :         }
    2969             : }
    2970             : /* }}} */
    2971             : 
    2972             : 
    2973             : /* {{{ proto array SoapClient::__getTypes ( void )
    2974             :    Returns list of SOAP types */
    2975           3 : PHP_METHOD(SoapClient, __getTypes)
    2976             : {
    2977             :         sdlPtr sdl;
    2978             :         HashPosition pos;
    2979             : 
    2980           3 :         FETCH_THIS_SDL(sdl);
    2981             :         
    2982           3 :         if (zend_parse_parameters_none() == FAILURE) {
    2983           0 :                 return;
    2984             :         }
    2985             : 
    2986           3 :         if (sdl) {
    2987             :                 sdlTypePtr *type;
    2988           3 :                 smart_str buf = {0};
    2989             : 
    2990           3 :                 array_init(return_value);
    2991           3 :                 if (sdl->types) {
    2992           3 :                         zend_hash_internal_pointer_reset_ex(sdl->types, &pos);
    2993          55 :                         while (zend_hash_get_current_data_ex(sdl->types, (void **)&type, &pos) != FAILURE) {
    2994          49 :                                 type_to_string((*type), &buf, 0);
    2995          49 :                                 add_next_index_stringl(return_value, buf.c, buf.len, 1);
    2996          49 :                                 smart_str_free(&buf);
    2997          49 :                                 zend_hash_move_forward_ex(sdl->types, &pos);
    2998             :                         }
    2999             :                 }
    3000             :         }
    3001             : }
    3002             : /* }}} */
    3003             : 
    3004             : 
    3005             : /* {{{ proto string SoapClient::__getLastRequest ( void )
    3006             :    Returns last SOAP request */
    3007         529 : PHP_METHOD(SoapClient, __getLastRequest)
    3008             : {
    3009             :         zval **tmp;
    3010             :         
    3011         529 :         if (zend_parse_parameters_none() == FAILURE) {
    3012           0 :                 return;
    3013             :         }
    3014             : 
    3015        1058 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__last_request", sizeof("__last_request"), (void **)&tmp) == SUCCESS &&
    3016         529 :             Z_TYPE_PP(tmp) == IS_STRING) {
    3017         529 :                 RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
    3018             :         }
    3019           0 :         RETURN_NULL();
    3020             : }
    3021             : /* }}} */
    3022             : 
    3023             : 
    3024             : /* {{{ proto object SoapClient::__getLastResponse ( void )
    3025             :    Returns last SOAP response */
    3026           6 : PHP_METHOD(SoapClient, __getLastResponse)
    3027             : {
    3028             :         zval **tmp;
    3029             : 
    3030           6 :         if (zend_parse_parameters_none() == FAILURE) {
    3031           0 :                 return;
    3032             :         }
    3033             :         
    3034          12 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__last_response", sizeof("__last_response"), (void **)&tmp) == SUCCESS &&
    3035           6 :             Z_TYPE_PP(tmp) == IS_STRING) {
    3036           6 :                 RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
    3037             :         }
    3038           0 :         RETURN_NULL();
    3039             : }
    3040             : /* }}} */
    3041             : 
    3042             : 
    3043             : /* {{{ proto string SoapClient::__getLastRequestHeaders(void)
    3044             :    Returns last SOAP request headers */
    3045           0 : PHP_METHOD(SoapClient, __getLastRequestHeaders)
    3046             : {
    3047             :         zval **tmp;
    3048             :         
    3049           0 :         if (zend_parse_parameters_none() == FAILURE) {
    3050           0 :                 return;
    3051             :         }
    3052             :         
    3053           0 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__last_request_headers", sizeof("__last_request_headers"), (void **)&tmp) == SUCCESS &&
    3054           0 :             Z_TYPE_PP(tmp) == IS_STRING) {
    3055           0 :                 RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
    3056             :         }
    3057           0 :         RETURN_NULL();
    3058             : }
    3059             : /* }}} */
    3060             : 
    3061             : 
    3062             : /* {{{ proto string SoapClient::__getLastResponseHeaders(void)
    3063             :    Returns last SOAP response headers */
    3064           0 : PHP_METHOD(SoapClient, __getLastResponseHeaders)
    3065             : {
    3066             :         zval **tmp;
    3067             :         
    3068           0 :         if (zend_parse_parameters_none() == FAILURE) {
    3069           0 :                 return;
    3070             :         }
    3071             : 
    3072           0 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__last_response_headers", sizeof("__last_response_headers"), (void **)&tmp) == SUCCESS &&
    3073           0 :             Z_TYPE_PP(tmp) == IS_STRING) {
    3074           0 :                 RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
    3075             :         }
    3076           0 :         RETURN_NULL();
    3077             : }
    3078             : /* }}} */
    3079             : 
    3080             : 
    3081             : /* {{{ proto string SoapClient::__doRequest()
    3082             :    SoapClient::__doRequest() */
    3083         317 : PHP_METHOD(SoapClient, __doRequest)
    3084             : {
    3085             :   char *buf, *location, *action;
    3086             :   int   buf_size, location_size, action_size;
    3087             :   long  version;
    3088         317 :   long  one_way = 0;
    3089             : 
    3090         317 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssl|l",
    3091             :             &buf, &buf_size,
    3092             :             &location, &location_size,
    3093             :             &action, &action_size,
    3094             :             &version, &one_way) == FAILURE) {
    3095           0 :                 return;
    3096             :         }
    3097         317 :         if (SOAP_GLOBAL(features) & SOAP_WAIT_ONE_WAY_CALLS) {
    3098           0 :                 one_way = 0;
    3099             :         }
    3100         317 :         if (one_way) {
    3101          85 :                 if (make_http_soap_request(this_ptr, buf, buf_size, location, action, version, NULL, NULL TSRMLS_CC)) {
    3102           0 :                         RETURN_EMPTY_STRING();
    3103             :                 }
    3104         232 :         } else if (make_http_soap_request(this_ptr, buf, buf_size, location, action, version,
    3105             :             &Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value) TSRMLS_CC)) {
    3106           1 :                 return_value->type = IS_STRING;
    3107           1 :                 return;
    3108             :         }
    3109         316 :         RETURN_NULL();
    3110             : }
    3111             : /* }}} */
    3112             : 
    3113             : /* {{{ proto void SoapClient::__setCookie(string name [, strung value])
    3114             :    Sets cookie thet will sent with SOAP request.
    3115             :    The call to this function will effect all folowing calls of SOAP methods.
    3116             :    If value is not specified cookie is removed. */
    3117           1 : PHP_METHOD(SoapClient, __setCookie)
    3118             : {
    3119             :         char *name;
    3120           1 :         char *val = NULL;
    3121           1 :         int  name_len, val_len = 0;
    3122             :         zval **cookies;
    3123             : 
    3124           1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &name, &name_len, &val, &val_len) == FAILURE) {
    3125           0 :                 return;
    3126             :         }
    3127             : 
    3128           1 :         if (val == NULL) {
    3129           0 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == SUCCESS &&
    3130           0 :                     Z_TYPE_PP(cookies) == IS_ARRAY) {
    3131           0 :                         zend_hash_del(Z_ARRVAL_PP(cookies), name, name_len+1);
    3132             :                 }
    3133             :         } else {
    3134             :                 zval *zcookie;
    3135             : 
    3136           1 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == FAILURE ||
    3137           0 :                     Z_TYPE_PP(cookies) != IS_ARRAY) {
    3138             :                         zval *tmp_cookies;
    3139             : 
    3140           1 :                         MAKE_STD_ZVAL(tmp_cookies);
    3141           1 :                         array_init(tmp_cookies);
    3142           1 :                         zend_hash_update(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), &tmp_cookies, sizeof(zval *), (void **)&cookies);
    3143             :                 }
    3144             : 
    3145           1 :                 ALLOC_INIT_ZVAL(zcookie);
    3146           1 :                 array_init(zcookie);
    3147           1 :                 add_index_stringl(zcookie, 0, val, val_len, 1);
    3148           1 :                 add_assoc_zval_ex(*cookies, name, name_len+1, zcookie);
    3149             :         }
    3150             : }
    3151             : /* }}} */
    3152             : 
    3153             : /* {{{ proto array SoapClient::__getCookies ( void )
    3154             :    Returns list of cookies */
    3155           1 : PHP_METHOD(SoapClient, __getCookies)
    3156             : {
    3157             :         zval **cookies, *tmp;
    3158             : 
    3159           1 :         if (zend_parse_parameters_none() == FAILURE) {
    3160           0 :                 return;
    3161             :         }
    3162             : 
    3163           1 :         array_init(return_value);
    3164             : 
    3165           2 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) != FAILURE &&
    3166           1 :             Z_TYPE_PP(cookies) == IS_ARRAY) {
    3167           1 :                 zend_hash_copy(Z_ARRVAL_P(return_value), Z_ARRVAL_P(*cookies), (copy_ctor_func_t) zval_add_ref, (void *)&tmp, sizeof(zval*));
    3168             :         }
    3169             : }
    3170             : /* }}} */
    3171             : 
    3172             : /* {{{ proto void SoapClient::__setSoapHeaders(array SoapHeaders)
    3173             :    Sets SOAP headers for subsequent calls (replaces any previous
    3174             :    values).
    3175             :    If no value is specified, all of the headers are removed. */
    3176           4 : PHP_METHOD(SoapClient, __setSoapHeaders)
    3177             : {
    3178           4 :         zval *headers = NULL;
    3179             : 
    3180           4 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &headers) == FAILURE) {
    3181           0 :                 return;
    3182             :         }
    3183             : 
    3184           5 :         if (headers == NULL || Z_TYPE_P(headers) == IS_NULL) {
    3185           1 :                 zend_hash_del(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers"));
    3186           3 :         } else if (Z_TYPE_P(headers) == IS_ARRAY) {
    3187             :                 zval *default_headers;
    3188             : 
    3189           2 :                 verify_soap_headers_array(Z_ARRVAL_P(headers) TSRMLS_CC);
    3190           2 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers"), (void **) &default_headers)==FAILURE) {
    3191           2 :                         add_property_zval(this_ptr, "__default_headers", headers);
    3192             :                 }
    3193           3 :         } else if (Z_TYPE_P(headers) == IS_OBJECT &&
    3194           1 :                    instanceof_function(Z_OBJCE_P(headers), soap_header_class_entry TSRMLS_CC)) {
    3195             :                 zval *default_headers;
    3196           1 :                 ALLOC_INIT_ZVAL(default_headers);
    3197           1 :                 array_init(default_headers);
    3198           1 :                 Z_ADDREF_P(headers);
    3199           1 :                 add_next_index_zval(default_headers, headers);
    3200             :                 Z_DELREF_P(default_headers);
    3201           1 :                 add_property_zval(this_ptr, "__default_headers", default_headers);
    3202             :         } else{
    3203           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid SOAP header");
    3204             :         }
    3205           4 :         RETURN_TRUE;
    3206             : }
    3207             : /* }}} */
    3208             : 
    3209             : 
    3210             : 
    3211             : /* {{{ proto string SoapClient::__setLocation([string new_location])
    3212             :    Sets the location option (the endpoint URL that will be touched by the 
    3213             :    following SOAP requests).
    3214             :    If new_location is not specified or null then SoapClient will use endpoint
    3215             :    from WSDL file. 
    3216             :    The function returns old value of location options. */
    3217           6 : PHP_METHOD(SoapClient, __setLocation)
    3218             : {
    3219           6 :         char *location = NULL;
    3220           6 :         int  location_len = 0;
    3221             :         zval **tmp;
    3222             : 
    3223           6 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &location, &location_len) == FAILURE) {
    3224           0 :                 return;
    3225             :         }
    3226             : 
    3227          10 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_STRING) {
    3228           4 :                 RETVAL_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
    3229             :         } else {
    3230           2 :           RETVAL_NULL();
    3231             :         }
    3232             : 
    3233           9 :         if (location && location_len) {
    3234           3 :                 add_property_stringl(this_ptr, "location", location, location_len, 1);
    3235             :         } else {
    3236           3 :                 zend_hash_del(Z_OBJPROP_P(this_ptr), "location", sizeof("location"));
    3237             :         }
    3238             : }
    3239             : /* }}} */
    3240             : 
    3241         398 : static void clear_soap_fault(zval *obj TSRMLS_DC)
    3242             : {
    3243         398 :         if (obj != NULL && obj->type == IS_OBJECT) {
    3244         398 :                 zend_hash_del(Z_OBJPROP_P(obj), "__soap_fault", sizeof("__soap_fault"));
    3245             :         }
    3246         398 : }
    3247             : 
    3248         326 : zval* add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail TSRMLS_DC)
    3249             : {
    3250             :         zval *fault;
    3251         326 :         ALLOC_INIT_ZVAL(fault);
    3252         326 :         set_soap_fault(fault, NULL, fault_code, fault_string, fault_actor, fault_detail, NULL TSRMLS_CC);
    3253             :         Z_DELREF_P(fault);
    3254             : 
    3255         326 :         add_property_zval(obj, "__soap_fault", fault);
    3256         326 :         return fault;
    3257             : }
    3258             : 
    3259         424 : static void set_soap_fault(zval *obj, char *fault_code_ns, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail, char *name TSRMLS_DC)
    3260             : {
    3261         424 :         if (Z_TYPE_P(obj) != IS_OBJECT) {
    3262         359 :                 object_init_ex(obj, soap_fault_class_entry);
    3263             :         }
    3264             :         
    3265         424 :         add_property_string(obj, "faultstring", fault_string ? fault_string : "", 1);
    3266         424 :         zend_update_property_string(zend_exception_get_default(TSRMLS_C), obj, "message", sizeof("message")-1, (fault_string ? fault_string : "") TSRMLS_CC);
    3267             :         
    3268         424 :         if (fault_code != NULL) {
    3269         424 :                 int soap_version = SOAP_GLOBAL(soap_version);
    3270             : 
    3271         424 :                 if (fault_code_ns) {
    3272           0 :                         add_property_string(obj, "faultcode", fault_code, 1);
    3273           0 :                         add_property_string(obj, "faultcodens", fault_code_ns, 1);
    3274             :                 } else {
    3275         424 :                         if (soap_version == SOAP_1_1) {
    3276         397 :                                 add_property_string(obj, "faultcode", fault_code, 1);
    3277        1444 :                                 if (strcmp(fault_code,"Client") == 0 ||
    3278         392 :                                     strcmp(fault_code,"Server") == 0 ||
    3279         328 :                                     strcmp(fault_code,"VersionMismatch") == 0 ||
    3280         327 :                                   strcmp(fault_code,"MustUnderstand") == 0) {
    3281          71 :                                         add_property_string(obj, "faultcodens", SOAP_1_1_ENV_NAMESPACE, 1);
    3282             :                                 }
    3283          27 :                         } else if (soap_version == SOAP_1_2) {
    3284          27 :                                 if (strcmp(fault_code,"Client") == 0) {
    3285           9 :                                         add_property_string(obj, "faultcode", "Sender", 1);
    3286           9 :                                         add_property_string(obj, "faultcodens", SOAP_1_2_ENV_NAMESPACE, 1);
    3287          18 :                                 } else if (strcmp(fault_code,"Server") == 0) {
    3288           8 :                                         add_property_string(obj, "faultcode", "Receiver", 1);
    3289           8 :                                         add_property_string(obj, "faultcodens", SOAP_1_2_ENV_NAMESPACE, 1);
    3290          30 :                                 } else if (strcmp(fault_code,"VersionMismatch") == 0 ||
    3291           9 :                                            strcmp(fault_code,"MustUnderstand") == 0 ||
    3292           5 :                                            strcmp(fault_code,"DataEncodingUnknown") == 0) {
    3293           6 :                                         add_property_string(obj, "faultcode", fault_code, 1);
    3294           6 :                                         add_property_string(obj, "faultcodens", SOAP_1_2_ENV_NAMESPACE, 1);
    3295             :                                 } else {
    3296           4 :                                         add_property_string(obj, "faultcode", fault_code, 1);
    3297             :                                 }
    3298             :                         }
    3299             :                 }
    3300             :         }
    3301         424 :         if (fault_actor != NULL) {
    3302           0 :                 add_property_string(obj, "faultactor", fault_actor, 1);
    3303             :         }
    3304         424 :         if (fault_detail != NULL) {
    3305          50 :                 add_property_zval(obj, "detail", fault_detail);
    3306             :         }
    3307         424 :         if (name != NULL) {
    3308          54 :                 add_property_string(obj, "_name", name, 1);
    3309             :         }
    3310         424 : }
    3311             : 
    3312         481 : static void deserialize_parameters(xmlNodePtr params, sdlFunctionPtr function, int *num_params, zval ***parameters TSRMLS_DC)
    3313             : {
    3314         481 :         int cur_param = 0,num_of_params = 0;
    3315         481 :         zval **tmp_parameters = NULL;
    3316             : 
    3317         481 :         if (function != NULL) {
    3318             :                 sdlParamPtr *param;
    3319             :                 xmlNodePtr val;
    3320         413 :                 int     use_names = 0;
    3321             : 
    3322         413 :                 if (function->requestParameters == NULL) {
    3323           0 :                         return;
    3324             :                 }
    3325         413 :                 num_of_params = zend_hash_num_elements(function->requestParameters);
    3326         413 :                 zend_hash_internal_pointer_reset(function->requestParameters);
    3327        1255 :                 while (zend_hash_get_current_data(function->requestParameters, (void **)&param) == SUCCESS) {
    3328         429 :                         if (get_node(params, (*param)->paramName) != NULL) {
    3329         308 :                                 use_names = 1;
    3330             :                         }
    3331         429 :                         zend_hash_move_forward(function->requestParameters);
    3332             :                 }
    3333         413 :                 if (use_names) {
    3334         251 :                         tmp_parameters = safe_emalloc(num_of_params, sizeof(zval *), 0);
    3335         251 :                         zend_hash_internal_pointer_reset(function->requestParameters);
    3336         805 :                         while (zend_hash_get_current_data(function->requestParameters, (void **)&param) == SUCCESS) {
    3337         308 :                                 val = get_node(params, (*param)->paramName);
    3338         308 :                                 if (!val) {
    3339             :                                         /* TODO: may be "nil" is not OK? */
    3340           0 :                                         MAKE_STD_ZVAL(tmp_parameters[cur_param]);
    3341           0 :                                         ZVAL_NULL(tmp_parameters[cur_param]);
    3342             :                                 } else {
    3343         308 :                                         tmp_parameters[cur_param] = master_to_zval((*param)->encode, val TSRMLS_CC);
    3344             :                                 }
    3345         303 :                                 cur_param++;
    3346             : 
    3347         303 :                                 zend_hash_move_forward(function->requestParameters);
    3348             :                         }
    3349         246 :                         (*parameters) = tmp_parameters;
    3350         246 :                         (*num_params) = num_of_params;
    3351         246 :                         return;
    3352             :                 }
    3353             :         }
    3354         230 :         if (params) {
    3355             :                 xmlNodePtr trav;
    3356             : 
    3357         157 :                 num_of_params = 0;
    3358         157 :                 trav = params;
    3359         491 :                 while (trav != NULL) {
    3360         177 :                         if (trav->type == XML_ELEMENT_NODE) {
    3361         175 :                                 num_of_params++;
    3362             :                         }
    3363         177 :                         trav = trav->next;
    3364             :                 }
    3365             : 
    3366         687 :                 if (num_of_params == 1 &&
    3367             :                     function &&
    3368         118 :                     function->binding &&
    3369         118 :                     function->binding->bindingType == BINDING_SOAP &&
    3370         118 :                     ((sdlSoapBindingFunctionPtr)function->bindingAttributes)->style == SOAP_DOCUMENT &&
    3371          87 :                     (function->requestParameters == NULL ||
    3372          87 :                      zend_hash_num_elements(function->requestParameters) == 0) &&
    3373           1 :                     strcmp((char *)params->name, function->functionName) == 0) {
    3374           1 :                         num_of_params = 0;
    3375         156 :                 } else if (num_of_params > 0) {
    3376         154 :                         tmp_parameters = safe_emalloc(num_of_params, sizeof(zval *), 0);
    3377             : 
    3378         154 :                         trav = params;
    3379         481 :                         while (trav != 0 && cur_param < num_of_params) {
    3380         174 :                                 if (trav->type == XML_ELEMENT_NODE) {
    3381             :                                         encodePtr enc;
    3382         174 :                                         sdlParamPtr *param = NULL;
    3383         294 :                                         if (function != NULL &&
    3384         120 :                                             zend_hash_index_find(function->requestParameters, cur_param, (void **)&param) == FAILURE) {
    3385             :                                                 TSRMLS_FETCH();
    3386           0 :                                                 soap_server_fault("Client", "Error cannot find parameter", NULL, NULL, NULL TSRMLS_CC);
    3387             :                                         }
    3388         174 :                                         if (param == NULL) {
    3389          54 :                                                 enc = NULL;
    3390             :                                         } else {
    3391         120 :                                                 enc = (*param)->encode;
    3392             :                                         }
    3393         174 :                                         tmp_parameters[cur_param] = master_to_zval(enc, trav TSRMLS_CC);
    3394         173 :                                         cur_param++;
    3395             :                                 }
    3396         173 :                                 trav = trav->next;
    3397             :                         }
    3398             :                 }
    3399             :         }
    3400         229 :         if (num_of_params > cur_param) {
    3401           0 :                 soap_server_fault("Client","Missing parameter", NULL, NULL, NULL TSRMLS_CC);
    3402             :         }
    3403         229 :         (*parameters) = tmp_parameters;
    3404         229 :         (*num_params) = num_of_params;
    3405             : }
    3406             : 
    3407         476 : static sdlFunctionPtr find_function(sdlPtr sdl, xmlNodePtr func, zval* function_name)
    3408             : {
    3409             :         sdlFunctionPtr function;
    3410             : 
    3411         476 :         function = get_function(sdl, (char*)func->name);
    3412         476 :         if (function && function->binding && function->binding->bindingType == BINDING_SOAP) {
    3413         339 :                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    3414         339 :                 if (fnb->style == SOAP_DOCUMENT) {
    3415          90 :                         if (func->children != NULL ||
    3416          13 :                             (function->requestParameters != NULL &&
    3417          13 :                              zend_hash_num_elements(function->requestParameters) > 0)) {
    3418          63 :                                 function = NULL;
    3419             :                         }
    3420             :                 }
    3421             :         }
    3422         476 :         if (sdl != NULL && function == NULL) {
    3423         139 :                 function = get_doc_function(sdl, func);
    3424             :         }
    3425             : 
    3426         476 :         INIT_ZVAL(*function_name);
    3427         476 :         if (function != NULL) {
    3428         386 :                 ZVAL_STRING(function_name, (char *)function->functionName, 1);
    3429             :         } else {
    3430          90 :                 ZVAL_STRING(function_name, (char *)func->name, 1);
    3431             :         }
    3432             : 
    3433         476 :         return function;
    3434             : }
    3435             : 
    3436         470 : static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, char* actor, zval *function_name, int *num_params, zval ***parameters, int *version, soapHeader **headers TSRMLS_DC)
    3437             : {
    3438         470 :         char* envelope_ns = NULL;
    3439             :         xmlNodePtr trav,env,head,body,func;
    3440             :         xmlAttrPtr attr;
    3441             :         sdlFunctionPtr function;
    3442             : 
    3443         470 :         encode_reset_ns();
    3444             : 
    3445             :         /* Get <Envelope> element */
    3446         470 :         env = NULL;
    3447         470 :         trav = request->children;
    3448        1408 :         while (trav != NULL) {
    3449         470 :                 if (trav->type == XML_ELEMENT_NODE) {
    3450         867 :                         if (env == NULL && node_is_equal_ex(trav,"Envelope",SOAP_1_1_ENV_NAMESPACE)) {
    3451         397 :                                 env = trav;
    3452         397 :                                 *version = SOAP_1_1;
    3453         397 :                                 envelope_ns = SOAP_1_1_ENV_NAMESPACE;
    3454         397 :                                 SOAP_GLOBAL(soap_version) = SOAP_1_1;
    3455         144 :                         } else if (env == NULL && node_is_equal_ex(trav,"Envelope",SOAP_1_2_ENV_NAMESPACE)) {
    3456          71 :                                 env = trav;
    3457          71 :                                 *version = SOAP_1_2;
    3458          71 :                                 envelope_ns = SOAP_1_2_ENV_NAMESPACE;
    3459          71 :                                 SOAP_GLOBAL(soap_version) = SOAP_1_2;
    3460             :                         } else {
    3461           2 :                                 soap_server_fault("VersionMismatch", "Wrong Version", NULL, NULL, NULL TSRMLS_CC);
    3462             :                         }
    3463             :                 }
    3464         468 :                 trav = trav->next;
    3465             :         }
    3466         468 :         if (env == NULL) {
    3467           0 :                 soap_server_fault("Client", "looks like we got XML without \"Envelope\" element", NULL, NULL, NULL TSRMLS_CC);
    3468             :         }
    3469             : 
    3470         468 :         attr = env->properties;
    3471        1218 :         while (attr != NULL) {
    3472         284 :                 if (attr->ns == NULL) {
    3473           1 :                         soap_server_fault("Client", "A SOAP Envelope element cannot have non Namespace qualified attributes", NULL, NULL, NULL TSRMLS_CC);
    3474         283 :                 } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
    3475           1 :                         if (*version == SOAP_1_2) {
    3476           1 :                                 soap_server_fault("Client", "encodingStyle cannot be specified on the Envelope", NULL, NULL, NULL TSRMLS_CC);
    3477           0 :                         } else if (strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) {
    3478           0 :                                 soap_server_fault("Client", "Unknown data encoding style", NULL, NULL, NULL TSRMLS_CC);
    3479             :                         }
    3480             :                 }
    3481         282 :                 attr = attr->next;
    3482             :         }
    3483             : 
    3484             :         /* Get <Header> element */
    3485         466 :         head = NULL;
    3486         466 :         trav = env->children;
    3487         933 :         while (trav != NULL && trav->type != XML_ELEMENT_NODE) {
    3488           1 :                 trav = trav->next;
    3489             :         }
    3490         466 :         if (trav != NULL && node_is_equal_ex(trav,"Header",envelope_ns)) {
    3491          48 :                 head = trav;
    3492          48 :                 trav = trav->next;
    3493             :         }
    3494             : 
    3495             :         /* Get <Body> element */
    3496         466 :         body = NULL;
    3497         932 :         while (trav != NULL && trav->type != XML_ELEMENT_NODE) {
    3498           0 :                 trav = trav->next;
    3499             :         }
    3500         466 :         if (trav != NULL && node_is_equal_ex(trav,"Body",envelope_ns)) {
    3501         465 :                 body = trav;
    3502         465 :                 trav = trav->next;
    3503             :         }
    3504         932 :         while (trav != NULL && trav->type != XML_ELEMENT_NODE) {
    3505           0 :                 trav = trav->next;
    3506             :         }
    3507         466 :         if (body == NULL) {
    3508           1 :                 soap_server_fault("Client", "Body must be present in a SOAP envelope", NULL, NULL, NULL TSRMLS_CC);
    3509             :         }
    3510         465 :         attr = body->properties;
    3511         931 :         while (attr != NULL) {
    3512           2 :                 if (attr->ns == NULL) {
    3513           0 :                         if (*version == SOAP_1_2) {
    3514           0 :                                 soap_server_fault("Client", "A SOAP Body element cannot have non Namespace qualified attributes", NULL, NULL, NULL TSRMLS_CC);
    3515             :                         }
    3516           2 :                 } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
    3517           1 :                         if (*version == SOAP_1_2) {
    3518           1 :                                 soap_server_fault("Client", "encodingStyle cannot be specified on the Body", NULL, NULL, NULL TSRMLS_CC);
    3519           0 :                         } else if (strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) {
    3520           0 :                                 soap_server_fault("Client", "Unknown data encoding style", NULL, NULL, NULL TSRMLS_CC);
    3521             :                         }
    3522             :                 }
    3523           1 :                 attr = attr->next;
    3524             :         }
    3525             : 
    3526         464 :         if (trav != NULL && *version == SOAP_1_2) {
    3527           1 :                 soap_server_fault("Client", "A SOAP 1.2 envelope can contain only Header and Body", NULL, NULL, NULL TSRMLS_CC);
    3528             :         }
    3529             : 
    3530         463 :         func = NULL;
    3531         463 :         trav = body->children;
    3532         955 :         while (trav != NULL) {
    3533         462 :                 if (trav->type == XML_ELEMENT_NODE) {
    3534             : /*
    3535             :                         if (func != NULL) {
    3536             :                                 soap_server_fault("Client", "looks like we got \"Body\" with several functions call", NULL, NULL, NULL TSRMLS_CC);
    3537             :                         }
    3538             : */
    3539         433 :                         func = trav;
    3540         433 :                         break; /* FIXME: the rest of body is ignored */
    3541             :                 }
    3542          29 :                 trav = trav->next;
    3543             :         }
    3544         463 :         if (func == NULL) {
    3545          30 :                 function = get_doc_function(sdl, NULL);
    3546          30 :                 if (function != NULL) {
    3547          30 :                         INIT_ZVAL(*function_name);
    3548          30 :                         ZVAL_STRING(function_name, (char *)function->functionName, 1);
    3549             :                 } else {
    3550           0 :                         soap_server_fault("Client", "looks like we got \"Body\" without function call", NULL, NULL, NULL TSRMLS_CC);
    3551             :                 }
    3552             :         } else {
    3553         433 :                 if (*version == SOAP_1_1) {
    3554         396 :                         attr = get_attribute_ex(func->properties,"encodingStyle",SOAP_1_1_ENV_NAMESPACE);
    3555         396 :                         if (attr && strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) {
    3556           0 :                                 soap_server_fault("Client","Unknown Data Encoding Style", NULL, NULL, NULL TSRMLS_CC);
    3557             :                         }
    3558             :                 } else {
    3559          37 :                         attr = get_attribute_ex(func->properties,"encodingStyle",SOAP_1_2_ENV_NAMESPACE);
    3560          37 :                         if (attr && strcmp((char*)attr->children->content,SOAP_1_2_ENC_NAMESPACE) != 0) {
    3561           1 :                                 soap_server_fault("DataEncodingUnknown","Unknown Data Encoding Style", NULL, NULL, NULL TSRMLS_CC);
    3562             :                         }
    3563             :                 }
    3564         432 :                 function = find_function(sdl, func, function_name);
    3565         432 :                 if (sdl != NULL && function == NULL) {
    3566           1 :                         if (*version == SOAP_1_2) {
    3567           1 :                                 soap_server_fault("rpc:ProcedureNotPresent","Procedure not present", NULL, NULL, NULL TSRMLS_CC);
    3568             :                         } else {
    3569           0 :                                 php_error(E_ERROR, "Procedure '%s' not present", func->name);
    3570             :                         }
    3571             :                 }
    3572             :         }
    3573             : 
    3574         461 :         *headers = NULL;
    3575         461 :         if (head) {
    3576          46 :                 soapHeader *h, *last = NULL;
    3577             : 
    3578          46 :                 attr = head->properties;
    3579          92 :                 while (attr != NULL) {
    3580           0 :                         if (attr->ns == NULL) {
    3581           0 :                                 soap_server_fault("Client", "A SOAP Header element cannot have non Namespace qualified attributes", NULL, NULL, NULL TSRMLS_CC);
    3582           0 :                         } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
    3583           0 :                                 if (*version == SOAP_1_2) {
    3584           0 :                                         soap_server_fault("Client", "encodingStyle cannot be specified on the Header", NULL, NULL, NULL TSRMLS_CC);
    3585           0 :                                 } else if (strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) {
    3586           0 :                                         soap_server_fault("Client", "Unknown data encoding style", NULL, NULL, NULL TSRMLS_CC);
    3587             :                                 }
    3588             :                         }
    3589           0 :                         attr = attr->next;
    3590             :                 }
    3591          46 :                 trav = head->children;
    3592         140 :                 while (trav != NULL) {
    3593          51 :                         if (trav->type == XML_ELEMENT_NODE) {
    3594          51 :                                 xmlNodePtr hdr_func = trav;
    3595          51 :                                 int mustUnderstand = 0;
    3596             : 
    3597          51 :                                 if (*version == SOAP_1_1) {
    3598          13 :                                         attr = get_attribute_ex(hdr_func->properties,"encodingStyle",SOAP_1_1_ENV_NAMESPACE);
    3599          13 :                                         if (attr && strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) {
    3600           0 :                                                 soap_server_fault("Client","Unknown Data Encoding Style", NULL, NULL, NULL TSRMLS_CC);
    3601             :                                         }
    3602          13 :                                         attr = get_attribute_ex(hdr_func->properties,"actor",envelope_ns);
    3603          13 :                                         if (attr != NULL) {
    3604           2 :                                                 if (strcmp((char*)attr->children->content,SOAP_1_1_ACTOR_NEXT) != 0 &&
    3605           0 :                                                     (actor == NULL || strcmp((char*)attr->children->content,actor) != 0)) {
    3606             :                                                   goto ignore_header;
    3607             :                                                 }
    3608             :                                         }
    3609          38 :                                 } else if (*version == SOAP_1_2) {
    3610          38 :                                         attr = get_attribute_ex(hdr_func->properties,"encodingStyle",SOAP_1_2_ENV_NAMESPACE);
    3611          38 :                                         if (attr && strcmp((char*)attr->children->content,SOAP_1_2_ENC_NAMESPACE) != 0) {
    3612           0 :                                                 soap_server_fault("DataEncodingUnknown","Unknown Data Encoding Style", NULL, NULL, NULL TSRMLS_CC);
    3613             :                                         }
    3614          38 :                                         attr = get_attribute_ex(hdr_func->properties,"role",envelope_ns);
    3615          38 :                                         if (attr != NULL) {
    3616          52 :                                                 if (strcmp((char*)attr->children->content,SOAP_1_2_ACTOR_UNLIMATERECEIVER) != 0 &&
    3617          16 :                                                     strcmp((char*)attr->children->content,SOAP_1_2_ACTOR_NEXT) != 0 &&
    3618          10 :                                                     (actor == NULL || strcmp((char*)attr->children->content,actor) != 0)) {
    3619             :                                                   goto ignore_header;
    3620             :                                                 }
    3621             :                                         }
    3622             :                                 }
    3623          47 :                                 attr = get_attribute_ex(hdr_func->properties,"mustUnderstand",envelope_ns);
    3624          47 :                                 if (attr) {
    3625          53 :                                         if (strcmp((char*)attr->children->content,"1") == 0 ||
    3626          10 :                                             strcmp((char*)attr->children->content,"true") == 0) {
    3627          18 :                                                 mustUnderstand = 1;
    3628          17 :                                         } else if (strcmp((char*)attr->children->content,"0") == 0 ||
    3629           6 :                                                    strcmp((char*)attr->children->content,"false") == 0) {
    3630           4 :                                                 mustUnderstand = 0;
    3631             :                                         } else {
    3632           3 :                                                 soap_server_fault("Client","mustUnderstand value is not boolean", NULL, NULL, NULL TSRMLS_CC);
    3633             :                                         }
    3634             :                                 }
    3635          44 :                                 h = emalloc(sizeof(soapHeader));
    3636          44 :                                 memset(h, 0, sizeof(soapHeader));
    3637          44 :                                 h->mustUnderstand = mustUnderstand;
    3638          44 :                                 h->function = find_function(sdl, hdr_func, &h->function_name);
    3639          44 :                                 if (!h->function && sdl && function && function->binding && function->binding->bindingType == BINDING_SOAP) {
    3640             :                                         sdlSoapBindingFunctionHeaderPtr *hdr;
    3641          28 :                                         sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    3642          28 :                                         if (fnb->input.headers) {
    3643          23 :                                                 smart_str key = {0};
    3644             : 
    3645          23 :                                                 if (hdr_func->ns) {
    3646          23 :                                                         smart_str_appends(&key, (char*)hdr_func->ns->href);
    3647          23 :                                                         smart_str_appendc(&key, ':');
    3648             :                                                 }
    3649          23 :                                                 smart_str_appendl(&key, Z_STRVAL(h->function_name), Z_STRLEN(h->function_name));
    3650          23 :                                                 smart_str_0(&key);
    3651          23 :                                                 if (zend_hash_find(fnb->input.headers, key.c, key.len+1, (void**)&hdr) == SUCCESS) {
    3652          21 :                                                         h->hdr = *hdr;
    3653             :                                                 }
    3654          23 :                                                 smart_str_free(&key);
    3655             :                                         }
    3656             :                                 }
    3657          44 :                                 if (h->hdr) {
    3658          21 :                                         h->num_params = 1;
    3659          21 :                                         h->parameters = emalloc(sizeof(zval*));
    3660          21 :                                         h->parameters[0] = master_to_zval(h->hdr->encode, hdr_func TSRMLS_CC);
    3661             :                                 } else {
    3662          23 :                                         if (h->function && h->function->binding && h->function->binding->bindingType == BINDING_SOAP) {
    3663          15 :                                                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)h->function->bindingAttributes;
    3664          15 :                                                 if (fnb->style == SOAP_RPC) {
    3665           0 :                                                         hdr_func = hdr_func->children;
    3666             :                                                 }
    3667             :                                         }
    3668          23 :                                         deserialize_parameters(hdr_func, h->function, &h->num_params, &h->parameters TSRMLS_CC);
    3669             :                                 }
    3670          44 :                                 INIT_ZVAL(h->retval);
    3671          44 :                                 if (last == NULL) {
    3672          40 :                                         *headers = h;
    3673             :                                 } else {
    3674           4 :                                         last->next = h;
    3675             :                                 }
    3676          44 :                                 last = h;
    3677             :                         }
    3678             : ignore_header:
    3679          48 :                         trav = trav->next;
    3680             :                 }
    3681             :         }
    3682             : 
    3683         856 :         if (function && function->binding && function->binding->bindingType == BINDING_SOAP) {
    3684         398 :                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    3685         398 :                 if (fnb->style == SOAP_RPC) {
    3686         275 :                         func = func->children;
    3687             :                 }
    3688             :         } else {
    3689          60 :                 func = func->children;
    3690             :         }
    3691         458 :         deserialize_parameters(func, function, num_params, parameters TSRMLS_CC);
    3692             :         
    3693         452 :         encode_finish();
    3694             : 
    3695         452 :         return function;
    3696             : }
    3697             : 
    3698          32 : static void set_soap_header_attributes(xmlNodePtr h, HashTable *ht, int version)
    3699             : {
    3700             :         zval **tmp;
    3701             : 
    3702          96 :         if (zend_hash_find(ht, "mustUnderstand", sizeof("mustUnderstand"), (void**)&tmp) == SUCCESS &&
    3703          64 :             Z_TYPE_PP(tmp) == IS_BOOL && Z_LVAL_PP(tmp)) {
    3704           8 :                 if (version == SOAP_1_1) {
    3705           8 :                         xmlSetProp(h, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX":mustUnderstand"), BAD_CAST("1"));
    3706             :                 } else {
    3707           0 :                         xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":mustUnderstand"), BAD_CAST("true"));
    3708             :                 }
    3709             :         }
    3710          32 :         if (zend_hash_find(ht, "actor", sizeof("actor"), (void**)&tmp) == SUCCESS) {
    3711           2 :                 if (Z_TYPE_PP(tmp) == IS_STRING) {
    3712           0 :                         if (version == SOAP_1_1) {
    3713           0 :                                 xmlSetProp(h, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX":actor"), BAD_CAST(Z_STRVAL_PP(tmp)));
    3714             :                         } else {
    3715           0 :                                 xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(Z_STRVAL_PP(tmp)));
    3716             :                         }
    3717           2 :                 } else if (Z_TYPE_PP(tmp) == IS_LONG) {
    3718           2 :                         if (version == SOAP_1_1) {
    3719           2 :                                 if (Z_LVAL_PP(tmp) == SOAP_ACTOR_NEXT) {
    3720           2 :                                         xmlSetProp(h, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX":actor"), BAD_CAST(SOAP_1_1_ACTOR_NEXT));
    3721             :                                 }
    3722             :                         } else {
    3723           0 :                                 if (Z_LVAL_PP(tmp) == SOAP_ACTOR_NEXT) {
    3724           0 :                                         xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(SOAP_1_2_ACTOR_NEXT));
    3725           0 :                                 } else if (Z_LVAL_PP(tmp) == SOAP_ACTOR_NONE) {
    3726           0 :                                         xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(SOAP_1_2_ACTOR_NONE));
    3727           0 :                                 } else if (Z_LVAL_PP(tmp) == SOAP_ACTOR_UNLIMATERECEIVER) {
    3728           0 :                                         xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(SOAP_1_2_ACTOR_UNLIMATERECEIVER));
    3729             :                                 }
    3730             :                         }
    3731             :                 }
    3732             :         }
    3733          32 : }
    3734             : 
    3735         390 : static int serialize_response_call2(xmlNodePtr body, sdlFunctionPtr function, char *function_name, char *uri, zval *ret, int version, int main, xmlNodePtr *node TSRMLS_DC)
    3736             : {
    3737         390 :         xmlNodePtr method = NULL, param;
    3738         390 :         sdlParamPtr parameter = NULL;
    3739             :         int param_count;
    3740             :         int style, use;
    3741         390 :         xmlNsPtr ns = NULL;
    3742             : 
    3743         731 :         if (function != NULL && function->binding->bindingType == BINDING_SOAP) {
    3744         341 :                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    3745             : 
    3746         341 :                 style = fnb->style;
    3747         341 :                 use = fnb->output.use;
    3748         341 :                 if (style == SOAP_RPC) {
    3749         239 :                         ns = encode_add_ns(body, fnb->output.ns);
    3750         239 :                         if (function->responseName) {
    3751         157 :                                 method = xmlNewChild(body, ns, BAD_CAST(function->responseName), NULL);
    3752          82 :                         } else if (function->responseParameters) {
    3753           0 :                                 method = xmlNewChild(body, ns, BAD_CAST(function->functionName), NULL);
    3754             :                         }
    3755             :                 }
    3756             :         } else {
    3757          49 :                 style = main?SOAP_RPC:SOAP_DOCUMENT;
    3758          49 :                 use = main?SOAP_ENCODED:SOAP_LITERAL;
    3759          49 :                 if (style == SOAP_RPC) {
    3760          49 :                         ns = encode_add_ns(body, uri);
    3761          49 :                         method = xmlNewChild(body, ns, BAD_CAST(function_name), NULL);
    3762             :                 }
    3763             :         }
    3764             : 
    3765         390 :         if (function != NULL) {
    3766         341 :                 if (function->responseParameters) {
    3767         259 :                         param_count = zend_hash_num_elements(function->responseParameters);
    3768             :                 } else {
    3769          82 :                   param_count = 0;
    3770             :                 }
    3771             :         } else {
    3772          49 :           param_count = 1;
    3773             :         }
    3774             : 
    3775         390 :         if (param_count == 1) {
    3776         275 :                 parameter = get_param(function, NULL, 0, TRUE);
    3777             : 
    3778         275 :                 if (style == SOAP_RPC) {
    3779             :                   xmlNode *rpc_result;
    3780         218 :                         if (main && version == SOAP_1_2) {
    3781          23 :                                 xmlNs *rpc_ns = xmlNewNs(body, BAD_CAST(RPC_SOAP12_NAMESPACE), BAD_CAST(RPC_SOAP12_NS_PREFIX));
    3782          23 :                                 rpc_result = xmlNewChild(method, rpc_ns, BAD_CAST("result"), NULL);
    3783          23 :                                 param = serialize_parameter(parameter, ret, 0, "return", use, method TSRMLS_CC);
    3784          23 :                                 xmlNodeSetContent(rpc_result,param->name);
    3785             :                         } else {
    3786         172 :                                 param = serialize_parameter(parameter, ret, 0, "return", use, method TSRMLS_CC);
    3787             :                         }
    3788             :                 } else {
    3789          80 :                         param = serialize_parameter(parameter, ret, 0, "return", use, body TSRMLS_CC);
    3790         160 :                         if (function && function->binding->bindingType == BINDING_SOAP) {
    3791          80 :                                 if (parameter && parameter->element) {
    3792          75 :                                         ns = encode_add_ns(param, parameter->element->namens);
    3793          75 :                                         xmlNodeSetName(param, BAD_CAST(parameter->element->name));
    3794          75 :                                         xmlSetNs(param, ns);
    3795             :                                 }
    3796           0 :                         } else if (strcmp((char*)param->name,"return") == 0) {
    3797           0 :                                 ns = encode_add_ns(param, uri);
    3798           0 :                                 xmlNodeSetName(param, BAD_CAST(function_name));
    3799           0 :                                 xmlSetNs(param, ns);
    3800             :                         }
    3801             :                 }
    3802         115 :         } else if (param_count > 1 && Z_TYPE_P(ret) == IS_ARRAY) {
    3803             :                 HashPosition pos;
    3804             :                 zval **data;
    3805           4 :                 int i = 0;
    3806             : 
    3807           4 :                 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(ret), &pos);
    3808          20 :                 while (zend_hash_get_current_data_ex(Z_ARRVAL_P(ret), (void **)&data, &pos) != FAILURE) {
    3809          12 :                         char *param_name = NULL;
    3810             :                         unsigned int param_name_len;
    3811          12 :                         ulong param_index = i;
    3812             : 
    3813          12 :                         zend_hash_get_current_key_ex(Z_ARRVAL_P(ret), &param_name, &param_name_len, &param_index, 0, &pos);
    3814          12 :                         parameter = get_param(function, param_name, param_index, TRUE);
    3815          12 :                         if (style == SOAP_RPC) {
    3816          12 :                                 param = serialize_parameter(parameter, *data, i, param_name, use, method TSRMLS_CC);
    3817             :                         } else {
    3818           0 :                                 param = serialize_parameter(parameter, *data, i, param_name, use, body TSRMLS_CC);
    3819           0 :                                 if (function && function->binding->bindingType == BINDING_SOAP) {
    3820           0 :                                         if (parameter && parameter->element) {
    3821           0 :                                                 ns = encode_add_ns(param, parameter->element->namens);
    3822           0 :                                                 xmlNodeSetName(param, BAD_CAST(parameter->element->name));
    3823           0 :                                                 xmlSetNs(param, ns);
    3824             :                                         }
    3825             :                                 }
    3826             :                         }
    3827             : 
    3828          12 :                         zend_hash_move_forward_ex(Z_ARRVAL_P(ret), &pos);
    3829          12 :                         i++;
    3830             :                 }
    3831             :         }
    3832         389 :         if (use == SOAP_ENCODED && version == SOAP_1_2 && method != NULL) {
    3833          26 :                 xmlSetNsProp(method, body->ns, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_2_ENC_NAMESPACE));
    3834             :         }
    3835         389 :         if (node) {
    3836          14 :                 *node = method;
    3837             :         }
    3838         389 :         return use;
    3839             : }
    3840             : 
    3841         472 : static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function_name, char *uri, zval *ret, soapHeader* headers, int version TSRMLS_DC)
    3842             : {
    3843             :         xmlDocPtr doc;
    3844         472 :         xmlNodePtr envelope = NULL, body, param;
    3845         472 :         xmlNsPtr ns = NULL;
    3846         472 :         int use = SOAP_LITERAL;
    3847         472 :         xmlNodePtr head = NULL;
    3848             : 
    3849         472 :         encode_reset_ns();
    3850             : 
    3851         472 :         doc = xmlNewDoc(BAD_CAST("1.0"));
    3852         472 :         doc->charset = XML_CHAR_ENCODING_UTF8;
    3853         472 :         doc->encoding = xmlCharStrdup("UTF-8");
    3854             : 
    3855         472 :         if (version == SOAP_1_1) {
    3856         397 :                 envelope = xmlNewDocNode(doc, NULL, BAD_CAST("Envelope"), NULL);
    3857         397 :                 ns = xmlNewNs(envelope, BAD_CAST(SOAP_1_1_ENV_NAMESPACE), BAD_CAST(SOAP_1_1_ENV_NS_PREFIX));
    3858         397 :                 xmlSetNs(envelope,ns);
    3859          75 :         } else if (version == SOAP_1_2) {
    3860          75 :                 envelope = xmlNewDocNode(doc, NULL, BAD_CAST("Envelope"), NULL);
    3861          75 :                 ns = xmlNewNs(envelope, BAD_CAST(SOAP_1_2_ENV_NAMESPACE), BAD_CAST(SOAP_1_2_ENV_NS_PREFIX));
    3862          75 :                 xmlSetNs(envelope,ns);
    3863             :         } else {
    3864           0 :                 soap_server_fault("Server", "Unknown SOAP version", NULL, NULL, NULL TSRMLS_CC);
    3865             :         }
    3866         472 :         xmlDocSetRootElement(doc, envelope);
    3867             : 
    3868         722 :         if (Z_TYPE_P(ret) == IS_OBJECT &&
    3869         154 :             instanceof_function(Z_OBJCE_P(ret), soap_fault_class_entry TSRMLS_CC)) {
    3870             :           char *detail_name;
    3871             :                 HashTable* prop;
    3872             :                 zval **tmp;
    3873          96 :                 sdlFaultPtr fault = NULL;
    3874          96 :                 char *fault_ns = NULL;
    3875             : 
    3876          96 :                 prop = Z_OBJPROP_P(ret);
    3877             : 
    3878          97 :                 if (headers &&
    3879           1 :                     zend_hash_find(prop, "headerfault", sizeof("headerfault"), (void**)&tmp) == SUCCESS) {
    3880           1 :                         encodePtr hdr_enc = NULL;
    3881           1 :                         int hdr_use = SOAP_LITERAL;
    3882           1 :                         zval *hdr_ret  = *tmp;
    3883           1 :                         char *hdr_ns   = headers->hdr?headers->hdr->ns:NULL;
    3884           1 :                         char *hdr_name = Z_STRVAL(headers->function_name);
    3885             : 
    3886           1 :                         head = xmlNewChild(envelope, ns, BAD_CAST("Header"), NULL);
    3887           2 :                         if (Z_TYPE_P(hdr_ret) == IS_OBJECT &&
    3888           1 :                             instanceof_function(Z_OBJCE_P(hdr_ret), soap_header_class_entry TSRMLS_CC)) {
    3889           1 :                                 HashTable* ht = Z_OBJPROP_P(hdr_ret);
    3890             :                                 sdlSoapBindingFunctionHeaderPtr *hdr;
    3891           1 :                                 smart_str key = {0};
    3892             : 
    3893           2 :                                 if (zend_hash_find(ht, "namespace", sizeof("namespace"), (void**)&tmp) == SUCCESS &&
    3894           1 :                               Z_TYPE_PP(tmp) == IS_STRING) {
    3895           1 :                                         smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
    3896           1 :                                         smart_str_appendc(&key, ':');
    3897           1 :                                         hdr_ns = Z_STRVAL_PP(tmp);
    3898             :                                 }
    3899           2 :                                 if (zend_hash_find(ht, "name", sizeof("name"), (void**)&tmp) == SUCCESS &&
    3900           1 :                                     Z_TYPE_PP(tmp) == IS_STRING) {
    3901           1 :                                         smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
    3902           1 :                                         hdr_name = Z_STRVAL_PP(tmp);
    3903             :                                 }
    3904           1 :                                 smart_str_0(&key);
    3905           2 :                                 if (headers->hdr && headers->hdr->headerfaults &&
    3906           1 :                                     zend_hash_find(headers->hdr->headerfaults, key.c, key.len+1, (void**)&hdr) == SUCCESS) {
    3907           1 :                                         hdr_enc = (*hdr)->encode;
    3908           1 :                                         hdr_use = (*hdr)->use;
    3909             :                                 }
    3910           1 :                                 smart_str_free(&key);
    3911           1 :                                 if (zend_hash_find(ht, "data", sizeof("data"), (void**)&tmp) == SUCCESS) {
    3912           1 :                                         hdr_ret = *tmp;
    3913             :                                 } else {
    3914           0 :                                         hdr_ret = NULL;
    3915             :                                 }
    3916             :                         }
    3917             : 
    3918           1 :                         if (headers->function) {
    3919           0 :                                 if (serialize_response_call2(head, headers->function, Z_STRVAL(headers->function_name), uri, hdr_ret, version, 0, NULL TSRMLS_CC) == SOAP_ENCODED) {
    3920           0 :                                         use = SOAP_ENCODED;
    3921             :                                 }
    3922             :                         } else {
    3923           1 :                                 xmlNodePtr xmlHdr = master_to_xml(hdr_enc, hdr_ret, hdr_use, head TSRMLS_CC);
    3924           1 :                                 if (hdr_name) {
    3925           1 :                                         xmlNodeSetName(xmlHdr, BAD_CAST(hdr_name));
    3926             :                                 }
    3927           1 :                                 if (hdr_ns) {
    3928           1 :                                         xmlNsPtr nsptr = encode_add_ns(xmlHdr, hdr_ns);
    3929           1 :                                         xmlSetNs(xmlHdr, nsptr);
    3930             :                                 }
    3931             :                         }
    3932             :                 }
    3933             : 
    3934          96 :                 body = xmlNewChild(envelope, ns, BAD_CAST("Body"), NULL);
    3935          96 :                 param = xmlNewChild(body, ns, BAD_CAST("Fault"), NULL);
    3936             : 
    3937          96 :                 if (zend_hash_find(prop, "faultcodens", sizeof("faultcodens"), (void**)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_STRING) {
    3938          89 :                         fault_ns = Z_STRVAL_PP(tmp);
    3939             :                 }
    3940          96 :                 use = SOAP_LITERAL;
    3941         150 :                 if (zend_hash_find(prop, "_name", sizeof("_name"), (void**)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_STRING) {
    3942             :                         sdlFaultPtr *tmp_fault;
    3943         108 :                         if (function && function->faults &&
    3944          54 :                             zend_hash_find(function->faults, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)+1, (void**)&tmp_fault) == SUCCESS) {
    3945          54 :                           fault = *tmp_fault;
    3946         162 :                                 if (function->binding &&
    3947          54 :                                     function->binding->bindingType == BINDING_SOAP &&
    3948          54 :                                     fault->bindingAttributes) {
    3949          53 :                                         sdlSoapBindingFunctionFaultPtr fb = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
    3950          53 :                                         use = fb->use;
    3951          53 :                                         if (fault_ns == NULL) {
    3952           0 :                                                 fault_ns = fb->ns;
    3953             :                                         }
    3954             :                                 }
    3955             :                         }
    3956          42 :                 } else if (function && function->faults &&
    3957           0 :                            zend_hash_num_elements(function->faults) == 1) {
    3958             : 
    3959           0 :                         zend_hash_internal_pointer_reset(function->faults);
    3960           0 :                         zend_hash_get_current_data(function->faults, (void**)&fault);
    3961           0 :                         fault = *(sdlFaultPtr*)fault;
    3962           0 :                         if (function->binding &&
    3963           0 :                             function->binding->bindingType == BINDING_SOAP &&
    3964           0 :                             fault->bindingAttributes) {
    3965           0 :                                 sdlSoapBindingFunctionFaultPtr fb = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
    3966           0 :                                 use = fb->use;
    3967           0 :                                 if (fault_ns == NULL) {
    3968           0 :                                   fault_ns = fb->ns;
    3969             :                                 }
    3970             :                         }
    3971             :                 }
    3972             : 
    3973         103 :                 if (fault_ns == NULL &&
    3974           7 :                     fault && 
    3975           0 :                     fault->details && 
    3976           0 :                     zend_hash_num_elements(fault->details) == 1) {
    3977             :                         sdlParamPtr sparam;
    3978             : 
    3979           0 :                         zend_hash_internal_pointer_reset(fault->details);
    3980           0 :                         zend_hash_get_current_data(fault->details, (void**)&sparam);
    3981           0 :                         sparam = *(sdlParamPtr*)sparam;
    3982           0 :                         if (sparam->element) {
    3983           0 :                                 fault_ns = sparam->element->namens;
    3984             :                         }
    3985             :                 }
    3986             : 
    3987          96 :                 if (version == SOAP_1_1) {
    3988         142 :                         if (zend_hash_find(prop, "faultcode", sizeof("faultcode"), (void**)&tmp) == SUCCESS &&
    3989          71 :                             Z_TYPE_PP(tmp) == IS_STRING) {
    3990             :                                 size_t new_len;
    3991          71 :                                 xmlNodePtr node = xmlNewNode(NULL, BAD_CAST("faultcode"));
    3992          71 :                                 char *str = php_escape_html_entities((unsigned char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), &new_len, 0, 0, NULL TSRMLS_CC);
    3993          71 :                                 xmlAddChild(param, node);
    3994          71 :                                 if (fault_ns) {
    3995          66 :                                         xmlNsPtr nsptr = encode_add_ns(node, fault_ns);
    3996          66 :                                         xmlChar *code = xmlBuildQName(BAD_CAST(str), nsptr->prefix, NULL, 0);
    3997          66 :                                         xmlNodeSetContent(node, code);
    3998          66 :                                         xmlFree(code);
    3999             :                                 } else {        
    4000           5 :                                         xmlNodeSetContentLen(node, BAD_CAST(str), (int)new_len);
    4001             :                                 }
    4002          71 :                                 efree(str);
    4003             :                         }
    4004          71 :                         if (zend_hash_find(prop, "faultstring", sizeof("faultstring"), (void**)&tmp) == SUCCESS) {
    4005          71 :                                 xmlNodePtr node = master_to_xml(get_conversion(IS_STRING), *tmp, SOAP_LITERAL, param TSRMLS_CC);
    4006          71 :                                 xmlNodeSetName(node, BAD_CAST("faultstring"));
    4007             :                         }
    4008          71 :                         if (zend_hash_find(prop, "faultactor", sizeof("faultactor"), (void**)&tmp) == SUCCESS) {
    4009           0 :                                 xmlNodePtr node = master_to_xml(get_conversion(IS_STRING), *tmp, SOAP_LITERAL, param TSRMLS_CC);
    4010           0 :                                 xmlNodeSetName(node, BAD_CAST("faultactor"));
    4011             :                         }
    4012          71 :                         detail_name = "detail";
    4013             :                 } else {
    4014          50 :                         if (zend_hash_find(prop, "faultcode", sizeof("faultcode"), (void**)&tmp) == SUCCESS &&
    4015          25 :                             Z_TYPE_PP(tmp) == IS_STRING) {
    4016             :                                 size_t new_len;
    4017          25 :                                 xmlNodePtr node = xmlNewChild(param, ns, BAD_CAST("Code"), NULL);
    4018          25 :                                 char *str = php_escape_html_entities((unsigned char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), &new_len, 0, 0, NULL TSRMLS_CC);
    4019          25 :                                 node = xmlNewChild(node, ns, BAD_CAST("Value"), NULL);
    4020          25 :                                 if (fault_ns) {
    4021          23 :                                         xmlNsPtr nsptr = encode_add_ns(node, fault_ns);
    4022          23 :                                         xmlChar *code = xmlBuildQName(BAD_CAST(str), nsptr->prefix, NULL, 0);
    4023          23 :                                         xmlNodeSetContent(node, code);
    4024          23 :                                         xmlFree(code);
    4025             :                                 } else {        
    4026           2 :                                         xmlNodeSetContentLen(node, BAD_CAST(str), (int)new_len);
    4027             :                                 }
    4028          25 :                                 efree(str);
    4029             :                         }
    4030          25 :                         if (zend_hash_find(prop, "faultstring", sizeof("faultstring"), (void**)&tmp) == SUCCESS) {
    4031          25 :                                 xmlNodePtr node = xmlNewChild(param, ns, BAD_CAST("Reason"), NULL);
    4032          25 :                                 node = master_to_xml(get_conversion(IS_STRING), *tmp, SOAP_LITERAL, node TSRMLS_CC);
    4033          25 :                                 xmlNodeSetName(node, BAD_CAST("Text"));
    4034          25 :                                 xmlSetNs(node, ns);
    4035             :                         }
    4036          25 :                         detail_name = SOAP_1_2_ENV_NS_PREFIX":Detail";
    4037             :                 }
    4038         150 :                 if (fault && fault->details && zend_hash_num_elements(fault->details) == 1) {
    4039             :                         xmlNodePtr node;
    4040          54 :                         zval *detail = NULL;
    4041             :                         sdlParamPtr sparam;
    4042             :                         xmlNodePtr x;
    4043             : 
    4044         102 :                         if (zend_hash_find(prop, "detail", sizeof("detail"), (void**)&tmp) == SUCCESS &&
    4045          48 :                             Z_TYPE_PP(tmp) != IS_NULL) {
    4046          48 :                                 detail = *tmp;
    4047             :                         }
    4048          54 :                         node = xmlNewNode(NULL, BAD_CAST(detail_name));
    4049          54 :                         xmlAddChild(param, node);
    4050             : 
    4051          54 :                         zend_hash_internal_pointer_reset(fault->details);
    4052          54 :                         zend_hash_get_current_data(fault->details, (void**)&sparam);
    4053          54 :                         sparam = *(sdlParamPtr*)sparam;
    4054             : 
    4055         133 :                         if (detail &&
    4056          48 :                             Z_TYPE_P(detail) == IS_OBJECT &&
    4057          18 :                             sparam->element &&
    4058          10 :                             zend_hash_num_elements(Z_OBJPROP_P(detail)) == 1 &&
    4059           3 :                             zend_hash_find(Z_OBJPROP_P(detail), sparam->element->name, strlen(sparam->element->name)+1, (void**)&tmp) == SUCCESS) {
    4060           0 :                                 detail = *tmp;
    4061             :                         }
    4062             : 
    4063          54 :                         x = serialize_parameter(sparam, detail, 1, NULL, use, node TSRMLS_CC);
    4064             : 
    4065         216 :                         if (function &&
    4066          54 :                             function->binding &&
    4067          54 :                             function->binding->bindingType == BINDING_SOAP &&
    4068          54 :                             function->bindingAttributes) {
    4069          54 :                                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    4070          81 :                                 if (fnb->style == SOAP_RPC && !sparam->element) {
    4071          27 :                                   if (fault->bindingAttributes) {
    4072          27 :                                                 sdlSoapBindingFunctionFaultPtr fb = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
    4073          27 :                                                 if (fb->ns) {
    4074          27 :                                                         xmlNsPtr ns = encode_add_ns(x, fb->ns);
    4075          27 :                                                         xmlSetNs(x, ns);
    4076             :                                                 }
    4077             :                                         }
    4078             :                                 } else {
    4079          27 :                                         if (sparam->element) {
    4080          27 :                                                 ns = encode_add_ns(x, sparam->element->namens);
    4081          27 :                                                 xmlNodeSetName(x, BAD_CAST(sparam->element->name));
    4082          27 :                                                 xmlSetNs(x, ns);
    4083             :                                         }
    4084             :                                 }
    4085             :                         }
    4086          54 :                         if (use == SOAP_ENCODED && version == SOAP_1_2) {
    4087           0 :                                 xmlSetNsProp(x, envelope->ns, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_2_ENC_NAMESPACE));
    4088             :                         }
    4089          42 :                 } else if (zend_hash_find(prop, "detail", sizeof("detail"), (void**)&tmp) == SUCCESS &&
    4090           0 :                     Z_TYPE_PP(tmp) != IS_NULL) {
    4091           0 :                         serialize_zval(*tmp, NULL, detail_name, use, param TSRMLS_CC);
    4092             :                 }
    4093             :         } else {
    4094             : 
    4095         376 :                 if (headers) {
    4096             :                         soapHeader *h;
    4097             : 
    4098          35 :                         head = xmlNewChild(envelope, ns, BAD_CAST("Header"), NULL);
    4099          35 :                         h = headers;
    4100         112 :                         while (h != NULL) {
    4101          42 :                                 if (Z_TYPE(h->retval) != IS_NULL) {
    4102          27 :                                         encodePtr hdr_enc = NULL;
    4103          27 :                                         int hdr_use = SOAP_LITERAL;
    4104          27 :                                         zval *hdr_ret = &h->retval;
    4105          27 :                                         char *hdr_ns   = h->hdr?h->hdr->ns:NULL;
    4106          27 :                                         char *hdr_name = Z_STRVAL(h->function_name);
    4107          27 :                                         HashTable *ht = NULL;
    4108             : 
    4109          40 :                                         if (Z_TYPE(h->retval) == IS_OBJECT &&
    4110          13 :                                             instanceof_function(Z_OBJCE(h->retval), soap_header_class_entry TSRMLS_CC)) {
    4111             :                                                 zval **tmp;
    4112             :                                                 sdlSoapBindingFunctionHeaderPtr *hdr;
    4113          13 :                                                 smart_str key = {0};
    4114             : 
    4115          13 :                                                 ht = Z_OBJPROP(h->retval);
    4116          26 :                                                 if (zend_hash_find(ht, "namespace", sizeof("namespace"), (void**)&tmp) == SUCCESS &&
    4117          13 :                                               Z_TYPE_PP(tmp) == IS_STRING) {
    4118          13 :                                                         smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
    4119          13 :                                                         smart_str_appendc(&key, ':');
    4120          13 :                                                         hdr_ns = Z_STRVAL_PP(tmp);
    4121             :                                                 }
    4122          26 :                                                 if (zend_hash_find(ht, "name", sizeof("name"), (void**)&tmp) == SUCCESS &&
    4123          13 :                                                     Z_TYPE_PP(tmp) == IS_STRING) {
    4124          13 :                                                         smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
    4125          13 :                                                         hdr_name = Z_STRVAL_PP(tmp);
    4126             :                                                 }
    4127          13 :                                                 smart_str_0(&key);
    4128          13 :                                                 if (function && function->binding && function->binding->bindingType == BINDING_SOAP) {
    4129           8 :                                                         sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    4130             : 
    4131          16 :                                                         if (fnb->output.headers &&
    4132           8 :                                                             zend_hash_find(fnb->output.headers, key.c, key.len+1, (void**)&hdr) == SUCCESS) {
    4133           8 :                                                                 hdr_enc = (*hdr)->encode;
    4134           8 :                                                                 hdr_use = (*hdr)->use;
    4135             :                                                         }
    4136             :                                                 }
    4137          13 :                                                 smart_str_free(&key);
    4138          13 :                                                 if (zend_hash_find(ht, "data", sizeof("data"), (void**)&tmp) == SUCCESS) {
    4139          13 :                                                         hdr_ret = *tmp;
    4140             :                                                 } else {
    4141           0 :                                                         hdr_ret = NULL;
    4142             :                                                 }
    4143             :                                         }
    4144             : 
    4145          27 :                                         if (h->function) {
    4146          14 :                                                 xmlNodePtr xmlHdr = NULL;
    4147             : 
    4148          14 :                                                 if (serialize_response_call2(head, h->function, Z_STRVAL(h->function_name), uri, hdr_ret, version, 0, &xmlHdr TSRMLS_CC) == SOAP_ENCODED) {
    4149           0 :                                                         use = SOAP_ENCODED;
    4150             :                                                 }
    4151          14 :                                                 if (ht) {
    4152           0 :                                                         set_soap_header_attributes(xmlHdr, ht, version);
    4153             :                                                 }
    4154             :                                         } else {
    4155          13 :                                                 xmlNodePtr xmlHdr = master_to_xml(hdr_enc, hdr_ret, hdr_use, head TSRMLS_CC);
    4156          13 :                                                 if (hdr_name) {
    4157          13 :                                                         xmlNodeSetName(xmlHdr, BAD_CAST(hdr_name));
    4158             :                                                 }
    4159          13 :                                                 if (hdr_ns) {
    4160          13 :                                                         xmlNsPtr nsptr = encode_add_ns(xmlHdr,hdr_ns);
    4161          13 :                                                         xmlSetNs(xmlHdr, nsptr);
    4162             :                                                 }
    4163          13 :                                                 if (ht) {
    4164          13 :                                                         set_soap_header_attributes(xmlHdr, ht, version);
    4165             :                                                 }
    4166             :                                         }
    4167             :                                 }
    4168          42 :                                 h = h->next;
    4169             :                         }
    4170             : 
    4171          35 :                         if (head->children == NULL) {
    4172          12 :                                 xmlUnlinkNode(head);
    4173          12 :                                 xmlFreeNode(head);
    4174             :                         }
    4175             :                 }
    4176             : 
    4177         376 :                 body = xmlNewChild(envelope, ns, BAD_CAST("Body"), NULL);
    4178             : 
    4179         376 :                 if (serialize_response_call2(body, function, function_name, uri, ret, version, 1, NULL TSRMLS_CC) == SOAP_ENCODED) {
    4180         205 :                         use = SOAP_ENCODED;
    4181             :                 }
    4182             : 
    4183             :         }
    4184             : 
    4185         471 :         if (use == SOAP_ENCODED) {
    4186         232 :                 xmlNewNs(envelope, BAD_CAST(XSD_NAMESPACE), BAD_CAST(XSD_NS_PREFIX));
    4187         232 :                 if (version == SOAP_1_1) {
    4188         206 :                         xmlNewNs(envelope, BAD_CAST(SOAP_1_1_ENC_NAMESPACE), BAD_CAST(SOAP_1_1_ENC_NS_PREFIX));
    4189         206 :                         xmlSetNsProp(envelope, envelope->ns, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_1_ENC_NAMESPACE));
    4190          26 :                 } else if (version == SOAP_1_2) {
    4191          26 :                         xmlNewNs(envelope, BAD_CAST(SOAP_1_2_ENC_NAMESPACE), BAD_CAST(SOAP_1_2_ENC_NS_PREFIX));
    4192             :                 }
    4193             :         }
    4194             : 
    4195         471 :         encode_finish();
    4196             : 
    4197         553 :         if (function && function->responseName == NULL && 
    4198          82 :             body->children == NULL && head == NULL) {
    4199          82 :                 xmlFreeDoc(doc);
    4200          82 :                 return NULL;
    4201             :         }
    4202         389 :         return doc;
    4203             : }
    4204             : 
    4205         398 : static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function, char *function_name, char *uri, zval **arguments, int arg_count, int version, HashTable *soap_headers TSRMLS_DC)
    4206             : {
    4207             :         xmlDoc *doc;
    4208         398 :         xmlNodePtr envelope = NULL, body, method = NULL, head = NULL;
    4209         398 :         xmlNsPtr ns = NULL;
    4210             :         zval **zstyle, **zuse;
    4211             :         int i, style, use;
    4212         398 :         HashTable *hdrs = NULL;
    4213             : 
    4214         398 :         encode_reset_ns();
    4215             : 
    4216         398 :         doc = xmlNewDoc(BAD_CAST("1.0"));
    4217         398 :         doc->encoding = xmlCharStrdup("UTF-8");
    4218         398 :         doc->charset = XML_CHAR_ENCODING_UTF8;
    4219         398 :         if (version == SOAP_1_1) {
    4220         396 :                 envelope = xmlNewDocNode(doc, NULL, BAD_CAST("Envelope"), NULL);
    4221         396 :                 ns = xmlNewNs(envelope, BAD_CAST(SOAP_1_1_ENV_NAMESPACE), BAD_CAST(SOAP_1_1_ENV_NS_PREFIX));
    4222         396 :                 xmlSetNs(envelope, ns);
    4223           2 :         } else if (version == SOAP_1_2) {
    4224           2 :                 envelope = xmlNewDocNode(doc, NULL, BAD_CAST("Envelope"), NULL);
    4225           2 :                 ns = xmlNewNs(envelope, BAD_CAST(SOAP_1_2_ENV_NAMESPACE), BAD_CAST(SOAP_1_2_ENV_NS_PREFIX));
    4226           2 :                 xmlSetNs(envelope, ns);
    4227             :         } else {
    4228           0 :                 soap_error0(E_ERROR, "Unknown SOAP version");
    4229             :         }
    4230         398 :         xmlDocSetRootElement(doc, envelope);
    4231             : 
    4232         398 :         if (soap_headers) {
    4233          16 :                 head = xmlNewChild(envelope, ns, BAD_CAST("Header"), NULL);
    4234             :         }
    4235             : 
    4236         398 :         body = xmlNewChild(envelope, ns, BAD_CAST("Body"), NULL);
    4237             : 
    4238         697 :         if (function && function->binding->bindingType == BINDING_SOAP) {
    4239         299 :                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    4240             : 
    4241         299 :                 hdrs = fnb->input.headers;
    4242         299 :                 style = fnb->style;
    4243             :                 /*FIXME: how to pass method name if style is SOAP_DOCUMENT */
    4244             :                 /*style = SOAP_RPC;*/
    4245         299 :                 use = fnb->input.use;
    4246         299 :                 if (style == SOAP_RPC) {
    4247         198 :                         ns = encode_add_ns(body, fnb->input.ns);
    4248         198 :                         if (function->requestName) {
    4249         198 :                                 method = xmlNewChild(body, ns, BAD_CAST(function->requestName), NULL);
    4250             :                         } else {
    4251           0 :                                 method = xmlNewChild(body, ns, BAD_CAST(function->functionName), NULL);
    4252             :                         }
    4253             :                 }
    4254             :         } else {
    4255         107 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "style", sizeof("style"), (void **)&zstyle) == SUCCESS &&
    4256           4 :                     Z_TYPE_PP(zstyle) == IS_LONG) {
    4257           4 :                         style = Z_LVAL_PP(zstyle);
    4258             :                 } else {
    4259          95 :                         style = SOAP_RPC;
    4260             :                 }
    4261             :                 /*FIXME: how to pass method name if style is SOAP_DOCUMENT */
    4262             :                 /*style = SOAP_RPC;*/
    4263          99 :                 if (style == SOAP_RPC) {
    4264          99 :                         ns = encode_add_ns(body, uri);
    4265          99 :                         if (function_name) {
    4266          98 :                                 method = xmlNewChild(body, ns, BAD_CAST(function_name), NULL);
    4267           2 :                         } else if (function && function->requestName) {
    4268           1 :                                 method = xmlNewChild(body, ns, BAD_CAST(function->requestName), NULL);
    4269           0 :                         } else if (function && function->functionName) {
    4270           0 :                                 method = xmlNewChild(body, ns, BAD_CAST(function->functionName), NULL);
    4271             :                         } else {
    4272           0 :                                 method = body;
    4273             :                         }
    4274             :                 } else {
    4275           0 :                         method = body;
    4276             :                 }
    4277             : 
    4278         107 :                 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use"), (void **)&zuse) == SUCCESS &&
    4279           8 :                     Z_TYPE_PP(zuse) == IS_LONG && Z_LVAL_PP(zuse) == SOAP_LITERAL) {
    4280           0 :                         use = SOAP_LITERAL;
    4281             :                 } else {
    4282          99 :                         use = SOAP_ENCODED;
    4283             :                 }
    4284             :         }
    4285             : 
    4286         842 :         for (i = 0;i < arg_count;i++) {
    4287             :                 xmlNodePtr param;
    4288         445 :                 sdlParamPtr parameter = get_param(function, NULL, i, FALSE);
    4289             : 
    4290         445 :                 if (style == SOAP_RPC) {
    4291         356 :                         param = serialize_parameter(parameter, arguments[i], i, NULL, use, method TSRMLS_CC);
    4292          89 :                 } else if (style == SOAP_DOCUMENT) {
    4293          89 :                         param = serialize_parameter(parameter, arguments[i], i, NULL, use, body TSRMLS_CC);
    4294          89 :                         if (function && function->binding->bindingType == BINDING_SOAP) {
    4295          89 :                                 if (parameter && parameter->element) {
    4296          83 :                                         ns = encode_add_ns(param, parameter->element->namens);
    4297          83 :                                         xmlNodeSetName(param, BAD_CAST(parameter->element->name));
    4298          83 :                                         xmlSetNs(param, ns);
    4299             :                                 }
    4300             :                         }
    4301             :                 }
    4302             :         }
    4303             : 
    4304         397 :         if (function && function->requestParameters) {
    4305         298 :                 int n = zend_hash_num_elements(function->requestParameters);
    4306             : 
    4307         298 :                 if (n > arg_count) {
    4308          20 :                         for (i = arg_count; i < n; i++) {
    4309             :                                 xmlNodePtr param;
    4310          10 :                                 sdlParamPtr parameter = get_param(function, NULL, i, FALSE);
    4311             : 
    4312          10 :                                 if (style == SOAP_RPC) {
    4313           1 :                                         param = serialize_parameter(parameter, NULL, i, NULL, use, method TSRMLS_CC);
    4314           9 :                                 } else if (style == SOAP_DOCUMENT) {
    4315           9 :                                         param = serialize_parameter(parameter, NULL, i, NULL, use, body TSRMLS_CC);
    4316           9 :                                         if (function && function->binding->bindingType == BINDING_SOAP) {
    4317           9 :                                                 if (parameter && parameter->element) {
    4318           9 :                                                         ns = encode_add_ns(param, parameter->element->namens);
    4319           9 :                                                         xmlNodeSetName(param, BAD_CAST(parameter->element->name));
    4320           9 :                                                         xmlSetNs(param, ns);
    4321             :                                                 }
    4322             :                                         }
    4323             :                                 }
    4324             :                         }
    4325             :                 }
    4326             :         }
    4327             : 
    4328         397 :         if (head) {
    4329             :                 zval** header;
    4330             : 
    4331          16 :                 zend_hash_internal_pointer_reset(soap_headers);
    4332          52 :                 while (zend_hash_get_current_data(soap_headers,(void**)&header) == SUCCESS) {
    4333          20 :                         HashTable *ht = Z_OBJPROP_PP(header);
    4334             :                         zval **name, **ns, **tmp;
    4335             : 
    4336          77 :                         if (zend_hash_find(ht, "name", sizeof("name"), (void**)&name) == SUCCESS &&
    4337          19 :                             Z_TYPE_PP(name) == IS_STRING &&
    4338          19 :                             zend_hash_find(ht, "namespace", sizeof("namespace"), (void**)&ns) == SUCCESS &&
    4339          19 :                             Z_TYPE_PP(ns) == IS_STRING) {
    4340             :                                 xmlNodePtr h;
    4341             :                                 xmlNsPtr nsptr;
    4342          19 :                                 int hdr_use = SOAP_LITERAL;
    4343          19 :                                 encodePtr enc = NULL;
    4344             : 
    4345          19 :                                 if (hdrs) {
    4346          11 :                                         smart_str key = {0};
    4347             :                                         sdlSoapBindingFunctionHeaderPtr *hdr;
    4348             : 
    4349          11 :                                         smart_str_appendl(&key, Z_STRVAL_PP(ns), Z_STRLEN_PP(ns));
    4350          11 :                                         smart_str_appendc(&key, ':');
    4351          11 :                                         smart_str_appendl(&key, Z_STRVAL_PP(name), Z_STRLEN_PP(name));
    4352          11 :                                         smart_str_0(&key);
    4353          11 :                                         if (zend_hash_find(hdrs, key.c, key.len+1,(void**)&hdr) == SUCCESS) {
    4354          10 :                                                 hdr_use = (*hdr)->use;
    4355          10 :                                                 enc = (*hdr)->encode;
    4356          10 :                                                 if (hdr_use == SOAP_ENCODED) {
    4357           0 :                                                         use = SOAP_ENCODED;
    4358             :                                                 }
    4359             :                                         }
    4360          11 :                                         smart_str_free(&key);
    4361             :                                 }
    4362             : 
    4363          19 :                                 if (zend_hash_find(ht, "data", sizeof("data"), (void**)&tmp) == SUCCESS) {
    4364          12 :                                         h = master_to_xml(enc, *tmp, hdr_use, head TSRMLS_CC);
    4365          12 :                                         xmlNodeSetName(h, BAD_CAST(Z_STRVAL_PP(name)));
    4366             :                                 } else {
    4367           7 :                                         h = xmlNewNode(NULL, BAD_CAST(Z_STRVAL_PP(name)));
    4368           7 :                                         xmlAddChild(head, h);
    4369             :                                 }
    4370          19 :                                 nsptr = encode_add_ns(h, Z_STRVAL_PP(ns));
    4371          19 :                                 xmlSetNs(h, nsptr);
    4372          19 :                                 set_soap_header_attributes(h, ht, version);
    4373             :                         }
    4374          20 :                         zend_hash_move_forward(soap_headers);
    4375             :                 }
    4376             :         }
    4377             : 
    4378         397 :         if (use == SOAP_ENCODED) {
    4379         287 :                 xmlNewNs(envelope, BAD_CAST(XSD_NAMESPACE), BAD_CAST(XSD_NS_PREFIX));
    4380         287 :                 if (version == SOAP_1_1) {
    4381         285 :                         xmlNewNs(envelope, BAD_CAST(SOAP_1_1_ENC_NAMESPACE), BAD_CAST(SOAP_1_1_ENC_NS_PREFIX));
    4382         285 :                         xmlSetNsProp(envelope, envelope->ns, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_1_ENC_NAMESPACE));
    4383           2 :                 } else if (version == SOAP_1_2) {
    4384           2 :                         xmlNewNs(envelope, BAD_CAST(SOAP_1_2_ENC_NAMESPACE), BAD_CAST(SOAP_1_2_ENC_NS_PREFIX));
    4385           2 :                         if (method) {
    4386           2 :                                 xmlSetNsProp(method, envelope->ns, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_2_ENC_NAMESPACE));
    4387             :                         }
    4388             :                 }
    4389             :         }
    4390             : 
    4391         397 :         encode_finish();
    4392             : 
    4393         397 :         return doc;
    4394             : }
    4395             : 
    4396         796 : static xmlNodePtr serialize_parameter(sdlParamPtr param, zval *param_val, int index, char *name, int style, xmlNodePtr parent TSRMLS_DC)
    4397             : {
    4398             :         char *paramName;
    4399             :         xmlNodePtr xmlParam;
    4400             :         char paramNameBuf[10];
    4401             : 
    4402        1798 :         if (param_val &&
    4403         780 :             Z_TYPE_P(param_val) == IS_OBJECT &&
    4404         222 :             Z_OBJCE_P(param_val) == soap_param_class_entry) {
    4405             :                 zval **param_name;
    4406             :                 zval **param_data;
    4407             : 
    4408          90 :                 if (zend_hash_find(Z_OBJPROP_P(param_val), "param_name", sizeof("param_name"), (void **)&param_name) == SUCCESS &&
    4409          30 :                     Z_TYPE_PP(param_name) == IS_STRING &&
    4410          30 :                     zend_hash_find(Z_OBJPROP_P(param_val), "param_data", sizeof("param_data"), (void **)&param_data) == SUCCESS) {
    4411          30 :                         param_val = *param_data;
    4412          30 :                         name = Z_STRVAL_PP(param_name);
    4413             :                 }
    4414             :         }
    4415             : 
    4416        1448 :         if (param != NULL && param->paramName != NULL) {
    4417         652 :                 paramName = param->paramName;
    4418             :         } else {
    4419         144 :                 if (name == NULL) {
    4420          65 :                         paramName = paramNameBuf;
    4421          65 :                         snprintf(paramName, sizeof(paramNameBuf), "param%d",index);
    4422             :                 } else {
    4423          79 :                         paramName = name;
    4424             :                 }
    4425             :         }
    4426             : 
    4427         796 :         xmlParam = serialize_zval(param_val, param, paramName, style, parent TSRMLS_CC);
    4428             : 
    4429         794 :         return xmlParam;
    4430             : }
    4431             : 
    4432         796 : static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName, int style, xmlNodePtr parent TSRMLS_DC)
    4433             : {
    4434             :         xmlNodePtr xmlParam;
    4435             :         encodePtr enc;
    4436             :         zval defval;
    4437             : 
    4438         796 :         if (param != NULL) {
    4439         652 :                 enc = param->encode;
    4440         652 :                 if (val == NULL) {
    4441          16 :                         if (param->element) {
    4442          13 :                                 if (param->element->fixed) {
    4443           0 :                                         ZVAL_STRING(&defval, param->element->fixed, 0);
    4444           0 :                                         val = &defval;
    4445          13 :                                 } else if (param->element->def && !param->element->nillable) {
    4446           1 :                                         ZVAL_STRING(&defval, param->element->def, 0);
    4447           1 :                                         val = &defval;
    4448             :                                 }
    4449             :                         }
    4450             :                 }
    4451             :         } else {
    4452         144 :                 enc = NULL;
    4453             :         }
    4454         796 :         xmlParam = master_to_xml(enc, val, style, parent TSRMLS_CC);
    4455         794 :         if (!strcmp((char*)xmlParam->name, "BOGUS")) {
    4456         788 :                 xmlNodeSetName(xmlParam, BAD_CAST(paramName));
    4457             :         }
    4458         794 :         return xmlParam;
    4459             : }
    4460             : 
    4461         742 : static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, int response)
    4462             : {
    4463             :         sdlParamPtr *tmp;
    4464             :         HashTable   *ht;
    4465             : 
    4466         742 :         if (function == NULL) {
    4467         144 :                 return NULL;
    4468             :         }
    4469             : 
    4470         598 :         if (response == FALSE) {
    4471         360 :                 ht = function->requestParameters;
    4472             :         } else {
    4473         238 :                 ht = function->responseParameters;
    4474             :         }
    4475             : 
    4476         598 :         if (ht == NULL) {
    4477           0 :           return NULL;
    4478             :         }
    4479             : 
    4480         598 :         if (param_name != NULL) {
    4481          12 :                 if (zend_hash_find(ht, param_name, strlen(param_name), (void **)&tmp) != FAILURE) {
    4482           0 :                         return *tmp;
    4483             :                 } else {
    4484             :                         HashPosition pos;
    4485             :                 
    4486          12 :                         zend_hash_internal_pointer_reset_ex(ht, &pos);
    4487          36 :                         while (zend_hash_get_current_data_ex(ht, (void **)&tmp, &pos) != FAILURE) {
    4488          24 :                                 if ((*tmp)->paramName && strcmp(param_name, (*tmp)->paramName) == 0) {
    4489          12 :                                         return *tmp;
    4490             :                                 }
    4491          12 :                                 zend_hash_move_forward_ex(ht, &pos);
    4492             :                         }
    4493             :                 }
    4494             :         } else {
    4495         586 :                 if (zend_hash_index_find(ht, index, (void **)&tmp) != FAILURE) {
    4496         586 :                         return (*tmp);
    4497             :                 }
    4498             :         }
    4499           0 :         return NULL;
    4500             : }
    4501             : 
    4502         776 : static sdlFunctionPtr get_function(sdlPtr sdl, const char *function_name)
    4503             : {
    4504             :         sdlFunctionPtr *tmp;
    4505             : 
    4506         776 :         int len = strlen(function_name);
    4507         776 :         char *str = estrndup(function_name,len);
    4508         776 :         php_strtolower(str,len);
    4509         776 :         if (sdl != NULL) {
    4510         715 :                 if (zend_hash_find(&sdl->functions, str, len+1, (void **)&tmp) != FAILURE) {
    4511         639 :                         efree(str);
    4512         639 :                         return (*tmp);
    4513          76 :                 } else if (sdl->requests != NULL && zend_hash_find(sdl->requests, str, len+1, (void **)&tmp) != FAILURE) {
    4514           0 :                         efree(str);
    4515           0 :                         return (*tmp);
    4516             :                 }
    4517             :         }
    4518         137 :         efree(str);
    4519         137 :         return NULL;
    4520             : }
    4521             : 
    4522         169 : static sdlFunctionPtr get_doc_function(sdlPtr sdl, xmlNodePtr params)
    4523             : {
    4524         169 :         if (sdl) {
    4525             :                 sdlFunctionPtr *tmp;
    4526             :                 sdlParamPtr    *param;
    4527             : 
    4528         169 :                 zend_hash_internal_pointer_reset(&sdl->functions);
    4529        1603 :                 while (zend_hash_get_current_data(&sdl->functions, (void**)&tmp) == SUCCESS) {
    4530        1405 :                         if ((*tmp)->binding && (*tmp)->binding->bindingType == BINDING_SOAP) {
    4531        1405 :                                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)(*tmp)->bindingAttributes;
    4532        1405 :                                 if (fnb->style == SOAP_DOCUMENT) {
    4533        1096 :                                         if (params == NULL) {
    4534          66 :                                                 if ((*tmp)->requestParameters == NULL ||
    4535          33 :                                                     zend_hash_num_elements((*tmp)->requestParameters) == 0) {
    4536          30 :                                                   return *tmp;
    4537             :                                                 }
    4538        2126 :                                         } else if ((*tmp)->requestParameters != NULL &&
    4539        1063 :                                                    zend_hash_num_elements((*tmp)->requestParameters) > 0) {
    4540        1027 :                                                 int ok = 1;
    4541        1027 :                                                 xmlNodePtr node = params;
    4542             : 
    4543        1027 :                                                 zend_hash_internal_pointer_reset((*tmp)->requestParameters);
    4544        2165 :                                                 while (zend_hash_get_current_data((*tmp)->requestParameters, (void**)&param) == SUCCESS) {
    4545        1028 :                                                         if ((*param)->element) {
    4546        1023 :                                                                 if (strcmp((*param)->element->name, (char*)node->name) != 0) {
    4547         917 :                                                                         ok = 0;
    4548         917 :                                                                         break;
    4549             :                                                                 }
    4550         212 :                                                                 if ((*param)->element->namens != NULL && node->ns != NULL) {
    4551         106 :                                                                         if (strcmp((*param)->element->namens, (char*)node->ns->href) != 0) {
    4552           0 :                                                                                 ok = 0;
    4553           0 :                                                                                 break;
    4554             :                                                                         }
    4555           0 :                                                                 } else if ((void*)(*param)->element->namens != (void*)node->ns) {
    4556           0 :                                                                         ok = 0;
    4557           0 :                                                                         break;
    4558             :                                                                 }
    4559           5 :                                                         } else if (strcmp((*param)->paramName, (char*)node->name) != 0) {
    4560           0 :                                                                 ok = 0;
    4561           0 :                                                                 break;
    4562             :                                                         }
    4563         111 :                                                         zend_hash_move_forward((*tmp)->requestParameters);
    4564         111 :                                                         node = node->next;
    4565             :                                                 }
    4566        1027 :                                                 if (ok /*&& node == NULL*/) {
    4567         110 :                                                         return (*tmp);
    4568             :                                                 }
    4569             :                                         }
    4570             :                                 }
    4571             :                         }
    4572        1265 :                         zend_hash_move_forward(&sdl->functions);
    4573             :                 }
    4574             :         }
    4575          29 :         return NULL;
    4576             : }
    4577             : 
    4578           7 : static void function_to_string(sdlFunctionPtr function, smart_str *buf)
    4579             : {
    4580           7 :         int i = 0;
    4581             :         HashPosition pos;
    4582             :         sdlParamPtr *param;
    4583             : 
    4584          21 :         if (function->responseParameters &&
    4585           7 :             zend_hash_num_elements(function->responseParameters) > 0) {
    4586           7 :                 if (zend_hash_num_elements(function->responseParameters) == 1) {
    4587           7 :                         zend_hash_internal_pointer_reset(function->responseParameters);
    4588           7 :                         zend_hash_get_current_data(function->responseParameters, (void**)&param);
    4589          14 :                         if ((*param)->encode && (*param)->encode->details.type_str) {
    4590           7 :                                 smart_str_appendl(buf, (*param)->encode->details.type_str, strlen((*param)->encode->details.type_str));
    4591           7 :                                 smart_str_appendc(buf, ' ');
    4592             :                         } else {
    4593           0 :                                 smart_str_appendl(buf, "UNKNOWN ", 8);
    4594             :                         }
    4595             :                 } else {
    4596           0 :                         i = 0;
    4597           0 :                         smart_str_appendl(buf, "list(", 5);
    4598           0 :                         zend_hash_internal_pointer_reset_ex(function->responseParameters, &pos);
    4599           0 :                         while (zend_hash_get_current_data_ex(function->responseParameters, (void **)&param, &pos) != FAILURE) {
    4600           0 :                                 if (i > 0) {
    4601           0 :                                         smart_str_appendl(buf, ", ", 2);
    4602             :                                 }
    4603           0 :                                 if ((*param)->encode && (*param)->encode->details.type_str) {
    4604           0 :                                         smart_str_appendl(buf, (*param)->encode->details.type_str, strlen((*param)->encode->details.type_str));
    4605             :                                 } else {
    4606           0 :                                         smart_str_appendl(buf, "UNKNOWN", 7);
    4607             :                                 }
    4608           0 :                                 smart_str_appendl(buf, " $", 2);
    4609           0 :                                 smart_str_appendl(buf, (*param)->paramName, strlen((*param)->paramName));
    4610           0 :                                 zend_hash_move_forward_ex(function->responseParameters, &pos);
    4611           0 :                                 i++;
    4612             :                         }
    4613           0 :                         smart_str_appendl(buf, ") ", 2);
    4614             :                 }
    4615             :         } else {
    4616           0 :                 smart_str_appendl(buf, "void ", 5);
    4617             :         }
    4618             : 
    4619           7 :         smart_str_appendl(buf, function->functionName, strlen(function->functionName));
    4620             : 
    4621           7 :         smart_str_appendc(buf, '(');
    4622           7 :         if (function->requestParameters) {
    4623           7 :                 i = 0;
    4624           7 :                 zend_hash_internal_pointer_reset_ex(function->requestParameters, &pos);
    4625          21 :                 while (zend_hash_get_current_data_ex(function->requestParameters, (void **)&param, &pos) != FAILURE) {
    4626           7 :                         if (i > 0) {
    4627           0 :                                 smart_str_appendl(buf, ", ", 2);
    4628             :                         }
    4629          14 :                         if ((*param)->encode && (*param)->encode->details.type_str) {
    4630           7 :                                 smart_str_appendl(buf, (*param)->encode->details.type_str, strlen((*param)->encode->details.type_str));
    4631             :                         } else {
    4632           0 :                                 smart_str_appendl(buf, "UNKNOWN", 7);
    4633             :                         }
    4634           7 :                         smart_str_appendl(buf, " $", 2);
    4635           7 :                         smart_str_appendl(buf, (*param)->paramName, strlen((*param)->paramName));
    4636           7 :                         zend_hash_move_forward_ex(function->requestParameters, &pos);
    4637           7 :                         i++;
    4638             :                 }
    4639             :         }
    4640           7 :         smart_str_appendc(buf, ')');
    4641           7 :         smart_str_0(buf);
    4642           7 : }
    4643             : 
    4644         110 : static void model_to_string(sdlContentModelPtr model, smart_str *buf, int level)
    4645             : {
    4646             :         int i;
    4647             : 
    4648         110 :         switch (model->kind) {
    4649             :                 case XSD_CONTENT_ELEMENT:
    4650          70 :                         type_to_string(model->u.element, buf, level);
    4651          70 :                         smart_str_appendl(buf, ";\n", 2);
    4652          70 :                         break;
    4653             :                 case XSD_CONTENT_ANY:
    4654           2 :                         for (i = 0;i < level;i++) {
    4655           1 :                                 smart_str_appendc(buf, ' ');
    4656             :                         }
    4657           1 :                         smart_str_appendl(buf, "<anyXML> any;\n", sizeof("<anyXML> any;\n")-1);
    4658           1 :                         break;
    4659             :                 case XSD_CONTENT_SEQUENCE:
    4660             :                 case XSD_CONTENT_ALL:
    4661             :                 case XSD_CONTENT_CHOICE: {
    4662             :                         sdlContentModelPtr *tmp;
    4663             : 
    4664          39 :                         zend_hash_internal_pointer_reset(model->u.content);
    4665         149 :                         while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
    4666          71 :                                 model_to_string(*tmp, buf, level);
    4667          71 :                                 zend_hash_move_forward(model->u.content);
    4668             :                         }
    4669          39 :                         break;
    4670             :                 }
    4671             :                 case XSD_CONTENT_GROUP:
    4672           0 :                         model_to_string(model->u.group->model, buf, level);
    4673             :                 default:
    4674             :                   break;
    4675             :         }
    4676         110 : }
    4677             : 
    4678         119 : static void type_to_string(sdlTypePtr type, smart_str *buf, int level)
    4679             : {
    4680             :         int i;
    4681         119 :         smart_str spaces = {0};
    4682             :         HashPosition pos;
    4683             : 
    4684         189 :         for (i = 0;i < level;i++) {
    4685          70 :                 smart_str_appendc(&spaces, ' ');
    4686             :         }
    4687         119 :         smart_str_appendl(buf, spaces.c, spaces.len);
    4688             : 
    4689         119 :         switch (type->kind) {
    4690             :                 case XSD_TYPEKIND_SIMPLE:
    4691          72 :                         if (type->encode) {
    4692          70 :                                 smart_str_appendl(buf, type->encode->details.type_str, strlen(type->encode->details.type_str));
    4693          70 :                                 smart_str_appendc(buf, ' ');
    4694             :                         } else {
    4695           2 :                                 smart_str_appendl(buf, "anyType ", sizeof("anyType ")-1);
    4696             :                         }
    4697          72 :                         smart_str_appendl(buf, type->name, strlen(type->name));
    4698          72 :                         break;
    4699             :                 case XSD_TYPEKIND_LIST:
    4700           2 :                         smart_str_appendl(buf, "list ", 5);
    4701           2 :                         smart_str_appendl(buf, type->name, strlen(type->name));
    4702           2 :                         if (type->elements) {
    4703             :                                 sdlTypePtr *item_type;
    4704             : 
    4705           2 :                                 smart_str_appendl(buf, " {", 2);
    4706           2 :                                 zend_hash_internal_pointer_reset_ex(type->elements, &pos);
    4707           2 :                                 if (zend_hash_get_current_data_ex(type->elements, (void **)&item_type, &pos) != FAILURE) {
    4708           2 :                                         smart_str_appendl(buf, (*item_type)->name, strlen((*item_type)->name));
    4709             :                                 }
    4710           2 :                                 smart_str_appendc(buf, '}');
    4711             :                         }
    4712           2 :                         break;
    4713             :                 case XSD_TYPEKIND_UNION:
    4714           0 :                         smart_str_appendl(buf, "union ", 6);
    4715           0 :                         smart_str_appendl(buf, type->name, strlen(type->name));
    4716           0 :                         if (type->elements) {
    4717             :                                 sdlTypePtr *item_type;
    4718           0 :                                 int first = 0;
    4719             : 
    4720           0 :                                 smart_str_appendl(buf, " {", 2);
    4721           0 :                                 zend_hash_internal_pointer_reset_ex(type->elements, &pos);
    4722           0 :                                 while (zend_hash_get_current_data_ex(type->elements, (void **)&item_type, &pos) != FAILURE) {
    4723           0 :                                         if (!first) {
    4724           0 :                                                 smart_str_appendc(buf, ',');
    4725           0 :                                                 first = 0;
    4726             :                                         }
    4727           0 :                                         smart_str_appendl(buf, (*item_type)->name, strlen((*item_type)->name));
    4728           0 :                                         zend_hash_move_forward_ex(type->elements, &pos);
    4729             :                                 }
    4730           0 :                                 smart_str_appendc(buf, '}');
    4731             :                         }
    4732           0 :                         break;
    4733             :                 case XSD_TYPEKIND_COMPLEX:
    4734             :                 case XSD_TYPEKIND_RESTRICTION:
    4735             :                 case XSD_TYPEKIND_EXTENSION:
    4736          47 :                         if (type->encode &&
    4737           1 :                             (type->encode->details.type == IS_ARRAY ||
    4738           1 :                              type->encode->details.type == SOAP_ENC_ARRAY)) {
    4739             :                           sdlAttributePtr *attr;
    4740             :                           sdlExtraAttributePtr *ext;
    4741             : 
    4742           0 :                                 if (type->attributes &&
    4743           0 :                                     zend_hash_find(type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType",
    4744             :                                       sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType"),
    4745           0 :                                       (void **)&attr) == SUCCESS &&
    4746           0 :                                       zend_hash_find((*attr)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&ext) == SUCCESS) {
    4747           0 :                                         char *end = strchr((*ext)->val, '[');
    4748             :                                         int len;
    4749           0 :                                         if (end == NULL) {
    4750           0 :                                                 len = strlen((*ext)->val);
    4751             :                                         } else {
    4752           0 :                                                 len = end-(*ext)->val;
    4753             :                                         }
    4754           0 :                                         if (len == 0) {
    4755           0 :                                                 smart_str_appendl(buf, "anyType", sizeof("anyType")-1);
    4756             :                                         } else {
    4757           0 :                                                 smart_str_appendl(buf, (*ext)->val, len);
    4758             :                                         }
    4759           0 :                                         smart_str_appendc(buf, ' ');
    4760           0 :                                         smart_str_appendl(buf, type->name, strlen(type->name));
    4761           0 :                                         if (end != NULL) {
    4762           0 :                                                 smart_str_appends(buf, end);
    4763             :                                         }
    4764             :                                 } else {
    4765             :                                         sdlTypePtr elementType;
    4766           0 :                                         if (type->attributes &&
    4767           0 :                                             zend_hash_find(type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType",
    4768             :                                               sizeof(SOAP_1_2_ENC_NAMESPACE":itemType"),
    4769           0 :                                               (void **)&attr) == SUCCESS &&
    4770           0 :                                               zend_hash_find((*attr)->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&ext) == SUCCESS) {
    4771           0 :                                                 smart_str_appends(buf, (*ext)->val);
    4772           0 :                                                 smart_str_appendc(buf, ' ');
    4773           0 :                                         } else if (type->elements &&
    4774           0 :                                                    zend_hash_num_elements(type->elements) == 1 &&
    4775           0 :                                                    (zend_hash_internal_pointer_reset(type->elements),
    4776             :                                                     zend_hash_get_current_data(type->elements, (void**)&elementType) == SUCCESS) &&
    4777           0 :                                                    (elementType = *(sdlTypePtr*)elementType) != NULL &&
    4778           0 :                                                    elementType->encode && elementType->encode->details.type_str) {
    4779           0 :                                                 smart_str_appends(buf, elementType->encode->details.type_str);
    4780           0 :                                                 smart_str_appendc(buf, ' ');
    4781             :                                         } else {
    4782           0 :                                                 smart_str_appendl(buf, "anyType ", 8);
    4783             :                                         }
    4784           0 :                                         smart_str_appendl(buf, type->name, strlen(type->name));
    4785           0 :                                         if (type->attributes &&
    4786           0 :                                             zend_hash_find(type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
    4787             :                                               sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"),
    4788           0 :                                               (void **)&attr) == SUCCESS &&
    4789           0 :                                               zend_hash_find((*attr)->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":arraySize"), (void **)&ext) == SUCCESS) {
    4790           0 :                                                 smart_str_appendc(buf, '[');
    4791           0 :                                                 smart_str_appends(buf, (*ext)->val);
    4792           0 :                                                 smart_str_appendc(buf, ']');
    4793             :                                         } else {
    4794           0 :                                                 smart_str_appendl(buf, "[]", 2);
    4795             :                                         }
    4796             :                                 }
    4797             :                         } else {
    4798          45 :                                 smart_str_appendl(buf, "struct ", 7);
    4799          45 :                                 smart_str_appendl(buf, type->name, strlen(type->name));
    4800          45 :                                 smart_str_appendc(buf, ' ');
    4801          45 :                                 smart_str_appendl(buf, "{\n", 2);
    4802          91 :                                 if ((type->kind == XSD_TYPEKIND_RESTRICTION ||
    4803          46 :                                      type->kind == XSD_TYPEKIND_EXTENSION) && type->encode) {
    4804           1 :                                         encodePtr enc = type->encode;
    4805           7 :                                         while (enc && enc->details.sdl_type &&
    4806           1 :                                                enc != enc->details.sdl_type->encode &&
    4807           1 :                                                enc->details.sdl_type->kind != XSD_TYPEKIND_SIMPLE &&
    4808           1 :                                                enc->details.sdl_type->kind != XSD_TYPEKIND_LIST &&
    4809           1 :                                                enc->details.sdl_type->kind != XSD_TYPEKIND_UNION) {
    4810           1 :                                                 enc = enc->details.sdl_type->encode;
    4811             :                                         }
    4812           1 :                                         if (enc) {
    4813           0 :                                                 smart_str_appendl(buf, spaces.c, spaces.len);
    4814           0 :                                                 smart_str_appendc(buf, ' ');
    4815           0 :                                                 smart_str_appendl(buf, type->encode->details.type_str, strlen(type->encode->details.type_str));
    4816           0 :                                                 smart_str_appendl(buf, " _;\n", 4);
    4817             :                                         }
    4818             :                                 }
    4819          45 :                                 if (type->model) {
    4820          39 :                                         model_to_string(type->model, buf, level+1);
    4821             :                                 }
    4822          45 :                                 if (type->attributes) {
    4823             :                                         sdlAttributePtr *attr;
    4824             : 
    4825           0 :                                         zend_hash_internal_pointer_reset_ex(type->attributes, &pos);
    4826           0 :                                         while (zend_hash_get_current_data_ex(type->attributes, (void **)&attr, &pos) != FAILURE) {
    4827           0 :                                                 smart_str_appendl(buf, spaces.c, spaces.len);
    4828           0 :                                                 smart_str_appendc(buf, ' ');
    4829           0 :                                                 if ((*attr)->encode && (*attr)->encode->details.type_str) {
    4830           0 :                                                         smart_str_appends(buf, (*attr)->encode->details.type_str);
    4831           0 :                                                         smart_str_appendc(buf, ' ');
    4832             :                                                 } else {
    4833           0 :                                                         smart_str_appendl(buf, "UNKNOWN ", 8);
    4834             :                                                 }
    4835           0 :                                                 smart_str_appends(buf, (*attr)->name);
    4836           0 :                                                 smart_str_appendl(buf, ";\n", 2);
    4837           0 :                                                 zend_hash_move_forward_ex(type->attributes, &pos);
    4838             :                                         }
    4839             :                                 }
    4840          45 :                                 smart_str_appendl(buf, spaces.c, spaces.len);
    4841          45 :                                 smart_str_appendc(buf, '}');
    4842             :                         }
    4843             :                         break;
    4844             :                 default:
    4845             :                         break;
    4846             :         }
    4847         119 :         smart_str_free(&spaces);
    4848         119 :         smart_str_0(buf);
    4849         119 : }
    4850             : 
    4851           1 : static void delete_url(void *handle)
    4852             : {
    4853           1 :         php_url_free((php_url*)handle);
    4854           1 : }
    4855             : 
    4856         456 : static void delete_service(void *data)
    4857             : {
    4858         456 :         soapServicePtr service = (soapServicePtr)data;
    4859             : 
    4860         456 :         if (service->soap_functions.ft) {
    4861         455 :                 zend_hash_destroy(service->soap_functions.ft);
    4862         455 :                 efree(service->soap_functions.ft);
    4863             :         }
    4864             : 
    4865         456 :         if (service->typemap) {
    4866           7 :                 zend_hash_destroy(service->typemap);
    4867           7 :                 efree(service->typemap);
    4868             :         }
    4869             : 
    4870         456 :         if (service->soap_class.argc) {
    4871             :                 int i;
    4872           2 :                 for (i = 0; i < service->soap_class.argc;i++) {
    4873           1 :                         zval_ptr_dtor(&service->soap_class.argv[i]);
    4874             :                 }
    4875           1 :                 efree(service->soap_class.argv);
    4876             :         }
    4877             : 
    4878         456 :         if (service->actor) {
    4879          81 :                 efree(service->actor);
    4880             :         }
    4881         456 :         if (service->uri) {
    4882         456 :                 efree(service->uri);
    4883             :         }
    4884         456 :         if (service->sdl) {
    4885         409 :                 delete_sdl(service->sdl);
    4886             :         }
    4887         456 :         if (service->encoding) {
    4888           4 :                 xmlCharEncCloseFunc(service->encoding);
    4889             :         }
    4890         456 :         if (service->class_map) {
    4891          11 :                 zend_hash_destroy(service->class_map);
    4892          11 :                 FREE_HASHTABLE(service->class_map);
    4893             :         }
    4894         456 :         if (service->soap_object) {
    4895           4 :                 zval_ptr_dtor(&service->soap_object);
    4896             :         }
    4897         456 :         efree(service);
    4898         456 : }
    4899             : 
    4900           6 : static void delete_hashtable(void *data)
    4901             : {
    4902           6 :         HashTable *ht = (HashTable*)data;
    4903           6 :         zend_hash_destroy(ht);
    4904           6 :         efree(ht);
    4905           6 : }

Generated by: LCOV version 1.10

Generated at Sun, 17 May 2015 16:25:16 +0000 (4 days ago)

Copyright © 2005-2015 The PHP Group
All rights reserved.