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