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-23 Instrumented lines: 2791
Code covered: 79.8 % Executed lines: 2228
Legend: not executed executed

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