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: 2121 2573 82.4 %
Date: 2014-08-04 Functions: 61 65 93.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Mon, 04 Aug 2014 15:49:12 +0000 (44 days ago)

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