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

LTP GCOV extension - code coverage report
Current view: directory - soap - soap.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 2411
Code covered: 81.0 % Executed lines: 1952
Legend: not executed executed

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