File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / soap / soap.c
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:03:55 2014 UTC (10 years, 6 months ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>