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: 2104 2598 81.0 %
Date: 2014-07-27 Functions: 59 63 93.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sun, 27 Jul 2014 12:58:35 +0000 (2 days ago)

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