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