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