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

Generated by: LCOV version 1.10

Generated at Wed, 16 Apr 2014 12:47:56 +0000 (8 days ago)

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