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