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