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: 1976 2370 83.4 %
Date: 2014-09-27 Functions: 66 70 94.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 27 Sep 2014 16:43:17 +0000 (2 days ago)

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