Annotation of embedaddon/php/ext/soap/soap.c, revision 1.1
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>