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: php_sdl.c 287425 2009-08-17 18:23:48Z dmitry $ */
21 :
22 : #include "php_soap.h"
23 : #include "ext/libxml/php_libxml.h"
24 : #include "libxml/uri.h"
25 :
26 : #include "ext/standard/md5.h"
27 : #include "tsrm_virtual_cwd.h"
28 :
29 : #include <sys/types.h>
30 : #include <sys/stat.h>
31 : #include <fcntl.h>
32 :
33 : #ifndef O_BINARY
34 : # define O_BINARY 0
35 : #endif
36 :
37 : static void delete_fault(void *fault);
38 : static void delete_fault_persistent(void *fault);
39 : static void delete_binding(void *binding);
40 : static void delete_binding_persistent(void *binding);
41 : static void delete_function(void *function);
42 : static void delete_function_persistent(void *function);
43 : static void delete_parameter(void *paramater);
44 : static void delete_parameter_persistent(void *paramater);
45 : static void delete_header(void *header);
46 : static void delete_header_persistent(void *header);
47 : static void delete_document(void *doc_ptr);
48 :
49 : encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr node, const xmlChar *type)
50 10674 : {
51 10674 : encodePtr enc = NULL;
52 : xmlNsPtr nsptr;
53 : char *ns, *cptype;
54 :
55 10674 : parse_namespace(type, &cptype, &ns);
56 10674 : nsptr = xmlSearchNs(node->doc, node, BAD_CAST(ns));
57 10674 : if (nsptr != NULL) {
58 10651 : enc = get_encoder(sdl, (char*)nsptr->href, cptype);
59 10651 : if (enc == NULL) {
60 7 : enc = get_encoder_ex(sdl, cptype, strlen(cptype));
61 : }
62 : } else {
63 23 : enc = get_encoder_ex(sdl, (char*)type, xmlStrlen(type));
64 : }
65 10674 : efree(cptype);
66 10674 : if (ns) {efree(ns);}
67 10674 : return enc;
68 : }
69 :
70 : static sdlTypePtr get_element(sdlPtr sdl, xmlNodePtr node, const xmlChar *type)
71 9963 : {
72 9963 : sdlTypePtr ret = NULL;
73 :
74 9963 : if (sdl->elements) {
75 : xmlNsPtr nsptr;
76 : char *ns, *cptype;
77 : sdlTypePtr *sdl_type;
78 :
79 9962 : parse_namespace(type, &cptype, &ns);
80 9962 : nsptr = xmlSearchNs(node->doc, node, BAD_CAST(ns));
81 9962 : if (nsptr != NULL) {
82 9962 : int ns_len = xmlStrlen(nsptr->href);
83 9962 : int type_len = strlen(cptype);
84 9962 : int len = ns_len + type_len + 1;
85 9962 : char *nscat = emalloc(len + 1);
86 :
87 9962 : memcpy(nscat, nsptr->href, ns_len);
88 9962 : nscat[ns_len] = ':';
89 9962 : memcpy(nscat+ns_len+1, cptype, type_len);
90 9962 : nscat[len] = '\0';
91 :
92 9962 : if (zend_hash_find(sdl->elements, nscat, len + 1, (void **)&sdl_type) == SUCCESS) {
93 9962 : ret = *sdl_type;
94 0 : } else if (zend_hash_find(sdl->elements, (char*)type, type_len + 1, (void **)&sdl_type) == SUCCESS) {
95 0 : ret = *sdl_type;
96 : }
97 9962 : efree(nscat);
98 : } else {
99 0 : if (zend_hash_find(sdl->elements, (char*)type, xmlStrlen(type) + 1, (void **)&sdl_type) == SUCCESS) {
100 0 : ret = *sdl_type;
101 : }
102 : }
103 :
104 9962 : efree(cptype);
105 9962 : if (ns) {efree(ns);}
106 : }
107 9963 : return ret;
108 : }
109 :
110 : encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type)
111 23994 : {
112 23994 : encodePtr enc = NULL;
113 : char *nscat;
114 23994 : int ns_len = strlen(ns);
115 23994 : int type_len = strlen(type);
116 23994 : int len = ns_len + type_len + 1;
117 :
118 23994 : nscat = emalloc(len + 1);
119 23994 : memcpy(nscat, ns, ns_len);
120 23994 : nscat[ns_len] = ':';
121 23994 : memcpy(nscat+ns_len+1, type, type_len);
122 23994 : nscat[len] = '\0';
123 :
124 23994 : enc = get_encoder_ex(sdl, nscat, len);
125 :
126 23994 : if (enc == NULL &&
127 : ((ns_len == sizeof(SOAP_1_1_ENC_NAMESPACE)-1 &&
128 : memcmp(ns, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)-1) == 0) ||
129 : (ns_len == sizeof(SOAP_1_2_ENC_NAMESPACE)-1 &&
130 : memcmp(ns, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)-1) == 0))) {
131 : char *enc_nscat;
132 : int enc_ns_len;
133 : int enc_len;
134 :
135 4 : enc_ns_len = sizeof(XSD_NAMESPACE)-1;
136 4 : enc_len = enc_ns_len + type_len + 1;
137 4 : enc_nscat = emalloc(enc_len + 1);
138 4 : memcpy(enc_nscat, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)-1);
139 4 : enc_nscat[enc_ns_len] = ':';
140 4 : memcpy(enc_nscat+enc_ns_len+1, type, type_len);
141 4 : enc_nscat[enc_len] = '\0';
142 :
143 4 : enc = get_encoder_ex(NULL, enc_nscat, enc_len);
144 4 : efree(enc_nscat);
145 4 : if (enc && sdl) {
146 4 : encodePtr new_enc = pemalloc(sizeof(encode), sdl->is_persistent);
147 4 : memcpy(new_enc, enc, sizeof(encode));
148 4 : if (sdl->is_persistent) {
149 2 : new_enc->details.ns = zend_strndup(ns, ns_len);
150 2 : new_enc->details.type_str = strdup(new_enc->details.type_str);
151 : } else {
152 2 : new_enc->details.ns = estrndup(ns, ns_len);
153 2 : new_enc->details.type_str = estrdup(new_enc->details.type_str);
154 : }
155 4 : if (sdl->encoders == NULL) {
156 0 : sdl->encoders = pemalloc(sizeof(HashTable), sdl->is_persistent);
157 0 : zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, sdl->is_persistent);
158 : }
159 4 : zend_hash_update(sdl->encoders, nscat, len + 1, &new_enc, sizeof(encodePtr), NULL);
160 4 : enc = new_enc;
161 : }
162 : }
163 23994 : efree(nscat);
164 23994 : return enc;
165 : }
166 :
167 : encodePtr get_encoder_ex(sdlPtr sdl, const char *nscat, int len)
168 24030 : {
169 : encodePtr *enc;
170 : TSRMLS_FETCH();
171 :
172 24030 : if (zend_hash_find(&SOAP_GLOBAL(defEnc), (char*)nscat, len + 1, (void **)&enc) == SUCCESS) {
173 15588 : return (*enc);
174 8442 : } else if (sdl && sdl->encoders && zend_hash_find(sdl->encoders, (char*)nscat, len + 1, (void **)&enc) == SUCCESS) {
175 6788 : return (*enc);
176 : }
177 1654 : return NULL;
178 : }
179 :
180 : sdlBindingPtr get_binding_from_type(sdlPtr sdl, int type)
181 0 : {
182 : sdlBindingPtr *binding;
183 :
184 0 : if (sdl == NULL) {
185 0 : return NULL;
186 : }
187 :
188 0 : for (zend_hash_internal_pointer_reset(sdl->bindings);
189 0 : zend_hash_get_current_data(sdl->bindings, (void **) &binding) == SUCCESS;
190 0 : zend_hash_move_forward(sdl->bindings)) {
191 0 : if ((*binding)->bindingType == type) {
192 0 : return *binding;
193 : }
194 : }
195 0 : return NULL;
196 : }
197 :
198 : sdlBindingPtr get_binding_from_name(sdlPtr sdl, char *name, char *ns)
199 0 : {
200 0 : sdlBindingPtr binding = NULL;
201 0 : smart_str key = {0};
202 :
203 0 : smart_str_appends(&key, ns);
204 0 : smart_str_appendc(&key, ':');
205 0 : smart_str_appends(&key, name);
206 0 : smart_str_0(&key);
207 :
208 0 : zend_hash_find(sdl->bindings, key.c, key.len, (void **)&binding);
209 :
210 0 : smart_str_free(&key);
211 0 : return binding;
212 : }
213 :
214 : static int is_wsdl_element(xmlNodePtr node)
215 40260 : {
216 40260 : if (node->ns && strcmp((char*)node->ns->href, WSDL_NAMESPACE) != 0) {
217 : xmlAttrPtr attr;
218 117 : if ((attr = get_attribute_ex(node->properties, "required", WSDL_NAMESPACE)) != NULL &&
219 : attr->children && attr->children->content &&
220 : (strcmp((char*)attr->children->content, "1") == 0 ||
221 : strcmp((char*)attr->children->content, "true") == 0)) {
222 1 : soap_error1(E_ERROR, "Parsing WSDL: Unknown required WSDL extension '%s'", node->ns->href);
223 : }
224 116 : return 0;
225 : }
226 40143 : return 1;
227 : }
228 :
229 : void sdl_set_uri_credentials(sdlCtx *ctx, char *uri TSRMLS_DC)
230 716 : {
231 : char *s;
232 : int l1, l2;
233 716 : zval *context = NULL;
234 716 : zval **header = NULL;
235 :
236 : /* check if we load xsd from the same server */
237 716 : s = strstr(ctx->sdl->source, "://");
238 716 : if (!s) return;
239 2 : s = strchr(s+3, '/');
240 2 : l1 = s - ctx->sdl->source;
241 2 : s = strstr((char*)uri, "://");
242 2 : if (!s) return;
243 2 : s = strchr(s+3, '/');
244 2 : l2 = s - (char*)uri;
245 2 : if (l1 != l2 || memcmp(ctx->sdl->source, uri, l1) != 0) {
246 : /* another server. clear authentication credentals */
247 2 : context = php_libxml_switch_context(NULL TSRMLS_CC);
248 2 : php_libxml_switch_context(context TSRMLS_CC);
249 2 : if (context) {
250 2 : ctx->context = php_stream_context_from_zval(context, 1);
251 :
252 2 : if (ctx->context &&
253 : php_stream_context_get_option(ctx->context, "http", "header", &header) == SUCCESS) {
254 2 : s = strstr(Z_STRVAL_PP(header), "Authorization: Basic");
255 2 : if (s && (s == Z_STRVAL_PP(header) || *(s-1) == '\n' || *(s-1) == '\r')) {
256 0 : char *rest = strstr(s, "\r\n");
257 0 : if (rest) {
258 : zval new_header;
259 :
260 0 : rest += 2;
261 0 : Z_TYPE(new_header) = IS_STRING;
262 0 : Z_STRLEN(new_header) = Z_STRLEN_PP(header) - (rest - s);
263 0 : Z_STRVAL(new_header) = emalloc(Z_STRLEN_PP(header) + 1);
264 0 : memcpy(Z_STRVAL(new_header), Z_STRVAL_PP(header), s - Z_STRVAL_PP(header));
265 0 : memcpy(Z_STRVAL(new_header) + (s - Z_STRVAL_PP(header)), rest, Z_STRLEN_PP(header) - (rest - Z_STRVAL_PP(header)) + 1);
266 0 : ctx->old_header = *header;
267 0 : Z_ADDREF_P(ctx->old_header);
268 0 : php_stream_context_set_option(ctx->context, "http", "header", &new_header);
269 0 : zval_dtor(&new_header);
270 : }
271 : }
272 : }
273 : }
274 : }
275 : }
276 :
277 : void sdl_restore_uri_credentials(sdlCtx *ctx TSRMLS_DC)
278 716 : {
279 716 : if (ctx->old_header) {
280 0 : php_stream_context_set_option(ctx->context, "http", "header", ctx->old_header);
281 0 : zval_ptr_dtor(&ctx->old_header);
282 0 : ctx->old_header = NULL;
283 : }
284 716 : ctx->context = NULL;
285 716 : }
286 :
287 : static void load_wsdl_ex(char *struri, sdlCtx *ctx, int include TSRMLS_DC)
288 716 : {
289 716 : sdlPtr tmpsdl = ctx->sdl;
290 : xmlDocPtr wsdl;
291 : xmlNodePtr root, definitions, trav;
292 : xmlAttrPtr targetNamespace;
293 :
294 716 : if (zend_hash_exists(&ctx->docs, struri, strlen(struri)+1)) {
295 4 : return;
296 : }
297 :
298 712 : sdl_set_uri_credentials(ctx, struri TSRMLS_CC);
299 712 : wsdl = soap_xmlParseFile(struri TSRMLS_CC);
300 712 : sdl_restore_uri_credentials(ctx TSRMLS_CC);
301 :
302 712 : if (!wsdl) {
303 2 : xmlErrorPtr xmlErrorPtr = xmlGetLastError();
304 2 : if (xmlErrorPtr) {
305 2 : soap_error2(E_ERROR, "Parsing WSDL: Couldn't load from '%s' : %s", struri, xmlErrorPtr->message);
306 : } else {
307 0 : soap_error1(E_ERROR, "Parsing WSDL: Couldn't load from '%s'", struri);
308 : }
309 : }
310 :
311 710 : zend_hash_add(&ctx->docs, struri, strlen(struri)+1, (void**)&wsdl, sizeof(xmlDocPtr), NULL);
312 :
313 710 : root = wsdl->children;
314 710 : definitions = get_node_ex(root, "definitions", WSDL_NAMESPACE);
315 710 : if (!definitions) {
316 6 : if (include) {
317 6 : xmlNodePtr schema = get_node_ex(root, "schema", XSD_NAMESPACE);
318 6 : if (schema) {
319 6 : load_schema(ctx, schema TSRMLS_CC);
320 6 : return;
321 : }
322 : }
323 0 : soap_error1(E_ERROR, "Parsing WSDL: Couldn't find <definitions> in '%s'", struri);
324 : }
325 :
326 704 : if (!include) {
327 691 : targetNamespace = get_attribute(definitions->properties, "targetNamespace");
328 691 : if (targetNamespace) {
329 691 : tmpsdl->target_ns = estrdup((char*)targetNamespace->children->content);
330 : }
331 : }
332 :
333 704 : trav = definitions->children;
334 17243 : while (trav != NULL) {
335 15835 : if (!is_wsdl_element(trav)) {
336 35 : trav = trav->next;
337 35 : continue;
338 : }
339 15800 : if (node_is_equal(trav,"types")) {
340 : /* TODO: Only one "types" is allowed */
341 671 : xmlNodePtr trav2 = trav->children;
342 :
343 2436 : while (trav2 != NULL) {
344 1094 : if (node_is_equal_ex(trav2, "schema", XSD_NAMESPACE)) {
345 1087 : load_schema(ctx, trav2 TSRMLS_CC);
346 7 : } else if (is_wsdl_element(trav2) && !node_is_equal(trav2,"documentation")) {
347 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
348 : }
349 1094 : trav2 = trav2->next;
350 : }
351 15129 : } else if (node_is_equal(trav,"import")) {
352 : /* TODO: namespace ??? */
353 23 : xmlAttrPtr tmp = get_attribute(trav->properties, "location");
354 23 : if (tmp) {
355 : xmlChar *uri;
356 23 : xmlChar *base = xmlNodeGetBase(trav->doc, trav);
357 :
358 23 : if (base == NULL) {
359 0 : uri = xmlBuildURI(tmp->children->content, trav->doc->URL);
360 : } else {
361 23 : uri = xmlBuildURI(tmp->children->content, base);
362 23 : xmlFree(base);
363 : }
364 23 : load_wsdl_ex((char*)uri, ctx, 1 TSRMLS_CC);
365 23 : xmlFree(uri);
366 : }
367 :
368 15106 : } else if (node_is_equal(trav,"message")) {
369 12783 : xmlAttrPtr name = get_attribute(trav->properties, "name");
370 25566 : if (name && name->children && name->children->content) {
371 12783 : if (zend_hash_add(&ctx->messages, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
372 0 : soap_error1(E_ERROR, "Parsing WSDL: <message> '%s' already defined", name->children->content);
373 : }
374 : } else {
375 0 : soap_error0(E_ERROR, "Parsing WSDL: <message> hasn't name attribute");
376 : }
377 :
378 2323 : } else if (node_is_equal(trav,"portType")) {
379 773 : xmlAttrPtr name = get_attribute(trav->properties, "name");
380 1546 : if (name && name->children && name->children->content) {
381 773 : if (zend_hash_add(&ctx->portTypes, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
382 0 : soap_error1(E_ERROR, "Parsing WSDL: <portType> '%s' already defined", name->children->content);
383 : }
384 : } else {
385 0 : soap_error0(E_ERROR, "Parsing WSDL: <portType> hasn't name attribute");
386 : }
387 :
388 1550 : } else if (node_is_equal(trav,"binding")) {
389 853 : xmlAttrPtr name = get_attribute(trav->properties, "name");
390 1706 : if (name && name->children && name->children->content) {
391 853 : if (zend_hash_add(&ctx->bindings, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
392 0 : soap_error1(E_ERROR, "Parsing WSDL: <binding> '%s' already defined", name->children->content);
393 : }
394 : } else {
395 0 : soap_error0(E_ERROR, "Parsing WSDL: <binding> hasn't name attribute");
396 : }
397 :
398 697 : } else if (node_is_equal(trav,"service")) {
399 696 : xmlAttrPtr name = get_attribute(trav->properties, "name");
400 1392 : if (name && name->children && name->children->content) {
401 696 : if (zend_hash_add(&ctx->services, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
402 0 : soap_error1(E_ERROR, "Parsing WSDL: <service> '%s' already defined", name->children->content);
403 : }
404 : } else {
405 0 : soap_error0(E_ERROR, "Parsing WSDL: <service> hasn't name attribute");
406 : }
407 1 : } else if (!node_is_equal(trav,"documentation")) {
408 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
409 : }
410 15800 : trav = trav->next;
411 : }
412 : }
413 :
414 : static sdlSoapBindingFunctionHeaderPtr wsdl_soap_binding_header(sdlCtx* ctx, xmlNodePtr header, char* wsdl_soap_namespace, int fault)
415 1603 : {
416 : xmlAttrPtr tmp;
417 : xmlNodePtr *message, part;
418 : char *ctype;
419 : sdlSoapBindingFunctionHeaderPtr h;
420 :
421 1603 : tmp = get_attribute(header->properties, "message");
422 1603 : if (!tmp) {
423 0 : soap_error0(E_ERROR, "Parsing WSDL: Missing message attribute for <header>");
424 : }
425 :
426 1603 : ctype = strrchr((char*)tmp->children->content,':');
427 1603 : if (ctype == NULL) {
428 0 : ctype = (char*)tmp->children->content;
429 : } else {
430 1603 : ++ctype;
431 : }
432 1603 : if (zend_hash_find(&ctx->messages, ctype, strlen(ctype)+1, (void**)&message) != SUCCESS) {
433 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing <message> with name '%s'", tmp->children->content);
434 : }
435 :
436 1603 : tmp = get_attribute(header->properties, "part");
437 1603 : if (!tmp) {
438 0 : soap_error0(E_ERROR, "Parsing WSDL: Missing part attribute for <header>");
439 : }
440 1603 : part = get_node_with_attribute_ex((*message)->children, "part", WSDL_NAMESPACE, "name", (char*)tmp->children->content, NULL);
441 1603 : if (!part) {
442 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing part '%s' in <message>", tmp->children->content);
443 : }
444 :
445 1603 : h = emalloc(sizeof(sdlSoapBindingFunctionHeader));
446 1603 : memset(h, 0, sizeof(sdlSoapBindingFunctionHeader));
447 1603 : h->name = estrdup((char*)tmp->children->content);
448 :
449 1603 : tmp = get_attribute(header->properties, "use");
450 1758 : if (tmp && !strncmp((char*)tmp->children->content, "encoded", sizeof("encoded"))) {
451 155 : h->use = SOAP_ENCODED;
452 : } else {
453 1448 : h->use = SOAP_LITERAL;
454 : }
455 :
456 1603 : tmp = get_attribute(header->properties, "namespace");
457 1603 : if (tmp) {
458 148 : h->ns = estrdup((char*)tmp->children->content);
459 : }
460 :
461 1603 : if (h->use == SOAP_ENCODED) {
462 155 : tmp = get_attribute(header->properties, "encodingStyle");
463 155 : if (tmp) {
464 155 : if (strncmp((char*)tmp->children->content, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)) == 0) {
465 9 : h->encodingStyle = SOAP_ENCODING_1_1;
466 146 : } else if (strncmp((char*)tmp->children->content, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)) == 0) {
467 146 : h->encodingStyle = SOAP_ENCODING_1_2;
468 : } else {
469 0 : soap_error1(E_ERROR, "Parsing WSDL: Unknown encodingStyle '%s'", tmp->children->content);
470 : }
471 : } else {
472 0 : soap_error0(E_ERROR, "Parsing WSDL: Unspecified encodingStyle");
473 : }
474 : }
475 :
476 1603 : tmp = get_attribute(part->properties, "type");
477 1603 : if (tmp != NULL) {
478 155 : h->encode = get_encoder_from_prefix(ctx->sdl, part, tmp->children->content);
479 : } else {
480 1448 : tmp = get_attribute(part->properties, "element");
481 1448 : if (tmp != NULL) {
482 1448 : h->element = get_element(ctx->sdl, part, tmp->children->content);
483 1448 : if (h->element) {
484 1448 : h->encode = h->element->encode;
485 1448 : if (!h->ns && h->element->namens) {
486 1448 : h->ns = estrdup(h->element->namens);
487 : }
488 1448 : if (h->element->name) {
489 1448 : efree(h->name);
490 1448 : h->name = estrdup(h->element->name);
491 : }
492 : }
493 : }
494 : }
495 1603 : if (!fault) {
496 1530 : xmlNodePtr trav = header->children;
497 3133 : while (trav != NULL) {
498 73 : if (node_is_equal_ex(trav, "headerfault", wsdl_soap_namespace)) {
499 73 : sdlSoapBindingFunctionHeaderPtr hf = wsdl_soap_binding_header(ctx, trav, wsdl_soap_namespace, 1);
500 73 : smart_str key = {0};
501 :
502 73 : if (h->headerfaults == NULL) {
503 73 : h->headerfaults = emalloc(sizeof(HashTable));
504 73 : zend_hash_init(h->headerfaults, 0, NULL, delete_header, 0);
505 : }
506 :
507 73 : if (hf->ns) {
508 73 : smart_str_appends(&key,hf->ns);
509 73 : smart_str_appendc(&key,':');
510 : }
511 73 : smart_str_appends(&key,hf->name);
512 73 : smart_str_0(&key);
513 73 : if (zend_hash_add(h->headerfaults, key.c, key.len+1, (void**)&hf, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL) != SUCCESS) {
514 0 : delete_header((void**)&hf);
515 : }
516 73 : smart_str_free(&key);
517 0 : } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
518 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
519 : }
520 73 : trav = trav->next;
521 : }
522 : }
523 1603 : return h;
524 : }
525 :
526 : static void wsdl_soap_binding_body(sdlCtx* ctx, xmlNodePtr node, char* wsdl_soap_namespace, sdlSoapBindingFunctionBody *binding, HashTable* params)
527 14744 : {
528 : xmlNodePtr body, trav;
529 : xmlAttrPtr tmp;
530 :
531 14744 : trav = node->children;
532 45772 : while (trav != NULL) {
533 16284 : if (node_is_equal_ex(trav, "body", wsdl_soap_namespace)) {
534 14742 : body = trav;
535 :
536 14742 : tmp = get_attribute(body->properties, "use");
537 22852 : if (tmp && !strncmp((char*)tmp->children->content, "literal", sizeof("literal"))) {
538 8110 : binding->use = SOAP_LITERAL;
539 : } else {
540 6632 : binding->use = SOAP_ENCODED;
541 : }
542 :
543 14742 : tmp = get_attribute(body->properties, "namespace");
544 14742 : if (tmp) {
545 6775 : binding->ns = estrdup((char*)tmp->children->content);
546 : }
547 :
548 14742 : tmp = get_attribute(body->properties, "parts");
549 14742 : if (tmp) {
550 : HashTable ht;
551 0 : char *parts = (char*)tmp->children->content;
552 :
553 : /* Delete all parts those are not in the "parts" attribute */
554 0 : zend_hash_init(&ht, 0, NULL, delete_parameter, 0);
555 0 : while (*parts) {
556 : HashPosition pos;
557 : sdlParamPtr *param;
558 0 : int found = 0;
559 : char *end;
560 :
561 0 : while (*parts == ' ') ++parts;
562 0 : if (*parts == '\0') break;
563 0 : end = strchr(parts, ' ');
564 0 : if (end) *end = '\0';
565 0 : zend_hash_internal_pointer_reset_ex(params, &pos);
566 0 : while (zend_hash_get_current_data_ex(params, (void **)¶m, &pos) != FAILURE) {
567 0 : if ((*param)->paramName &&
568 : strcmp(parts, (*param)->paramName) == 0) {
569 : sdlParamPtr x_param;
570 0 : x_param = emalloc(sizeof(sdlParam));
571 0 : *x_param = **param;
572 0 : (*param)->paramName = NULL;
573 0 : zend_hash_next_index_insert(&ht, &x_param, sizeof(sdlParamPtr), NULL);
574 0 : found = 1;
575 0 : break;
576 : }
577 0 : zend_hash_move_forward_ex(params, &pos);
578 : }
579 0 : if (!found) {
580 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing part '%s' in <message>", parts);
581 : }
582 0 : parts += strlen(parts);
583 0 : if (end) *end = ' ';
584 : }
585 0 : zend_hash_destroy(params);
586 0 : *params = ht;
587 : }
588 :
589 14742 : if (binding->use == SOAP_ENCODED) {
590 6632 : tmp = get_attribute(body->properties, "encodingStyle");
591 6632 : if (tmp) {
592 6632 : if (strncmp((char*)tmp->children->content, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)) == 0) {
593 4004 : binding->encodingStyle = SOAP_ENCODING_1_1;
594 2628 : } else if (strncmp((char*)tmp->children->content, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)) == 0) {
595 2628 : binding->encodingStyle = SOAP_ENCODING_1_2;
596 : } else {
597 0 : soap_error1(E_ERROR, "Parsing WSDL: Unknown encodingStyle '%s'", tmp->children->content);
598 : }
599 : } else {
600 0 : soap_error0(E_ERROR, "Parsing WSDL: Unspecified encodingStyle");
601 : }
602 : }
603 1542 : } else if (node_is_equal_ex(trav, "header", wsdl_soap_namespace)) {
604 1530 : sdlSoapBindingFunctionHeaderPtr h = wsdl_soap_binding_header(ctx, trav, wsdl_soap_namespace, 0);
605 1530 : smart_str key = {0};
606 :
607 1530 : if (binding->headers == NULL) {
608 880 : binding->headers = emalloc(sizeof(HashTable));
609 880 : zend_hash_init(binding->headers, 0, NULL, delete_header, 0);
610 : }
611 :
612 1530 : if (h->ns) {
613 1523 : smart_str_appends(&key,h->ns);
614 1523 : smart_str_appendc(&key,':');
615 : }
616 1530 : smart_str_appends(&key,h->name);
617 1530 : smart_str_0(&key);
618 1530 : if (zend_hash_add(binding->headers, key.c, key.len+1, (void**)&h, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL) != SUCCESS) {
619 0 : delete_header((void**)&h);
620 : }
621 1530 : smart_str_free(&key);
622 12 : } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
623 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
624 : }
625 16284 : trav = trav->next;
626 : }
627 14744 : }
628 :
629 : static HashTable* wsdl_message(sdlCtx *ctx, xmlChar* message_name)
630 15956 : {
631 15956 : xmlNodePtr trav, part, message = NULL, *tmp;
632 15956 : HashTable* parameters = NULL;
633 : char *ctype;
634 :
635 15956 : ctype = strrchr((char*)message_name,':');
636 15956 : if (ctype == NULL) {
637 179 : ctype = (char*)message_name;
638 : } else {
639 15777 : ++ctype;
640 : }
641 15956 : if (zend_hash_find(&ctx->messages, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) {
642 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing <message> with name '%s'", message_name);
643 : }
644 15956 : message = *tmp;
645 :
646 15956 : parameters = emalloc(sizeof(HashTable));
647 15956 : zend_hash_init(parameters, 0, NULL, delete_parameter, 0);
648 :
649 15956 : trav = message->children;
650 47748 : while (trav != NULL) {
651 : xmlAttrPtr element, type, name;
652 : sdlParamPtr param;
653 :
654 15836 : if (trav->ns != NULL && strcmp((char*)trav->ns->href, WSDL_NAMESPACE) != 0) {
655 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected extensibility element <%s>", trav->name);
656 : }
657 15836 : if (node_is_equal(trav,"documentation")) {
658 8 : trav = trav->next;
659 8 : continue;
660 : }
661 15828 : if (!node_is_equal(trav,"part")) {
662 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
663 : }
664 15828 : part = trav;
665 15828 : param = emalloc(sizeof(sdlParam));
666 15828 : memset(param,0,sizeof(sdlParam));
667 15828 : param->order = 0;
668 :
669 15828 : name = get_attribute(part->properties, "name");
670 15828 : if (name == NULL) {
671 0 : soap_error1(E_ERROR, "Parsing WSDL: No name associated with <part> '%s'", message->name);
672 : }
673 :
674 15828 : param->paramName = estrdup((char*)name->children->content);
675 :
676 15828 : type = get_attribute(part->properties, "type");
677 15828 : if (type != NULL) {
678 7313 : param->encode = get_encoder_from_prefix(ctx->sdl, part, type->children->content);
679 : } else {
680 8515 : element = get_attribute(part->properties, "element");
681 8515 : if (element != NULL) {
682 8515 : param->element = get_element(ctx->sdl, part, element->children->content);
683 8515 : if (param->element) {
684 8514 : param->encode = param->element->encode;
685 : }
686 : }
687 : }
688 :
689 15828 : zend_hash_next_index_insert(parameters, ¶m, sizeof(sdlParamPtr), NULL);
690 :
691 15828 : trav = trav->next;
692 : }
693 15956 : return parameters;
694 : }
695 :
696 : static sdlPtr load_wsdl(char *struri TSRMLS_DC)
697 693 : {
698 : sdlCtx ctx;
699 : int i,n;
700 :
701 693 : memset(&ctx,0,sizeof(ctx));
702 693 : ctx.sdl = emalloc(sizeof(sdl));
703 693 : memset(ctx.sdl, 0, sizeof(sdl));
704 693 : ctx.sdl->source = estrdup(struri);
705 693 : zend_hash_init(&ctx.sdl->functions, 0, NULL, delete_function, 0);
706 :
707 693 : zend_hash_init(&ctx.docs, 0, NULL, delete_document, 0);
708 693 : zend_hash_init(&ctx.messages, 0, NULL, NULL, 0);
709 693 : zend_hash_init(&ctx.bindings, 0, NULL, NULL, 0);
710 693 : zend_hash_init(&ctx.portTypes, 0, NULL, NULL, 0);
711 693 : zend_hash_init(&ctx.services, 0, NULL, NULL, 0);
712 :
713 693 : load_wsdl_ex(struri,&ctx, 0 TSRMLS_CC);
714 691 : schema_pass2(&ctx);
715 :
716 691 : n = zend_hash_num_elements(&ctx.services);
717 691 : if (n > 0) {
718 691 : zend_hash_internal_pointer_reset(&ctx.services);
719 1386 : for (i = 0; i < n; i++) {
720 : xmlNodePtr *tmp, service;
721 : xmlNodePtr trav, port;
722 696 : int has_soap_port = 0;
723 :
724 696 : zend_hash_get_current_data(&ctx.services, (void **)&tmp);
725 696 : service = *tmp;
726 :
727 696 : trav = service->children;
728 2322 : while (trav != NULL) {
729 : xmlAttrPtr type, name, bindingAttr, location;
730 : xmlNodePtr portType, operation;
731 : xmlNodePtr address, binding, trav2;
732 : char *ctype;
733 : sdlBindingPtr tmpbinding;
734 931 : char *wsdl_soap_namespace = NULL;
735 :
736 931 : if (!is_wsdl_element(trav) || node_is_equal(trav,"documentation")) {
737 78 : trav = trav->next;
738 78 : continue;
739 : }
740 853 : if (!node_is_equal(trav,"port")) {
741 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
742 : }
743 :
744 853 : port = trav;
745 :
746 853 : tmpbinding = emalloc(sizeof(sdlBinding));
747 853 : memset(tmpbinding, 0, sizeof(sdlBinding));
748 :
749 853 : bindingAttr = get_attribute(port->properties, "binding");
750 853 : if (bindingAttr == NULL) {
751 0 : soap_error0(E_ERROR, "Parsing WSDL: No binding associated with <port>");
752 : }
753 :
754 : /* find address and figure out binding type */
755 853 : address = NULL;
756 853 : trav2 = port->children;
757 2564 : while (trav2 != NULL) {
758 858 : if (node_is_equal(trav2,"address") && trav2->ns) {
759 858 : if (!strncmp((char*)trav2->ns->href, WSDL_SOAP11_NAMESPACE, sizeof(WSDL_SOAP11_NAMESPACE))) {
760 621 : address = trav2;
761 621 : wsdl_soap_namespace = WSDL_SOAP11_NAMESPACE;
762 621 : tmpbinding->bindingType = BINDING_SOAP;
763 237 : } else if (!strncmp((char*)trav2->ns->href, WSDL_SOAP12_NAMESPACE, sizeof(WSDL_SOAP12_NAMESPACE))) {
764 223 : address = trav2;
765 223 : wsdl_soap_namespace = WSDL_SOAP12_NAMESPACE;
766 223 : tmpbinding->bindingType = BINDING_SOAP;
767 14 : } else if (!strncmp((char*)trav2->ns->href, RPC_SOAP12_NAMESPACE, sizeof(RPC_SOAP12_NAMESPACE))) {
768 0 : address = trav2;
769 0 : wsdl_soap_namespace = RPC_SOAP12_NAMESPACE;
770 0 : tmpbinding->bindingType = BINDING_SOAP;
771 14 : } else if (!strncmp((char*)trav2->ns->href, WSDL_HTTP11_NAMESPACE, sizeof(WSDL_HTTP11_NAMESPACE))) {
772 7 : address = trav2;
773 7 : tmpbinding->bindingType = BINDING_HTTP;
774 7 : } else if (!strncmp((char*)trav2->ns->href, WSDL_HTTP12_NAMESPACE, sizeof(WSDL_HTTP12_NAMESPACE))) {
775 0 : address = trav2;
776 0 : tmpbinding->bindingType = BINDING_HTTP;
777 : }
778 : }
779 858 : if (trav2 != address && is_wsdl_element(trav2) && !node_is_equal(trav2,"documentation")) {
780 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
781 : }
782 858 : trav2 = trav2->next;
783 : }
784 853 : if (!address || tmpbinding->bindingType == BINDING_HTTP) {
785 9 : if (has_soap_port || trav->next || i < n-1) {
786 8 : efree(tmpbinding);
787 8 : trav = trav->next;
788 8 : continue;
789 1 : } else if (!address) {
790 0 : soap_error0(E_ERROR, "Parsing WSDL: No address associated with <port>");
791 : }
792 : }
793 845 : has_soap_port = 1;
794 :
795 845 : location = get_attribute(address->properties, "location");
796 845 : if (!location) {
797 0 : soap_error0(E_ERROR, "Parsing WSDL: No location associated with <port>");
798 : }
799 :
800 845 : tmpbinding->location = estrdup((char*)location->children->content);
801 :
802 845 : ctype = strrchr((char*)bindingAttr->children->content,':');
803 845 : if (ctype == NULL) {
804 0 : ctype = (char*)bindingAttr->children->content;
805 : } else {
806 845 : ++ctype;
807 : }
808 845 : if (zend_hash_find(&ctx.bindings, ctype, strlen(ctype)+1, (void*)&tmp) != SUCCESS) {
809 0 : soap_error1(E_ERROR, "Parsing WSDL: No <binding> element with name '%s'", ctype);
810 : }
811 845 : binding = *tmp;
812 :
813 845 : if (tmpbinding->bindingType == BINDING_SOAP) {
814 : sdlSoapBindingPtr soapBinding;
815 : xmlNodePtr soapBindingNode;
816 : xmlAttrPtr tmp;
817 :
818 844 : soapBinding = emalloc(sizeof(sdlSoapBinding));
819 844 : memset(soapBinding, 0, sizeof(sdlSoapBinding));
820 844 : soapBinding->style = SOAP_DOCUMENT;
821 :
822 844 : soapBindingNode = get_node_ex(binding->children, "binding", wsdl_soap_namespace);
823 844 : if (soapBindingNode) {
824 844 : tmp = get_attribute(soapBindingNode->properties, "style");
825 844 : if (tmp && !strncmp((char*)tmp->children->content, "rpc", sizeof("rpc"))) {
826 504 : soapBinding->style = SOAP_RPC;
827 : }
828 :
829 844 : tmp = get_attribute(soapBindingNode->properties, "transport");
830 844 : if (tmp) {
831 844 : if (strncmp((char*)tmp->children->content, WSDL_HTTP_TRANSPORT, sizeof(WSDL_HTTP_TRANSPORT)) == 0) {
832 844 : soapBinding->transport = SOAP_TRANSPORT_HTTP;
833 : } else {
834 0 : soap_error1(E_ERROR, "Parsing WSDL: PHP-SOAP doesn't support transport '%s'", tmp->children->content);
835 : }
836 : }
837 : }
838 844 : tmpbinding->bindingAttributes = (void *)soapBinding;
839 : }
840 :
841 845 : name = get_attribute(binding->properties, "name");
842 845 : if (name == NULL) {
843 0 : soap_error0(E_ERROR, "Parsing WSDL: Missing 'name' attribute for <binding>");
844 : }
845 845 : tmpbinding->name = estrdup((char*)name->children->content);
846 :
847 845 : type = get_attribute(binding->properties, "type");
848 845 : if (type == NULL) {
849 0 : soap_error0(E_ERROR, "Parsing WSDL: Missing 'type' attribute for <binding>");
850 : }
851 :
852 845 : ctype = strrchr((char*)type->children->content,':');
853 845 : if (ctype == NULL) {
854 175 : ctype = (char*)type->children->content;
855 : } else {
856 670 : ++ctype;
857 : }
858 845 : if (zend_hash_find(&ctx.portTypes, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) {
859 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing <portType> with name '%s'", name->children->content);
860 : }
861 845 : portType = *tmp;
862 :
863 845 : trav2 = binding->children;
864 10039 : while (trav2 != NULL) {
865 : sdlFunctionPtr function;
866 : xmlNodePtr input, output, fault, portTypeOperation, trav3;
867 : xmlAttrPtr op_name, paramOrder;
868 :
869 8350 : if ((tmpbinding->bindingType == BINDING_SOAP &&
870 : node_is_equal_ex(trav2, "binding", wsdl_soap_namespace)) ||
871 : !is_wsdl_element(trav2) ||
872 : node_is_equal(trav2,"documentation")) {
873 852 : trav2 = trav2->next;
874 852 : continue;
875 : }
876 7497 : if (!node_is_equal(trav2,"operation")) {
877 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
878 : }
879 :
880 7497 : operation = trav2;
881 :
882 7497 : op_name = get_attribute(operation->properties, "name");
883 7497 : if (op_name == NULL) {
884 0 : soap_error0(E_ERROR, "Parsing WSDL: Missing 'name' attribute for <operation>");
885 : }
886 :
887 7497 : trav3 = operation->children;
888 38452 : while (trav3 != NULL) {
889 23458 : if (tmpbinding->bindingType == BINDING_SOAP &&
890 : node_is_equal_ex(trav3, "operation", wsdl_soap_namespace)) {
891 15963 : } else if (is_wsdl_element(trav3) &&
892 : !node_is_equal(trav3,"input") &&
893 : !node_is_equal(trav3,"output") &&
894 : !node_is_equal(trav3,"fault") &&
895 : !node_is_equal(trav3,"documentation")) {
896 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav3->name);
897 : }
898 23458 : trav3 = trav3->next;
899 : }
900 :
901 7497 : portTypeOperation = get_node_with_attribute_ex(portType->children, "operation", WSDL_NAMESPACE, "name", (char*)op_name->children->content, NULL);
902 7497 : if (portTypeOperation == NULL) {
903 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing <portType>/<operation> with name '%s'", op_name->children->content);
904 : }
905 :
906 7497 : function = emalloc(sizeof(sdlFunction));
907 7497 : memset(function, 0, sizeof(sdlFunction));
908 7497 : function->functionName = estrdup((char*)op_name->children->content);
909 :
910 7497 : if (tmpbinding->bindingType == BINDING_SOAP) {
911 : sdlSoapBindingFunctionPtr soapFunctionBinding;
912 : sdlSoapBindingPtr soapBinding;
913 : xmlNodePtr soapOperation;
914 : xmlAttrPtr tmp;
915 :
916 7496 : soapFunctionBinding = emalloc(sizeof(sdlSoapBindingFunction));
917 7496 : memset(soapFunctionBinding, 0, sizeof(sdlSoapBindingFunction));
918 7496 : soapBinding = (sdlSoapBindingPtr)tmpbinding->bindingAttributes;
919 7496 : soapFunctionBinding->style = soapBinding->style;
920 :
921 7496 : soapOperation = get_node_ex(operation->children, "operation", wsdl_soap_namespace);
922 7496 : if (soapOperation) {
923 7495 : tmp = get_attribute(soapOperation->properties, "soapAction");
924 7495 : if (tmp) {
925 5813 : soapFunctionBinding->soapAction = estrdup((char*)tmp->children->content);
926 : }
927 :
928 7495 : tmp = get_attribute(soapOperation->properties, "style");
929 7495 : if (tmp) {
930 4951 : if (!strncmp((char*)tmp->children->content, "rpc", sizeof("rpc"))) {
931 1596 : soapFunctionBinding->style = SOAP_RPC;
932 : } else {
933 3355 : soapFunctionBinding->style = SOAP_DOCUMENT;
934 : }
935 : } else {
936 2544 : soapFunctionBinding->style = soapBinding->style;
937 : }
938 : }
939 :
940 7496 : function->bindingAttributes = (void *)soapFunctionBinding;
941 : }
942 :
943 7497 : input = get_node_ex(portTypeOperation->children, "input", WSDL_NAMESPACE);
944 7497 : if (input != NULL) {
945 : xmlAttrPtr message, name;
946 :
947 7497 : message = get_attribute(input->properties, "message");
948 7497 : if (message == NULL) {
949 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing name for <input> of '%s'", op_name->children->content);
950 : }
951 7497 : function->requestParameters = wsdl_message(&ctx, message->children->content);
952 :
953 7497 : name = get_attribute(input->properties, "name");
954 : /* FIXME
955 : if (name != NULL) {
956 : function->requestName = estrdup(name->children->content);
957 : } else {
958 : */
959 : {
960 7497 : function->requestName = estrdup(function->functionName);
961 : }
962 :
963 7497 : if (tmpbinding->bindingType == BINDING_SOAP) {
964 7496 : input = get_node_ex(operation->children, "input", WSDL_NAMESPACE);
965 7496 : if (input != NULL) {
966 7496 : sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes;
967 7496 : wsdl_soap_binding_body(&ctx, input, wsdl_soap_namespace, &soapFunctionBinding->input, function->requestParameters);
968 : }
969 : }
970 : }
971 :
972 7497 : output = get_node_ex(portTypeOperation->children, "output", WSDL_NAMESPACE);
973 7497 : if (output != NULL) {
974 : xmlAttrPtr message, name;
975 :
976 7249 : message = get_attribute(output->properties, "message");
977 7249 : if (message == NULL) {
978 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing name for <output> of '%s'", op_name->children->content);
979 : }
980 7249 : function->responseParameters = wsdl_message(&ctx, message->children->content);
981 :
982 7249 : name = get_attribute(output->properties, "name");
983 : /* FIXME
984 : if (name != NULL) {
985 : function->responseName = estrdup(name->children->content);
986 : } else if (input == NULL) {
987 : function->responseName = estrdup(function->functionName);
988 : } else {
989 : */
990 : {
991 7249 : int len = strlen(function->functionName);
992 7249 : function->responseName = emalloc(len + sizeof("Response"));
993 7249 : memcpy(function->responseName, function->functionName, len);
994 7249 : memcpy(function->responseName+len, "Response", sizeof("Response"));
995 : }
996 :
997 7249 : if (tmpbinding->bindingType == BINDING_SOAP) {
998 7248 : output = get_node_ex(operation->children, "output", WSDL_NAMESPACE);
999 7248 : if (output != NULL) {
1000 7248 : sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes;
1001 7248 : wsdl_soap_binding_body(&ctx, output, wsdl_soap_namespace, &soapFunctionBinding->output, function->responseParameters);
1002 : }
1003 : }
1004 : }
1005 :
1006 7497 : paramOrder = get_attribute(portTypeOperation->properties, "parameterOrder");
1007 : if (paramOrder) {
1008 : /* FIXME: */
1009 : }
1010 :
1011 7497 : fault = portTypeOperation->children;
1012 30962 : while (fault != NULL) {
1013 15968 : if (node_is_equal_ex(fault, "fault", WSDL_NAMESPACE)) {
1014 : xmlAttrPtr message, name;
1015 : sdlFaultPtr f;
1016 :
1017 1210 : name = get_attribute(fault->properties, "name");
1018 1210 : if (name == NULL) {
1019 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing name for <fault> of '%s'", op_name->children->content);
1020 : }
1021 1210 : message = get_attribute(fault->properties, "message");
1022 1210 : if (message == NULL) {
1023 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing name for <output> of '%s'", op_name->children->content);
1024 : }
1025 :
1026 1210 : f = emalloc(sizeof(sdlFault));
1027 1210 : memset(f, 0, sizeof(sdlFault));
1028 :
1029 1210 : f->name = estrdup((char*)name->children->content);
1030 1210 : f->details = wsdl_message(&ctx, message->children->content);
1031 1210 : if (f->details == NULL || zend_hash_num_elements(f->details) > 1) {
1032 0 : soap_error1(E_ERROR, "Parsing WSDL: The fault message '%s' must have a single part", message->children->content);
1033 : }
1034 :
1035 1210 : if (tmpbinding->bindingType == BINDING_SOAP) {
1036 1210 : xmlNodePtr soap_fault = get_node_with_attribute_ex(operation->children, "fault", WSDL_NAMESPACE, "name", f->name, NULL);
1037 1210 : if (soap_fault != NULL) {
1038 1176 : xmlNodePtr trav = soap_fault->children;
1039 3528 : while (trav != NULL) {
1040 1176 : if (node_is_equal_ex(trav, "fault", wsdl_soap_namespace)) {
1041 : xmlAttrPtr tmp;
1042 : sdlSoapBindingFunctionFaultPtr binding;
1043 :
1044 1176 : binding = f->bindingAttributes = emalloc(sizeof(sdlSoapBindingFunctionFault));
1045 1176 : memset(f->bindingAttributes, 0, sizeof(sdlSoapBindingFunctionFault));
1046 :
1047 1176 : tmp = get_attribute(trav->properties, "use");
1048 1784 : if (tmp && !strncmp((char*)tmp->children->content, "encoded", sizeof("encoded"))) {
1049 608 : binding->use = SOAP_ENCODED;
1050 : } else {
1051 568 : binding->use = SOAP_LITERAL;
1052 : }
1053 :
1054 1176 : tmp = get_attribute(trav->properties, "namespace");
1055 1176 : if (tmp) {
1056 608 : binding->ns = estrdup((char*)tmp->children->content);
1057 : }
1058 :
1059 1176 : if (binding->use == SOAP_ENCODED) {
1060 608 : tmp = get_attribute(trav->properties, "encodingStyle");
1061 608 : if (tmp) {
1062 608 : if (strncmp((char*)tmp->children->content, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)) == 0) {
1063 608 : binding->encodingStyle = SOAP_ENCODING_1_1;
1064 0 : } else if (strncmp((char*)tmp->children->content, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)) == 0) {
1065 0 : binding->encodingStyle = SOAP_ENCODING_1_2;
1066 : } else {
1067 0 : soap_error1(E_ERROR, "Parsing WSDL: Unknown encodingStyle '%s'", tmp->children->content);
1068 : }
1069 : } else {
1070 0 : soap_error0(E_ERROR, "Parsing WSDL: Unspecified encodingStyle");
1071 : }
1072 : }
1073 0 : } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
1074 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
1075 : }
1076 1176 : trav = trav->next;
1077 : }
1078 : }
1079 : }
1080 1210 : if (function->faults == NULL) {
1081 682 : function->faults = emalloc(sizeof(HashTable));
1082 682 : zend_hash_init(function->faults, 0, NULL, delete_fault, 0);
1083 : }
1084 1210 : if (zend_hash_add(function->faults, f->name, strlen(f->name)+1, (void**)&f, sizeof(sdlFaultPtr), NULL) != SUCCESS) {
1085 0 : soap_error2(E_ERROR, "Parsing WSDL: <fault> with name '%s' already defined in '%s'", f->name, op_name->children->content);
1086 : }
1087 : }
1088 15968 : fault = fault->next;
1089 : }
1090 :
1091 7497 : function->binding = tmpbinding;
1092 :
1093 : {
1094 7497 : char *tmp = estrdup(function->functionName);
1095 7497 : int len = strlen(tmp);
1096 :
1097 7497 : if (zend_hash_add(&ctx.sdl->functions, php_strtolower(tmp, len), len+1, &function, sizeof(sdlFunctionPtr), NULL) != SUCCESS) {
1098 1628 : zend_hash_next_index_insert(&ctx.sdl->functions, &function, sizeof(sdlFunctionPtr), NULL);
1099 : }
1100 7497 : efree(tmp);
1101 7497 : if (function->requestName != NULL && strcmp(function->requestName,function->functionName) != 0) {
1102 0 : if (ctx.sdl->requests == NULL) {
1103 0 : ctx.sdl->requests = emalloc(sizeof(HashTable));
1104 0 : zend_hash_init(ctx.sdl->requests, 0, NULL, NULL, 0);
1105 : }
1106 0 : tmp = estrdup(function->requestName);
1107 0 : len = strlen(tmp);
1108 0 : zend_hash_add(ctx.sdl->requests, php_strtolower(tmp, len), len+1, &function, sizeof(sdlFunctionPtr), NULL);
1109 0 : efree(tmp);
1110 : }
1111 : }
1112 7497 : trav2 = trav2->next;
1113 : }
1114 :
1115 844 : if (!ctx.sdl->bindings) {
1116 690 : ctx.sdl->bindings = emalloc(sizeof(HashTable));
1117 690 : zend_hash_init(ctx.sdl->bindings, 0, NULL, delete_binding, 0);
1118 : }
1119 :
1120 844 : zend_hash_add(ctx.sdl->bindings, tmpbinding->name, strlen(tmpbinding->name), &tmpbinding, sizeof(sdlBindingPtr), NULL);
1121 844 : trav= trav->next;
1122 : }
1123 :
1124 695 : zend_hash_move_forward(&ctx.services);
1125 : }
1126 : } else {
1127 0 : soap_error0(E_ERROR, "Parsing WSDL: Couldn't bind to service");
1128 : }
1129 :
1130 690 : zend_hash_destroy(&ctx.messages);
1131 690 : zend_hash_destroy(&ctx.bindings);
1132 690 : zend_hash_destroy(&ctx.portTypes);
1133 690 : zend_hash_destroy(&ctx.services);
1134 690 : zend_hash_destroy(&ctx.docs);
1135 :
1136 690 : return ctx.sdl;
1137 : }
1138 :
1139 : #define WSDL_CACHE_VERSION 0x2e
1140 :
1141 : #define WSDL_CACHE_GET(ret,type,buf) memcpy(&ret,*buf,sizeof(type)); *buf += sizeof(type);
1142 : #define WSDL_CACHE_GET_INT(ret,buf) ret = ((unsigned char)(*buf)[0])|((unsigned char)(*buf)[1]<<8)|((unsigned char)(*buf)[2]<<16)|((int)(*buf)[3]<<24); *buf += 4;
1143 : #define WSDL_CACHE_GET_1(ret,type,buf) ret = (type)(**buf); (*buf)++;
1144 : #define WSDL_CACHE_GET_N(ret,n,buf) memcpy(ret,*buf,n); *buf += n;
1145 : #define WSDL_CACHE_SKIP(n,buf) *buf += n;
1146 :
1147 : #define WSDL_CACHE_PUT_INT(val,buf) smart_str_appendc(buf,val & 0xff); \
1148 : smart_str_appendc(buf,(val >> 8) & 0xff); \
1149 : smart_str_appendc(buf,(val >> 16) & 0xff); \
1150 : smart_str_appendc(buf,(val >> 24) & 0xff);
1151 : #define WSDL_CACHE_PUT_1(val,buf) smart_str_appendc(buf,val);
1152 : #define WSDL_CACHE_PUT_N(val,n,buf) smart_str_appendl(buf,(char*)val,n);
1153 :
1154 : static char* sdl_deserialize_string(char **in)
1155 90 : {
1156 : char *s;
1157 : int len;
1158 :
1159 90 : WSDL_CACHE_GET_INT(len, in);
1160 90 : if (len == 0x7fffffff) {
1161 29 : return NULL;
1162 : } else {
1163 61 : s = emalloc(len+1);
1164 61 : WSDL_CACHE_GET_N(s, len, in);
1165 61 : s[len] = '\0';
1166 61 : return s;
1167 : }
1168 : }
1169 :
1170 : static void sdl_deserialize_key(HashTable* ht, void* data, char **in)
1171 27 : {
1172 : int len;
1173 :
1174 27 : WSDL_CACHE_GET_INT(len, in);
1175 27 : if (len == 0) {
1176 10 : zend_hash_next_index_insert(ht, &data, sizeof(void*), NULL);
1177 : } else {
1178 17 : zend_hash_add(ht, *in, len, &data, sizeof(void*), NULL);
1179 17 : WSDL_CACHE_SKIP(len, in);
1180 : }
1181 27 : }
1182 :
1183 : static void sdl_deserialize_attribute(sdlAttributePtr attr, encodePtr *encoders, char **in)
1184 0 : {
1185 : int i;
1186 :
1187 0 : attr->name = sdl_deserialize_string(in);
1188 0 : attr->namens = sdl_deserialize_string(in);
1189 0 : attr->ref = sdl_deserialize_string(in);
1190 0 : attr->def = sdl_deserialize_string(in);
1191 0 : attr->fixed = sdl_deserialize_string(in);
1192 0 : WSDL_CACHE_GET_1(attr->form, sdlForm, in);
1193 0 : WSDL_CACHE_GET_1(attr->use, sdlUse, in);
1194 0 : WSDL_CACHE_GET_INT(i, in);
1195 0 : attr->encode = encoders[i];
1196 0 : WSDL_CACHE_GET_INT(i, in);
1197 0 : if (i > 0) {
1198 0 : attr->extraAttributes = emalloc(sizeof(HashTable));
1199 0 : zend_hash_init(attr->extraAttributes, i, NULL, delete_extra_attribute, 0);
1200 0 : while (i > 0) {
1201 0 : sdlExtraAttributePtr x = emalloc(sizeof(sdlExtraAttribute));
1202 0 : sdl_deserialize_key(attr->extraAttributes, x, in);
1203 0 : x->ns = sdl_deserialize_string(in);
1204 0 : x->val = sdl_deserialize_string(in);
1205 0 : --i;
1206 : }
1207 : }
1208 0 : }
1209 :
1210 : static sdlRestrictionIntPtr sdl_deserialize_resriction_int(char **in)
1211 0 : {
1212 0 : if (**in == 1) {
1213 0 : sdlRestrictionIntPtr x = emalloc(sizeof(sdlRestrictionInt));
1214 0 : WSDL_CACHE_SKIP(1, in);
1215 0 : WSDL_CACHE_GET_INT(x->value, in);
1216 0 : WSDL_CACHE_GET_1(x->fixed, char, in);
1217 0 : return x;
1218 : } else {
1219 0 : WSDL_CACHE_SKIP(1, in);
1220 0 : return NULL;
1221 : }
1222 : }
1223 :
1224 : static sdlRestrictionCharPtr sdl_deserialize_resriction_char(char **in)
1225 0 : {
1226 0 : if (**in == 1) {
1227 0 : sdlRestrictionCharPtr x = emalloc(sizeof(sdlRestrictionChar));
1228 0 : WSDL_CACHE_SKIP(1, in);
1229 0 : x->value = sdl_deserialize_string(in);
1230 0 : WSDL_CACHE_GET_1(x->fixed, char, in);
1231 0 : return x;
1232 : } else {
1233 0 : WSDL_CACHE_SKIP(1, in);
1234 0 : return NULL;
1235 : }
1236 : }
1237 :
1238 : static sdlContentModelPtr sdl_deserialize_model(sdlTypePtr *types, sdlTypePtr *elements, char **in)
1239 9 : {
1240 : int i;
1241 9 : sdlContentModelPtr model = emalloc(sizeof(sdlContentModel));
1242 :
1243 9 : WSDL_CACHE_GET_1(model->kind, sdlContentKind, in);
1244 9 : WSDL_CACHE_GET_INT(model->min_occurs, in);
1245 9 : WSDL_CACHE_GET_INT(model->max_occurs, in);
1246 9 : switch (model->kind) {
1247 : case XSD_CONTENT_ELEMENT:
1248 6 : WSDL_CACHE_GET_INT(i, in);
1249 6 : model->u.element = elements[i];
1250 6 : break;
1251 : case XSD_CONTENT_SEQUENCE:
1252 : case XSD_CONTENT_ALL:
1253 : case XSD_CONTENT_CHOICE:
1254 3 : WSDL_CACHE_GET_INT(i, in);
1255 3 : model->u.content = emalloc(sizeof(HashTable));
1256 3 : zend_hash_init(model->u.content, i, NULL, delete_model, 0);
1257 12 : while (i > 0) {
1258 6 : sdlContentModelPtr x = sdl_deserialize_model(types, elements, in);
1259 6 : zend_hash_next_index_insert(model->u.content,&x,sizeof(sdlContentModelPtr),NULL);
1260 6 : i--;
1261 : }
1262 3 : break;
1263 : case XSD_CONTENT_GROUP_REF:
1264 0 : model->u.group_ref = sdl_deserialize_string(in);
1265 0 : break;
1266 : case XSD_CONTENT_GROUP:
1267 0 : WSDL_CACHE_GET_INT(i, in);
1268 0 : model->u.group = types[i];
1269 : break;
1270 : default:
1271 : break;
1272 : }
1273 9 : return model;
1274 : }
1275 :
1276 : static void sdl_deserialize_type(sdlTypePtr type, sdlTypePtr *types, encodePtr *encoders, char **in)
1277 9 : {
1278 : int i;
1279 9 : sdlTypePtr *elements = NULL;
1280 :
1281 9 : WSDL_CACHE_GET_1(type->kind, sdlTypeKind, in);
1282 9 : type->name = sdl_deserialize_string(in);
1283 9 : type->namens = sdl_deserialize_string(in);
1284 9 : type->def = sdl_deserialize_string(in);
1285 9 : type->fixed = sdl_deserialize_string(in);
1286 9 : type->ref = sdl_deserialize_string(in);
1287 9 : WSDL_CACHE_GET_1(type->nillable, char, in);
1288 9 : WSDL_CACHE_GET_1(type->form, sdlForm, in);
1289 :
1290 9 : WSDL_CACHE_GET_INT(i, in);
1291 9 : type->encode = encoders[i];
1292 :
1293 9 : if (**in == 1) {
1294 0 : WSDL_CACHE_SKIP(1, in);
1295 0 : type->restrictions = emalloc(sizeof(sdlRestrictions));
1296 : /*memset(type->restrictions, 0, sizeof(sdlRestrictions));*/
1297 0 : type->restrictions->minExclusive = sdl_deserialize_resriction_int(in);
1298 0 : type->restrictions->minInclusive = sdl_deserialize_resriction_int(in);
1299 0 : type->restrictions->maxExclusive = sdl_deserialize_resriction_int(in);
1300 0 : type->restrictions->maxInclusive = sdl_deserialize_resriction_int(in);
1301 0 : type->restrictions->totalDigits = sdl_deserialize_resriction_int(in);
1302 0 : type->restrictions->fractionDigits = sdl_deserialize_resriction_int(in);
1303 0 : type->restrictions->length = sdl_deserialize_resriction_int(in);
1304 0 : type->restrictions->minLength = sdl_deserialize_resriction_int(in);
1305 0 : type->restrictions->maxLength = sdl_deserialize_resriction_int(in);
1306 0 : type->restrictions->whiteSpace = sdl_deserialize_resriction_char(in);
1307 0 : type->restrictions->pattern = sdl_deserialize_resriction_char(in);
1308 0 : WSDL_CACHE_GET_INT(i, in);
1309 0 : if (i > 0) {
1310 0 : type->restrictions->enumeration = emalloc(sizeof(HashTable));
1311 0 : zend_hash_init(type->restrictions->enumeration, i, NULL, delete_restriction_var_char, 0);
1312 0 : while (i > 0) {
1313 0 : sdlRestrictionCharPtr x = sdl_deserialize_resriction_char(in);
1314 0 : sdl_deserialize_key(type->restrictions->enumeration, x, in);
1315 0 : --i;
1316 : }
1317 : } else {
1318 0 : type->restrictions->enumeration = NULL;
1319 : }
1320 : } else {
1321 9 : WSDL_CACHE_SKIP(1, in);
1322 : }
1323 :
1324 9 : WSDL_CACHE_GET_INT(i, in);
1325 9 : if (i > 0) {
1326 3 : elements = emalloc((i+1) * sizeof(sdlTypePtr));
1327 3 : elements[0] = NULL;
1328 3 : type->elements = emalloc(sizeof(HashTable));
1329 3 : zend_hash_init(type->elements, i, NULL, delete_type, 0);
1330 12 : while (i > 0) {
1331 6 : sdlTypePtr t = emalloc(sizeof(sdlType));
1332 6 : memset(t, 0, sizeof(sdlType));
1333 6 : sdl_deserialize_key(type->elements, t, in);
1334 6 : sdl_deserialize_type(t, types, encoders, in);
1335 6 : elements[i] = t;
1336 6 : --i;
1337 : }
1338 : }
1339 :
1340 9 : WSDL_CACHE_GET_INT(i, in);
1341 9 : if (i > 0) {
1342 0 : type->attributes = emalloc(sizeof(HashTable));
1343 0 : zend_hash_init(type->attributes, i, NULL, delete_attribute, 0);
1344 0 : while (i > 0) {
1345 0 : sdlAttributePtr attr = emalloc(sizeof(sdlAttribute));
1346 0 : memset(attr, 0, sizeof(sdlAttribute));
1347 0 : sdl_deserialize_key(type->attributes, attr, in);
1348 0 : sdl_deserialize_attribute(attr, encoders, in);
1349 0 : --i;
1350 : }
1351 : }
1352 :
1353 9 : if (**in != 0) {
1354 3 : WSDL_CACHE_SKIP(1, in);
1355 3 : type->model = sdl_deserialize_model(types, elements, in);
1356 : } else {
1357 6 : WSDL_CACHE_SKIP(1, in);
1358 : }
1359 9 : if (elements != NULL) {
1360 3 : efree(elements);
1361 : }
1362 9 : }
1363 :
1364 : static void sdl_deserialize_encoder(encodePtr enc, sdlTypePtr *types, char **in)
1365 4 : {
1366 : int i;
1367 :
1368 4 : WSDL_CACHE_GET_INT(enc->details.type, in);
1369 4 : enc->details.type_str = sdl_deserialize_string(in);
1370 4 : enc->details.ns = sdl_deserialize_string(in);
1371 4 : WSDL_CACHE_GET_INT(i, in);
1372 4 : enc->details.sdl_type = types[i];
1373 4 : enc->to_xml = sdl_guess_convert_xml;
1374 4 : enc->to_zval = sdl_guess_convert_zval;
1375 :
1376 4 : if (enc->details.sdl_type == NULL) {
1377 1 : int ns_len = strlen(enc->details.ns);
1378 1 : int type_len = strlen(enc->details.type_str);
1379 :
1380 1 : if (((ns_len == sizeof(SOAP_1_1_ENC_NAMESPACE)-1 &&
1381 : memcmp(enc->details.ns, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)-1) == 0) ||
1382 : (ns_len == sizeof(SOAP_1_2_ENC_NAMESPACE)-1 &&
1383 : memcmp(enc->details.ns, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)-1) == 0))) {
1384 : char *enc_nscat;
1385 : int enc_ns_len;
1386 : int enc_len;
1387 : encodePtr real_enc;
1388 :
1389 1 : enc_ns_len = sizeof(XSD_NAMESPACE)-1;
1390 1 : enc_len = enc_ns_len + type_len + 1;
1391 1 : enc_nscat = emalloc(enc_len + 1);
1392 1 : memcpy(enc_nscat, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)-1);
1393 1 : enc_nscat[enc_ns_len] = ':';
1394 1 : memcpy(enc_nscat+enc_ns_len+1, enc->details.type_str, type_len);
1395 1 : enc_nscat[enc_len] = '\0';
1396 :
1397 1 : real_enc = get_encoder_ex(NULL, enc_nscat, enc_len);
1398 1 : efree(enc_nscat);
1399 1 : if (real_enc) {
1400 1 : enc->to_zval = real_enc->to_zval;
1401 1 : enc->to_xml = real_enc->to_xml;
1402 : }
1403 : }
1404 : }
1405 4 : }
1406 :
1407 : static void sdl_deserialize_soap_body(sdlSoapBindingFunctionBodyPtr body, encodePtr *encoders, sdlTypePtr *types, char **in)
1408 6 : {
1409 : int i, j, n;
1410 :
1411 6 : WSDL_CACHE_GET_1(body->use, sdlEncodingUse, in);
1412 6 : if (body->use == SOAP_ENCODED) {
1413 4 : WSDL_CACHE_GET_1(body->encodingStyle, sdlRpcEncodingStyle, in);
1414 : } else {
1415 2 : body->encodingStyle = SOAP_ENCODING_DEFAULT;
1416 : }
1417 6 : body->ns = sdl_deserialize_string(in);
1418 6 : WSDL_CACHE_GET_INT(i, in);
1419 6 : if (i > 0) {
1420 0 : body->headers = emalloc(sizeof(HashTable));
1421 0 : zend_hash_init(body->headers, i, NULL, delete_header, 0);
1422 0 : while (i > 0) {
1423 0 : sdlSoapBindingFunctionHeaderPtr tmp = emalloc(sizeof(sdlSoapBindingFunctionHeader));
1424 0 : memset(tmp, 0, sizeof(sdlSoapBindingFunctionHeader));
1425 0 : sdl_deserialize_key(body->headers, tmp, in);
1426 0 : WSDL_CACHE_GET_1(tmp->use, sdlEncodingUse, in);
1427 0 : if (tmp->use == SOAP_ENCODED) {
1428 0 : WSDL_CACHE_GET_1(tmp->encodingStyle, sdlRpcEncodingStyle, in);
1429 : } else {
1430 0 : tmp->encodingStyle = SOAP_ENCODING_DEFAULT;
1431 : }
1432 0 : tmp->name = sdl_deserialize_string(in);
1433 0 : tmp->ns = sdl_deserialize_string(in);
1434 0 : WSDL_CACHE_GET_INT(n, in);
1435 0 : tmp->encode = encoders[n];
1436 0 : WSDL_CACHE_GET_INT(n, in);
1437 0 : tmp->element = types[n];
1438 0 : --i;
1439 0 : WSDL_CACHE_GET_INT(j, in);
1440 0 : if (j > 0) {
1441 0 : tmp->headerfaults = emalloc(sizeof(HashTable));
1442 0 : zend_hash_init(tmp->headerfaults, i, NULL, delete_header, 0);
1443 0 : while (j > 0) {
1444 0 : sdlSoapBindingFunctionHeaderPtr tmp2 = emalloc(sizeof(sdlSoapBindingFunctionHeader));
1445 0 : memset(tmp2, 0, sizeof(sdlSoapBindingFunctionHeader));
1446 0 : sdl_deserialize_key(tmp->headerfaults, tmp2, in);
1447 0 : WSDL_CACHE_GET_1(tmp2->use, sdlEncodingUse, in);
1448 0 : if (tmp2->use == SOAP_ENCODED) {
1449 0 : WSDL_CACHE_GET_1(tmp2->encodingStyle, sdlRpcEncodingStyle, in);
1450 : } else {
1451 0 : tmp2->encodingStyle = SOAP_ENCODING_DEFAULT;
1452 : }
1453 0 : tmp2->name = sdl_deserialize_string(in);
1454 0 : tmp2->ns = sdl_deserialize_string(in);
1455 0 : WSDL_CACHE_GET_INT(n, in);
1456 0 : tmp2->encode = encoders[n];
1457 0 : WSDL_CACHE_GET_INT(n, in);
1458 0 : tmp2->element = types[n];
1459 0 : --j;
1460 : }
1461 : }
1462 : }
1463 : }
1464 6 : }
1465 :
1466 : static HashTable* sdl_deserialize_parameters(encodePtr *encoders, sdlTypePtr *types, char **in)
1467 8 : {
1468 : int i, n;
1469 : HashTable *ht;
1470 :
1471 8 : WSDL_CACHE_GET_INT(i, in);
1472 8 : if (i == 0) {return NULL;}
1473 7 : ht = emalloc(sizeof(HashTable));
1474 7 : zend_hash_init(ht, i, NULL, delete_parameter, 0);
1475 21 : while (i > 0) {
1476 7 : sdlParamPtr param = emalloc(sizeof(sdlParam));
1477 7 : sdl_deserialize_key(ht, param, in);
1478 7 : param->paramName = sdl_deserialize_string(in);
1479 7 : WSDL_CACHE_GET_INT(param->order, in);
1480 7 : WSDL_CACHE_GET_INT(n, in);
1481 7 : param->encode = encoders[n];
1482 7 : WSDL_CACHE_GET_INT(n, in);
1483 7 : param->element = types[n];
1484 7 : --i;
1485 : }
1486 7 : return ht;
1487 : }
1488 :
1489 : static sdlPtr get_sdl_from_cache(const char *fn, const char *uri, time_t t, time_t *cached TSRMLS_DC)
1490 7 : {
1491 : sdlPtr sdl;
1492 : time_t old_t;
1493 : int i, num_groups, num_types, num_elements, num_encoders, num_bindings, num_func;
1494 7 : sdlFunctionPtr *functions = NULL;
1495 : sdlBindingPtr *bindings;
1496 : sdlTypePtr *types;
1497 : encodePtr *encoders;
1498 : encodePtr enc;
1499 :
1500 : int f;
1501 : struct stat st;
1502 : char *in, *buf;
1503 :
1504 7 : f = open(fn, O_RDONLY|O_BINARY);
1505 7 : if (f < 0) {
1506 1 : return NULL;
1507 : }
1508 6 : if (fstat(f, &st) != 0) {
1509 0 : close(f);
1510 0 : return NULL;
1511 : }
1512 6 : buf = in = emalloc(st.st_size);
1513 6 : if (read(f, in, st.st_size) != st.st_size) {
1514 0 : close(f);
1515 0 : efree(in);
1516 0 : return NULL;
1517 : }
1518 6 : close(f);
1519 :
1520 6 : if (strncmp(in,"wsdl",4) != 0 || in[4] != WSDL_CACHE_VERSION || in[5] != '\0') {
1521 0 : unlink(fn);
1522 0 : efree(buf);
1523 0 : return NULL;
1524 : }
1525 6 : in += 6;
1526 :
1527 6 : WSDL_CACHE_GET(old_t, time_t, &in);
1528 6 : if (old_t < t) {
1529 4 : unlink(fn);
1530 4 : efree(buf);
1531 4 : return NULL;
1532 : }
1533 2 : *cached = old_t;
1534 :
1535 2 : WSDL_CACHE_GET_INT(i, &in);
1536 2 : if (i == 0 && strncmp(in, uri, i) != 0) {
1537 0 : unlink(fn);
1538 0 : efree(buf);
1539 0 : return NULL;
1540 : }
1541 2 : WSDL_CACHE_SKIP(i, &in);
1542 :
1543 2 : sdl = emalloc(sizeof(*sdl));
1544 2 : memset(sdl, 0, sizeof(*sdl));
1545 :
1546 2 : sdl->source = sdl_deserialize_string(&in);
1547 2 : sdl->target_ns = sdl_deserialize_string(&in);
1548 :
1549 2 : WSDL_CACHE_GET_INT(num_groups, &in);
1550 2 : WSDL_CACHE_GET_INT(num_types, &in);
1551 2 : WSDL_CACHE_GET_INT(num_elements, &in);
1552 2 : WSDL_CACHE_GET_INT(num_encoders, &in);
1553 :
1554 2 : i = num_groups+num_types+num_elements;
1555 2 : types = emalloc((i+1)*sizeof(sdlTypePtr));
1556 2 : types[0] = NULL;
1557 7 : while (i > 0) {
1558 3 : types[i] = emalloc(sizeof(sdlType));
1559 3 : memset(types[i], 0, sizeof(sdlType));
1560 3 : i--;
1561 : }
1562 :
1563 2 : i = num_encoders;
1564 2 : enc = defaultEncoding;
1565 156 : while (enc->details.type != END_KNOWN_TYPES) {
1566 152 : i++; enc++;
1567 : }
1568 2 : encoders = emalloc((i+1)*sizeof(encodePtr));
1569 2 : i = num_encoders;
1570 2 : encoders[0] = NULL;
1571 8 : while (i > 0) {
1572 4 : encoders[i] = emalloc(sizeof(encode));
1573 4 : memset(encoders[i], 0, sizeof(encode));
1574 4 : i--;
1575 : }
1576 2 : i = num_encoders;
1577 2 : enc = defaultEncoding;
1578 156 : while (enc->details.type != END_KNOWN_TYPES) {
1579 152 : encoders[++i] = enc++;
1580 : }
1581 :
1582 2 : i = 1;
1583 2 : if (num_groups > 0) {
1584 0 : sdl->groups = emalloc(sizeof(HashTable));
1585 0 : zend_hash_init(sdl->groups, num_groups, NULL, delete_type, 0);
1586 0 : while (i < num_groups+1) {
1587 0 : sdl_deserialize_key(sdl->groups, types[i], &in);
1588 0 : sdl_deserialize_type(types[i], types, encoders, &in);
1589 0 : i++;
1590 : }
1591 : }
1592 :
1593 2 : if (num_types > 0) {
1594 2 : sdl->types = emalloc(sizeof(HashTable));
1595 2 : zend_hash_init(sdl->types, num_types, NULL, delete_type, 0);
1596 7 : while (i < num_groups+num_types+1) {
1597 3 : sdl_deserialize_key(sdl->types, types[i], &in);
1598 3 : sdl_deserialize_type(types[i], types, encoders, &in);
1599 3 : i++;
1600 : }
1601 : }
1602 :
1603 2 : if (num_elements > 0) {
1604 0 : sdl->elements = emalloc(sizeof(HashTable));
1605 0 : zend_hash_init(sdl->elements, num_elements, NULL, delete_type, 0);
1606 0 : while (i < num_groups+num_types+num_elements+1) {
1607 0 : sdl_deserialize_key(sdl->elements, types[i], &in);
1608 0 : sdl_deserialize_type(types[i], types, encoders, &in);
1609 0 : i++;
1610 : }
1611 : }
1612 :
1613 2 : i = 1;
1614 2 : if (num_encoders > 0) {
1615 2 : sdl->encoders = emalloc(sizeof(HashTable));
1616 2 : zend_hash_init(sdl->encoders, num_encoders, NULL, delete_encoder, 0);
1617 8 : while (i < num_encoders+1) {
1618 4 : sdl_deserialize_key(sdl->encoders, encoders[i], &in);
1619 4 : sdl_deserialize_encoder(encoders[i], types, &in);
1620 4 : i++;
1621 : }
1622 : }
1623 :
1624 : /* deserialize bindings */
1625 2 : WSDL_CACHE_GET_INT(num_bindings, &in);
1626 2 : bindings = emalloc(num_bindings*sizeof(sdlBindingPtr));
1627 2 : if (num_bindings > 0) {
1628 2 : sdl->bindings = emalloc(sizeof(HashTable));
1629 2 : zend_hash_init(sdl->bindings, num_bindings, NULL, delete_binding, 0);
1630 4 : for (i = 0; i < num_bindings; i++) {
1631 2 : sdlBindingPtr binding = emalloc(sizeof(sdlBinding));
1632 2 : memset(binding, 0, sizeof(sdlBinding));
1633 2 : sdl_deserialize_key(sdl->bindings, binding, &in);
1634 2 : binding->name = sdl_deserialize_string(&in);
1635 2 : binding->location = sdl_deserialize_string(&in);
1636 2 : WSDL_CACHE_GET_1(binding->bindingType,sdlBindingType,&in);
1637 4 : if (binding->bindingType == BINDING_SOAP && *in != 0) {
1638 2 : sdlSoapBindingPtr soap_binding = binding->bindingAttributes = emalloc(sizeof(sdlSoapBinding));
1639 2 : WSDL_CACHE_GET_1(soap_binding->style,sdlEncodingStyle,&in);
1640 2 : WSDL_CACHE_GET_1(soap_binding->transport,sdlTransport,&in);
1641 : } else {
1642 0 : WSDL_CACHE_SKIP(1,&in);
1643 : }
1644 2 : bindings[i] = binding;
1645 : }
1646 : }
1647 :
1648 : /* deserialize functions */
1649 2 : WSDL_CACHE_GET_INT(num_func, &in);
1650 2 : zend_hash_init(&sdl->functions, num_func, NULL, delete_function, 0);
1651 2 : if (num_func > 0) {
1652 2 : functions = emalloc(num_func*sizeof(sdlFunctionPtr));
1653 5 : for (i = 0; i < num_func; i++) {
1654 : int binding_num, num_faults;
1655 3 : sdlFunctionPtr func = emalloc(sizeof(sdlFunction));
1656 3 : sdl_deserialize_key(&sdl->functions, func, &in);
1657 3 : func->functionName = sdl_deserialize_string(&in);
1658 3 : func->requestName = sdl_deserialize_string(&in);
1659 3 : func->responseName = sdl_deserialize_string(&in);
1660 :
1661 3 : WSDL_CACHE_GET_INT(binding_num, &in);
1662 3 : if (binding_num == 0) {
1663 0 : func->binding = NULL;
1664 : } else {
1665 3 : func->binding = bindings[binding_num-1];
1666 : }
1667 6 : if (func->binding && func->binding->bindingType == BINDING_SOAP && *in != 0) {
1668 3 : sdlSoapBindingFunctionPtr binding = func->bindingAttributes = emalloc(sizeof(sdlSoapBindingFunction));
1669 3 : memset(binding, 0, sizeof(sdlSoapBindingFunction));
1670 3 : WSDL_CACHE_GET_1(binding->style,sdlEncodingStyle,&in);
1671 3 : binding->soapAction = sdl_deserialize_string(&in);
1672 3 : sdl_deserialize_soap_body(&binding->input, encoders, types, &in);
1673 3 : sdl_deserialize_soap_body(&binding->output, encoders, types, &in);
1674 : } else {
1675 0 : WSDL_CACHE_SKIP(1, &in);
1676 0 : func->bindingAttributes = NULL;
1677 : }
1678 :
1679 3 : func->requestParameters = sdl_deserialize_parameters(encoders, types, &in);
1680 3 : func->responseParameters = sdl_deserialize_parameters(encoders, types, &in);
1681 :
1682 3 : WSDL_CACHE_GET_INT(num_faults, &in);
1683 3 : if (num_faults > 0) {
1684 : int j;
1685 :
1686 2 : func->faults = emalloc(sizeof(HashTable));
1687 2 : zend_hash_init(func->faults, num_faults, NULL, delete_fault, 0);
1688 :
1689 4 : for (j = 0; j < num_faults; j++) {
1690 2 : sdlFaultPtr fault = emalloc(sizeof(sdlFault));
1691 :
1692 2 : sdl_deserialize_key(func->faults, fault, &in);
1693 2 : fault->name =sdl_deserialize_string(&in);
1694 2 : fault->details =sdl_deserialize_parameters(encoders, types, &in);
1695 2 : if (*in != 0) {
1696 2 : sdlSoapBindingFunctionFaultPtr binding = fault->bindingAttributes = emalloc(sizeof(sdlSoapBindingFunctionFault));
1697 2 : memset(binding, 0, sizeof(sdlSoapBindingFunctionFault));
1698 2 : WSDL_CACHE_GET_1(binding->use,sdlEncodingUse,&in);
1699 2 : if (binding->use == SOAP_ENCODED) {
1700 2 : WSDL_CACHE_GET_1(binding->encodingStyle, sdlRpcEncodingStyle, &in);
1701 : } else {
1702 0 : binding->encodingStyle = SOAP_ENCODING_DEFAULT;
1703 : }
1704 2 : binding->ns = sdl_deserialize_string(&in);
1705 : } else {
1706 0 : WSDL_CACHE_SKIP(1, &in);
1707 0 : fault->bindingAttributes = NULL;
1708 : }
1709 : }
1710 : } else {
1711 1 : func->faults = NULL;
1712 : }
1713 3 : functions[i] = func;
1714 : }
1715 : }
1716 :
1717 : /* deserialize requests */
1718 2 : WSDL_CACHE_GET_INT(i, &in);
1719 2 : if (i > 0) {
1720 0 : sdl->requests = emalloc(sizeof(HashTable));
1721 0 : zend_hash_init(sdl->requests, i, NULL, NULL, 0);
1722 0 : while (i > 0) {
1723 : int function_num;
1724 :
1725 0 : WSDL_CACHE_GET_INT(function_num, &in);
1726 0 : sdl_deserialize_key(sdl->requests, functions[function_num-1], &in);
1727 0 : i--;
1728 : }
1729 : }
1730 :
1731 2 : if (functions) {
1732 2 : efree(functions);
1733 : }
1734 2 : efree(bindings);
1735 2 : efree(encoders);
1736 2 : efree(types);
1737 2 : efree(buf);
1738 2 : return sdl;
1739 : }
1740 :
1741 : static void sdl_serialize_string(const char *str, smart_str *out)
1742 734 : {
1743 : int i;
1744 :
1745 734 : if (str) {
1746 403 : i = strlen(str);
1747 403 : WSDL_CACHE_PUT_INT(i, out);
1748 403 : if (i > 0) {
1749 400 : WSDL_CACHE_PUT_N(str, i, out);
1750 : }
1751 : } else {
1752 331 : WSDL_CACHE_PUT_INT(0x7fffffff, out);
1753 : }
1754 734 : }
1755 :
1756 : static void sdl_serialize_key(HashTable *ht, smart_str *out)
1757 206 : {
1758 : zstr key;
1759 : uint key_len;
1760 : ulong index;
1761 :
1762 206 : if (zend_hash_get_current_key_ex(ht, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
1763 144 : WSDL_CACHE_PUT_INT(key_len, out);
1764 144 : WSDL_CACHE_PUT_N(key.s, key_len, out);
1765 : } else {
1766 62 : WSDL_CACHE_PUT_INT(0, out);
1767 : }
1768 206 : }
1769 :
1770 130 : static void sdl_serialize_encoder_ref(encodePtr enc, HashTable *tmp_encoders, smart_str *out) {
1771 130 : if (enc) {
1772 : int *encoder_num;
1773 99 : if (zend_hash_find(tmp_encoders, (char*)&enc, sizeof(enc), (void**)&encoder_num) == SUCCESS) {
1774 99 : WSDL_CACHE_PUT_INT(*encoder_num, out);
1775 : } else {
1776 0 : WSDL_CACHE_PUT_INT(0, out);
1777 : }
1778 : } else {
1779 31 : WSDL_CACHE_PUT_INT(0, out);
1780 : }
1781 130 : }
1782 :
1783 106 : static void sdl_serialize_type_ref(sdlTypePtr type, HashTable *tmp_types, smart_str *out) {
1784 106 : if (type) {
1785 : int *type_num;
1786 94 : if (zend_hash_find(tmp_types, (char*)&type, sizeof(type), (void**)&type_num) == SUCCESS) {
1787 94 : WSDL_CACHE_PUT_INT(*type_num, out);
1788 : } else {
1789 0 : WSDL_CACHE_PUT_INT(0, out);
1790 : }
1791 : } else {
1792 12 : WSDL_CACHE_PUT_INT(0,out);
1793 : }
1794 106 : }
1795 :
1796 : static void sdl_serialize_attribute(sdlAttributePtr attr, HashTable *tmp_encoders, smart_str *out)
1797 16 : {
1798 : int i;
1799 :
1800 16 : sdl_serialize_string(attr->name, out);
1801 16 : sdl_serialize_string(attr->namens, out);
1802 16 : sdl_serialize_string(attr->ref, out);
1803 16 : sdl_serialize_string(attr->def, out);
1804 16 : sdl_serialize_string(attr->fixed, out);
1805 16 : WSDL_CACHE_PUT_1(attr->form, out);
1806 16 : WSDL_CACHE_PUT_1(attr->use, out);
1807 16 : sdl_serialize_encoder_ref(attr->encode, tmp_encoders, out);
1808 16 : if (attr->extraAttributes) {
1809 2 : i = zend_hash_num_elements(attr->extraAttributes);
1810 : } else {
1811 14 : i = 0;
1812 : }
1813 16 : WSDL_CACHE_PUT_INT(i, out);
1814 16 : if (i > 0) {
1815 : sdlExtraAttributePtr *tmp;
1816 2 : zend_hash_internal_pointer_reset(attr->extraAttributes);
1817 6 : while (zend_hash_get_current_data(attr->extraAttributes, (void**)&tmp) == SUCCESS) {
1818 2 : sdl_serialize_key(attr->extraAttributes, out);
1819 2 : sdl_serialize_string((*tmp)->ns, out);
1820 2 : sdl_serialize_string((*tmp)->val, out);
1821 2 : zend_hash_move_forward(attr->extraAttributes);
1822 : }
1823 : }
1824 16 : }
1825 :
1826 : static void sdl_serialize_model(sdlContentModelPtr model, HashTable *tmp_types, HashTable *tmp_elements, smart_str *out)
1827 71 : {
1828 71 : WSDL_CACHE_PUT_1(model->kind, out);
1829 71 : WSDL_CACHE_PUT_INT(model->min_occurs, out);
1830 71 : WSDL_CACHE_PUT_INT(model->max_occurs, out);
1831 71 : switch (model->kind) {
1832 : case XSD_CONTENT_ELEMENT:
1833 47 : sdl_serialize_type_ref(model->u.element, tmp_elements, out);
1834 47 : break;
1835 : case XSD_CONTENT_SEQUENCE:
1836 : case XSD_CONTENT_ALL:
1837 : case XSD_CONTENT_CHOICE: {
1838 : sdlContentModelPtr *tmp;
1839 24 : int i = zend_hash_num_elements(model->u.content);
1840 :
1841 24 : WSDL_CACHE_PUT_INT(i, out);
1842 24 : zend_hash_internal_pointer_reset(model->u.content);
1843 95 : while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
1844 47 : sdl_serialize_model(*tmp, tmp_types, tmp_elements, out);
1845 47 : zend_hash_move_forward(model->u.content);
1846 : }
1847 : }
1848 24 : break;
1849 : case XSD_CONTENT_GROUP_REF:
1850 0 : sdl_serialize_string(model->u.group_ref,out);
1851 0 : break;
1852 : case XSD_CONTENT_GROUP:
1853 0 : sdl_serialize_type_ref(model->u.group, tmp_types, out);
1854 : break;
1855 : default:
1856 : break;
1857 : }
1858 71 : }
1859 :
1860 : static void sdl_serialize_resriction_int(sdlRestrictionIntPtr x, smart_str *out)
1861 36 : {
1862 36 : if (x) {
1863 0 : WSDL_CACHE_PUT_1(1, out);
1864 0 : WSDL_CACHE_PUT_INT(x->value, out);
1865 0 : WSDL_CACHE_PUT_1(x->fixed, out);
1866 : } else {
1867 36 : WSDL_CACHE_PUT_1(0, out);
1868 : }
1869 36 : }
1870 :
1871 : static void sdl_serialize_resriction_char(sdlRestrictionCharPtr x, smart_str *out)
1872 32 : {
1873 32 : if (x) {
1874 24 : WSDL_CACHE_PUT_1(1, out);
1875 24 : sdl_serialize_string(x->value, out);
1876 24 : WSDL_CACHE_PUT_1(x->fixed, out);
1877 : } else {
1878 8 : WSDL_CACHE_PUT_1(0, out);
1879 : }
1880 32 : }
1881 :
1882 : static void sdl_serialize_type(sdlTypePtr type, HashTable *tmp_encoders, HashTable *tmp_types, smart_str *out)
1883 91 : {
1884 : int i;
1885 91 : HashTable *tmp_elements = NULL;
1886 :
1887 91 : WSDL_CACHE_PUT_1(type->kind, out);
1888 91 : sdl_serialize_string(type->name, out);
1889 91 : sdl_serialize_string(type->namens, out);
1890 91 : sdl_serialize_string(type->def, out);
1891 91 : sdl_serialize_string(type->fixed, out);
1892 91 : sdl_serialize_string(type->ref, out);
1893 91 : WSDL_CACHE_PUT_1(type->nillable, out);
1894 91 : WSDL_CACHE_PUT_1(type->form, out);
1895 91 : sdl_serialize_encoder_ref(type->encode, tmp_encoders, out);
1896 :
1897 91 : if (type->restrictions) {
1898 4 : WSDL_CACHE_PUT_1(1, out);
1899 4 : sdl_serialize_resriction_int(type->restrictions->minExclusive,out);
1900 4 : sdl_serialize_resriction_int(type->restrictions->minInclusive,out);
1901 4 : sdl_serialize_resriction_int(type->restrictions->maxExclusive,out);
1902 4 : sdl_serialize_resriction_int(type->restrictions->maxInclusive,out);
1903 4 : sdl_serialize_resriction_int(type->restrictions->totalDigits,out);
1904 4 : sdl_serialize_resriction_int(type->restrictions->fractionDigits,out);
1905 4 : sdl_serialize_resriction_int(type->restrictions->length,out);
1906 4 : sdl_serialize_resriction_int(type->restrictions->minLength,out);
1907 4 : sdl_serialize_resriction_int(type->restrictions->maxLength,out);
1908 4 : sdl_serialize_resriction_char(type->restrictions->whiteSpace,out);
1909 4 : sdl_serialize_resriction_char(type->restrictions->pattern,out);
1910 4 : if (type->restrictions->enumeration) {
1911 4 : i = zend_hash_num_elements(type->restrictions->enumeration);
1912 : } else {
1913 0 : i = 0;
1914 : }
1915 4 : WSDL_CACHE_PUT_INT(i, out);
1916 4 : if (i > 0) {
1917 : sdlRestrictionCharPtr *tmp;
1918 :
1919 4 : zend_hash_internal_pointer_reset(type->restrictions->enumeration);
1920 32 : while (zend_hash_get_current_data(type->restrictions->enumeration, (void**)&tmp) == SUCCESS) {
1921 24 : sdl_serialize_resriction_char(*tmp, out);
1922 24 : sdl_serialize_key(type->restrictions->enumeration, out);
1923 24 : zend_hash_move_forward(type->restrictions->enumeration);
1924 : }
1925 : }
1926 : } else {
1927 87 : WSDL_CACHE_PUT_1(0, out);
1928 : }
1929 91 : if (type->elements) {
1930 24 : i = zend_hash_num_elements(type->elements);
1931 : } else {
1932 67 : i = 0;
1933 : }
1934 91 : WSDL_CACHE_PUT_INT(i, out);
1935 91 : if (i > 0) {
1936 : sdlTypePtr *tmp;
1937 :
1938 24 : tmp_elements = emalloc(sizeof(HashTable));
1939 24 : zend_hash_init(tmp_elements, i, NULL, NULL, 0);
1940 :
1941 24 : zend_hash_internal_pointer_reset(type->elements);
1942 95 : while (zend_hash_get_current_data(type->elements, (void**)&tmp) == SUCCESS) {
1943 47 : sdl_serialize_key(type->elements, out);
1944 47 : sdl_serialize_type(*tmp, tmp_encoders, tmp_types, out);
1945 47 : zend_hash_add(tmp_elements, (char*)tmp, sizeof(*tmp), &i, sizeof(int), NULL);
1946 47 : i--;
1947 47 : zend_hash_move_forward(type->elements);
1948 : }
1949 : }
1950 :
1951 91 : if (type->attributes) {
1952 9 : i = zend_hash_num_elements(type->attributes);
1953 : } else {
1954 82 : i = 0;
1955 : }
1956 91 : WSDL_CACHE_PUT_INT(i, out);
1957 91 : if (i > 0) {
1958 : sdlAttributePtr *tmp;
1959 9 : zend_hash_internal_pointer_reset(type->attributes);
1960 34 : while (zend_hash_get_current_data(type->attributes, (void**)&tmp) == SUCCESS) {
1961 16 : sdl_serialize_key(type->attributes, out);
1962 16 : sdl_serialize_attribute(*tmp, tmp_encoders, out);
1963 16 : zend_hash_move_forward(type->attributes);
1964 : }
1965 : }
1966 91 : if (type->model) {
1967 24 : WSDL_CACHE_PUT_1(1, out);
1968 24 : sdl_serialize_model(type->model, tmp_types, tmp_elements, out);
1969 : } else {
1970 67 : WSDL_CACHE_PUT_1(0, out);
1971 : }
1972 91 : if (tmp_elements != NULL) {
1973 24 : zend_hash_destroy(tmp_elements);
1974 24 : efree(tmp_elements);
1975 : }
1976 91 : }
1977 :
1978 : static void sdl_serialize_encoder(encodePtr enc, HashTable *tmp_types, smart_str *out)
1979 36 : {
1980 36 : WSDL_CACHE_PUT_INT(enc->details.type, out);
1981 36 : sdl_serialize_string(enc->details.type_str, out);
1982 36 : sdl_serialize_string(enc->details.ns, out);
1983 36 : sdl_serialize_type_ref(enc->details.sdl_type, tmp_types, out);
1984 36 : }
1985 :
1986 : static void sdl_serialize_parameters(HashTable *ht, HashTable *tmp_encoders, HashTable *tmp_types, smart_str *out)
1987 18 : {
1988 : int i;
1989 :
1990 18 : if (ht) {
1991 18 : i = zend_hash_num_elements(ht);
1992 : } else {
1993 0 : i = 0;
1994 : }
1995 18 : WSDL_CACHE_PUT_INT(i, out);
1996 18 : if (i > 0) {
1997 : sdlParamPtr *tmp;
1998 :
1999 17 : zend_hash_internal_pointer_reset(ht);
2000 53 : while (zend_hash_get_current_data(ht, (void**)&tmp) == SUCCESS) {
2001 19 : sdl_serialize_key(ht, out);
2002 19 : sdl_serialize_string((*tmp)->paramName, out);
2003 19 : WSDL_CACHE_PUT_INT((*tmp)->order, out);
2004 19 : sdl_serialize_encoder_ref((*tmp)->encode, tmp_encoders, out);
2005 19 : sdl_serialize_type_ref((*tmp)->element, tmp_types, out);
2006 19 : zend_hash_move_forward(ht);
2007 : }
2008 : }
2009 18 : }
2010 :
2011 : static void sdl_serialize_soap_body(sdlSoapBindingFunctionBodyPtr body, HashTable *tmp_encoders, HashTable *tmp_types, smart_str *out)
2012 16 : {
2013 : int i, j;
2014 :
2015 16 : WSDL_CACHE_PUT_1(body->use, out);
2016 16 : if (body->use == SOAP_ENCODED) {
2017 6 : WSDL_CACHE_PUT_1(body->encodingStyle, out);
2018 : }
2019 16 : sdl_serialize_string(body->ns, out);
2020 16 : if (body->headers) {
2021 4 : i = zend_hash_num_elements(body->headers);
2022 : } else {
2023 12 : i = 0;
2024 : }
2025 16 : WSDL_CACHE_PUT_INT(i, out);
2026 16 : if (i > 0) {
2027 : sdlSoapBindingFunctionHeaderPtr *tmp;
2028 4 : zend_hash_internal_pointer_reset(body->headers);
2029 12 : while (zend_hash_get_current_data(body->headers, (void**)&tmp) == SUCCESS) {
2030 4 : sdl_serialize_key(body->headers, out);
2031 4 : WSDL_CACHE_PUT_1((*tmp)->use, out);
2032 4 : if ((*tmp)->use == SOAP_ENCODED) {
2033 0 : WSDL_CACHE_PUT_1((*tmp)->encodingStyle, out);
2034 : }
2035 4 : sdl_serialize_string((*tmp)->name, out);
2036 4 : sdl_serialize_string((*tmp)->ns, out);
2037 4 : sdl_serialize_encoder_ref((*tmp)->encode, tmp_encoders, out);
2038 4 : sdl_serialize_type_ref((*tmp)->element, tmp_types, out);
2039 4 : if ((*tmp)->headerfaults) {
2040 0 : j = zend_hash_num_elements((*tmp)->headerfaults);
2041 : } else {
2042 4 : j = 0;
2043 : }
2044 4 : WSDL_CACHE_PUT_INT(j, out);
2045 4 : if (j > 0) {
2046 : sdlSoapBindingFunctionHeaderPtr *tmp2;
2047 0 : zend_hash_internal_pointer_reset((*tmp)->headerfaults);
2048 0 : while (zend_hash_get_current_data((*tmp)->headerfaults, (void**)&tmp2) == SUCCESS) {
2049 0 : sdl_serialize_key((*tmp)->headerfaults, out);
2050 0 : WSDL_CACHE_PUT_1((*tmp2)->use, out);
2051 0 : if ((*tmp2)->use == SOAP_ENCODED) {
2052 0 : WSDL_CACHE_PUT_1((*tmp2)->encodingStyle, out);
2053 : }
2054 0 : sdl_serialize_string((*tmp2)->name, out);
2055 0 : sdl_serialize_string((*tmp2)->ns, out);
2056 0 : sdl_serialize_encoder_ref((*tmp2)->encode, tmp_encoders, out);
2057 0 : sdl_serialize_type_ref((*tmp2)->element, tmp_types, out);
2058 0 : zend_hash_move_forward((*tmp)->headerfaults);
2059 : }
2060 : }
2061 4 : zend_hash_move_forward(body->headers);
2062 : }
2063 : }
2064 16 : }
2065 :
2066 : static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr sdl TSRMLS_DC)
2067 4 : {
2068 4 : smart_str buf = {0};
2069 4 : smart_str *out = &buf;
2070 : int i;
2071 4 : int type_num = 1;
2072 4 : int encoder_num = 1;
2073 : int f;
2074 : encodePtr enc;
2075 : HashTable tmp_types;
2076 : HashTable tmp_encoders;
2077 : HashTable tmp_bindings;
2078 : HashTable tmp_functions;
2079 :
2080 : #ifdef ZEND_WIN32
2081 : f = open(fn,O_CREAT|O_WRONLY|O_EXCL|O_BINARY,S_IREAD|S_IWRITE);
2082 : #else
2083 4 : f = open(fn,O_CREAT|O_WRONLY|O_EXCL|O_BINARY,S_IREAD|S_IWRITE);
2084 : #endif
2085 4 : if (f < 0) {return;}
2086 :
2087 4 : zend_hash_init(&tmp_types, 0, NULL, NULL, 0);
2088 4 : zend_hash_init(&tmp_encoders, 0, NULL, NULL, 0);
2089 4 : zend_hash_init(&tmp_bindings, 0, NULL, NULL, 0);
2090 4 : zend_hash_init(&tmp_functions, 0, NULL, NULL, 0);
2091 :
2092 4 : WSDL_CACHE_PUT_N("wsdl", 4, out);
2093 4 : WSDL_CACHE_PUT_1(WSDL_CACHE_VERSION,out);
2094 4 : WSDL_CACHE_PUT_1(0,out);
2095 4 : WSDL_CACHE_PUT_N(&t, sizeof(t), out);
2096 :
2097 4 : sdl_serialize_string(uri, out);
2098 4 : sdl_serialize_string(sdl->source, out);
2099 4 : sdl_serialize_string(sdl->target_ns, out);
2100 :
2101 4 : if (sdl->groups) {
2102 0 : i = zend_hash_num_elements(sdl->groups);
2103 : } else {
2104 4 : i = 0;
2105 : }
2106 4 : WSDL_CACHE_PUT_INT(i, out);
2107 4 : if (i > 0) {
2108 : sdlTypePtr *tmp;
2109 :
2110 0 : zend_hash_internal_pointer_reset(sdl->groups);
2111 0 : while (zend_hash_get_current_data(sdl->groups, (void**)&tmp) == SUCCESS) {
2112 0 : zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL);
2113 0 : ++type_num;
2114 0 : zend_hash_move_forward(sdl->groups);
2115 : }
2116 : }
2117 :
2118 4 : if (sdl->types) {
2119 4 : i = zend_hash_num_elements(sdl->types);
2120 : } else {
2121 0 : i = 0;
2122 : }
2123 4 : WSDL_CACHE_PUT_INT(i, out);
2124 4 : if (i > 0) {
2125 : sdlTypePtr *tmp;
2126 :
2127 4 : zend_hash_internal_pointer_reset(sdl->types);
2128 43 : while (zend_hash_get_current_data(sdl->types, (void**)&tmp) == SUCCESS) {
2129 35 : zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL);
2130 35 : ++type_num;
2131 35 : zend_hash_move_forward(sdl->types);
2132 : }
2133 : }
2134 :
2135 4 : if (sdl->elements) {
2136 1 : i = zend_hash_num_elements(sdl->elements);
2137 : } else {
2138 3 : i = 0;
2139 : }
2140 4 : WSDL_CACHE_PUT_INT(i, out);
2141 4 : if (i > 0) {
2142 : sdlTypePtr *tmp;
2143 :
2144 1 : zend_hash_internal_pointer_reset(sdl->elements);
2145 11 : while (zend_hash_get_current_data(sdl->elements, (void**)&tmp) == SUCCESS) {
2146 9 : zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL);
2147 9 : ++type_num;
2148 9 : zend_hash_move_forward(sdl->elements);
2149 : }
2150 : }
2151 :
2152 4 : if (sdl->encoders) {
2153 4 : i = zend_hash_num_elements(sdl->encoders);
2154 : } else {
2155 0 : i = 0;
2156 : }
2157 4 : WSDL_CACHE_PUT_INT(i, out);
2158 4 : if (i > 0) {
2159 : encodePtr *tmp;
2160 :
2161 4 : zend_hash_internal_pointer_reset(sdl->encoders);
2162 44 : while (zend_hash_get_current_data(sdl->encoders, (void**)&tmp) == SUCCESS) {
2163 36 : zend_hash_add(&tmp_encoders, (char*)tmp, sizeof(*tmp), (void**)&encoder_num, sizeof(encoder_num), NULL);
2164 36 : ++encoder_num;
2165 36 : zend_hash_move_forward(sdl->encoders);
2166 : }
2167 : }
2168 4 : enc = defaultEncoding;
2169 312 : while (enc->details.type != END_KNOWN_TYPES) {
2170 304 : zend_hash_add(&tmp_encoders, (char*)&enc, sizeof(encodePtr), (void**)&encoder_num, sizeof(encoder_num), NULL);
2171 304 : enc++;
2172 304 : ++encoder_num;
2173 : }
2174 :
2175 4 : if (sdl->groups) {
2176 : sdlTypePtr *tmp;
2177 0 : zend_hash_internal_pointer_reset(sdl->groups);
2178 0 : while (zend_hash_get_current_data(sdl->groups, (void**)&tmp) == SUCCESS) {
2179 0 : sdl_serialize_key(sdl->groups, out);
2180 0 : sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out);
2181 0 : zend_hash_move_forward(sdl->groups);
2182 : }
2183 : }
2184 :
2185 4 : if (sdl->types) {
2186 : sdlTypePtr *tmp;
2187 4 : zend_hash_internal_pointer_reset(sdl->types);
2188 43 : while (zend_hash_get_current_data(sdl->types, (void**)&tmp) == SUCCESS) {
2189 35 : sdl_serialize_key(sdl->types, out);
2190 35 : sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out);
2191 35 : zend_hash_move_forward(sdl->types);
2192 : }
2193 : }
2194 :
2195 4 : if (sdl->elements) {
2196 : sdlTypePtr *tmp;
2197 1 : zend_hash_internal_pointer_reset(sdl->elements);
2198 11 : while (zend_hash_get_current_data(sdl->elements, (void**)&tmp) == SUCCESS) {
2199 9 : sdl_serialize_key(sdl->elements, out);
2200 9 : sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out);
2201 9 : zend_hash_move_forward(sdl->elements);
2202 : }
2203 : }
2204 :
2205 4 : if (sdl->encoders) {
2206 : encodePtr *tmp;
2207 4 : zend_hash_internal_pointer_reset(sdl->encoders);
2208 44 : while (zend_hash_get_current_data(sdl->encoders, (void**)&tmp) == SUCCESS) {
2209 36 : sdl_serialize_key(sdl->encoders, out);
2210 36 : sdl_serialize_encoder(*tmp, &tmp_types, out);
2211 36 : zend_hash_move_forward(sdl->encoders);
2212 : }
2213 : }
2214 :
2215 : /* serialize bindings */
2216 4 : if (sdl->bindings) {
2217 4 : i = zend_hash_num_elements(sdl->bindings);
2218 : } else {
2219 0 : i = 0;
2220 : }
2221 4 : WSDL_CACHE_PUT_INT(i, out);
2222 4 : if (i > 0) {
2223 : sdlBindingPtr *tmp;
2224 4 : int binding_num = 1;
2225 :
2226 4 : zend_hash_internal_pointer_reset(sdl->bindings);
2227 12 : while (zend_hash_get_current_data(sdl->bindings, (void**)&tmp) == SUCCESS) {
2228 4 : sdl_serialize_key(sdl->bindings, out);
2229 4 : sdl_serialize_string((*tmp)->name, out);
2230 4 : sdl_serialize_string((*tmp)->location, out);
2231 4 : WSDL_CACHE_PUT_1((*tmp)->bindingType,out);
2232 8 : if ((*tmp)->bindingType == BINDING_SOAP && (*tmp)->bindingAttributes != NULL) {
2233 4 : sdlSoapBindingPtr binding = (sdlSoapBindingPtr)(*tmp)->bindingAttributes;
2234 4 : WSDL_CACHE_PUT_1(binding->style, out);
2235 4 : WSDL_CACHE_PUT_1(binding->transport, out);
2236 : } else {
2237 0 : WSDL_CACHE_PUT_1(0,out);
2238 : }
2239 :
2240 4 : zend_hash_add(&tmp_bindings, (char*)tmp, sizeof(*tmp), (void**)&binding_num, sizeof(binding_num), NULL);
2241 4 : binding_num++;
2242 4 : zend_hash_move_forward(sdl->bindings);
2243 : }
2244 : }
2245 :
2246 : /* serialize functions */
2247 4 : i = zend_hash_num_elements(&sdl->functions);
2248 4 : WSDL_CACHE_PUT_INT(i, out);
2249 4 : if (i > 0) {
2250 : sdlFunctionPtr *tmp;
2251 : int *binding_num;
2252 4 : int function_num = 1;
2253 :
2254 4 : zend_hash_internal_pointer_reset(&sdl->functions);
2255 16 : while (zend_hash_get_current_data(&sdl->functions, (void**)&tmp) == SUCCESS) {
2256 8 : sdl_serialize_key(&sdl->functions, out);
2257 8 : sdl_serialize_string((*tmp)->functionName, out);
2258 8 : sdl_serialize_string((*tmp)->requestName, out);
2259 8 : sdl_serialize_string((*tmp)->responseName, out);
2260 :
2261 8 : if ((*tmp)->binding == NULL ||
2262 : zend_hash_find(&tmp_bindings,(char*)&(*tmp)->binding,sizeof((*tmp)->binding), (void**)&binding_num) != SUCCESS) {
2263 : }
2264 8 : WSDL_CACHE_PUT_INT(*binding_num, out);
2265 8 : if (*binding_num >= 0) {
2266 16 : if ((*tmp)->binding->bindingType == BINDING_SOAP && (*tmp)->bindingAttributes != NULL) {
2267 8 : sdlSoapBindingFunctionPtr binding = (sdlSoapBindingFunctionPtr)(*tmp)->bindingAttributes;
2268 8 : WSDL_CACHE_PUT_1(binding->style, out);
2269 8 : sdl_serialize_string(binding->soapAction, out);
2270 8 : sdl_serialize_soap_body(&binding->input, &tmp_encoders, &tmp_types, out);
2271 8 : sdl_serialize_soap_body(&binding->output, &tmp_encoders, &tmp_types, out);
2272 : } else {
2273 0 : WSDL_CACHE_PUT_1(0,out);
2274 : }
2275 : }
2276 8 : sdl_serialize_parameters((*tmp)->requestParameters, &tmp_encoders, &tmp_types, out);
2277 8 : sdl_serialize_parameters((*tmp)->responseParameters, &tmp_encoders, &tmp_types, out);
2278 :
2279 8 : if ((*tmp)->faults) {
2280 : sdlFaultPtr *fault;
2281 :
2282 2 : WSDL_CACHE_PUT_INT(zend_hash_num_elements((*tmp)->faults), out);
2283 :
2284 2 : zend_hash_internal_pointer_reset((*tmp)->faults);
2285 6 : while (zend_hash_get_current_data((*tmp)->faults, (void**)&fault) == SUCCESS) {
2286 2 : sdl_serialize_key((*tmp)->faults, out);
2287 2 : sdl_serialize_string((*fault)->name, out);
2288 2 : sdl_serialize_parameters((*fault)->details, &tmp_encoders, &tmp_types, out);
2289 4 : if ((*tmp)->binding->bindingType == BINDING_SOAP && (*fault)->bindingAttributes != NULL) {
2290 2 : sdlSoapBindingFunctionFaultPtr binding = (sdlSoapBindingFunctionFaultPtr)(*fault)->bindingAttributes;
2291 2 : WSDL_CACHE_PUT_1(binding->use, out);
2292 2 : if (binding->use == SOAP_ENCODED) {
2293 2 : WSDL_CACHE_PUT_1(binding->encodingStyle, out);
2294 : }
2295 2 : sdl_serialize_string(binding->ns, out);
2296 : } else {
2297 0 : WSDL_CACHE_PUT_1(0, out);
2298 : }
2299 2 : zend_hash_move_forward((*tmp)->faults);
2300 : }
2301 : } else {
2302 6 : WSDL_CACHE_PUT_INT(0, out);
2303 : }
2304 :
2305 8 : zend_hash_add(&tmp_functions, (char*)tmp, sizeof(*tmp), (void**)&function_num, sizeof(function_num), NULL);
2306 8 : function_num++;
2307 8 : zend_hash_move_forward(&sdl->functions);
2308 : }
2309 : }
2310 :
2311 : /* serialize requests */
2312 4 : if (sdl->requests) {
2313 0 : i = zend_hash_num_elements(sdl->requests);
2314 : } else {
2315 4 : i = 0;
2316 : }
2317 4 : WSDL_CACHE_PUT_INT(i, out);
2318 4 : if (i > 0) {
2319 : sdlFunctionPtr *tmp;
2320 : int *function_num;
2321 :
2322 0 : zend_hash_internal_pointer_reset(sdl->requests);
2323 0 : while (zend_hash_get_current_data(sdl->requests, (void**)&tmp) == SUCCESS) {
2324 0 : if (zend_hash_find(&tmp_functions, (char*)tmp, sizeof(*tmp), (void**)&function_num) != SUCCESS) {
2325 : }
2326 0 : WSDL_CACHE_PUT_INT(*function_num, out);
2327 0 : sdl_serialize_key(sdl->requests, out);
2328 0 : zend_hash_move_forward(sdl->requests);
2329 : }
2330 : }
2331 :
2332 4 : write(f, buf.c, buf.len);
2333 4 : close(f);
2334 4 : smart_str_free(&buf);
2335 4 : zend_hash_destroy(&tmp_functions);
2336 4 : zend_hash_destroy(&tmp_bindings);
2337 4 : zend_hash_destroy(&tmp_encoders);
2338 4 : zend_hash_destroy(&tmp_types);
2339 : }
2340 :
2341 :
2342 : static void make_persistent_restriction_int(void *data)
2343 0 : {
2344 0 : sdlRestrictionIntPtr *rest = (sdlRestrictionIntPtr *)data;
2345 0 : sdlRestrictionIntPtr prest = NULL;
2346 :
2347 0 : prest = malloc(sizeof(sdlRestrictionInt));
2348 0 : *prest = **rest;
2349 0 : *rest = prest;
2350 0 : }
2351 :
2352 :
2353 : static void make_persistent_restriction_char(void *data)
2354 0 : {
2355 0 : sdlRestrictionCharPtr *rest = (sdlRestrictionCharPtr *)data;
2356 0 : sdlRestrictionCharPtr prest = NULL;
2357 :
2358 0 : prest = malloc(sizeof(sdlRestrictionChar));
2359 0 : memset(prest, 0, sizeof(sdlRestrictionChar));
2360 0 : prest->value = strdup((*rest)->value);
2361 0 : prest->fixed = (*rest)->fixed;
2362 0 : *rest = prest;
2363 0 : }
2364 :
2365 :
2366 : static void make_persistent_sdl_type_ref(sdlTypePtr *type, HashTable *ptr_map, HashTable *bp_types)
2367 25 : {
2368 : sdlTypePtr *tmp;
2369 :
2370 25 : if (zend_hash_find(ptr_map, (char *)type, sizeof(sdlTypePtr), (void**)&tmp) == SUCCESS) {
2371 25 : *type = *tmp;
2372 : } else {
2373 0 : zend_hash_next_index_insert(bp_types, (void*)&type, sizeof(sdlTypePtr*), NULL);
2374 : }
2375 25 : }
2376 :
2377 :
2378 : static void make_persistent_sdl_encoder_ref(encodePtr *enc, HashTable *ptr_map, HashTable *bp_encoders)
2379 19 : {
2380 : encodePtr *tmp;
2381 :
2382 : /* do not process defaultEncoding's here */
2383 19 : if ((*enc) >= defaultEncoding && (*enc) < defaultEncoding + numDefaultEncodings) {
2384 16 : return;
2385 : }
2386 :
2387 3 : if (zend_hash_find(ptr_map, (char *)enc, sizeof(encodePtr), (void**)&tmp) == SUCCESS) {
2388 0 : *enc = *tmp;
2389 : } else {
2390 3 : zend_hash_next_index_insert(bp_encoders, (void*)&enc, sizeof(encodePtr*), NULL);
2391 : }
2392 : }
2393 :
2394 :
2395 : static HashTable* make_persistent_sdl_function_headers(HashTable *headers, HashTable *ptr_map)
2396 0 : {
2397 : HashTable *pheaders;
2398 : sdlSoapBindingFunctionHeaderPtr *tmp, pheader;
2399 : encodePtr *penc;
2400 : sdlTypePtr *ptype;
2401 : ulong index;
2402 : zstr key;
2403 : uint key_len;
2404 :
2405 0 : pheaders = malloc(sizeof(HashTable));
2406 0 : zend_hash_init(pheaders, zend_hash_num_elements(headers), NULL, delete_header_persistent, 1);
2407 :
2408 0 : zend_hash_internal_pointer_reset(headers);
2409 0 : while (zend_hash_get_current_data(headers, (void**)&tmp) == SUCCESS) {
2410 0 : pheader = malloc(sizeof(sdlSoapBindingFunctionHeader));
2411 0 : memset(pheader, 0, sizeof(sdlSoapBindingFunctionHeader));
2412 0 : *pheader = **tmp;
2413 :
2414 0 : if (pheader->name) {
2415 0 : pheader->name = strdup(pheader->name);
2416 : }
2417 0 : if (pheader->ns) {
2418 0 : pheader->ns = strdup(pheader->ns);
2419 : }
2420 :
2421 0 : if (pheader->encode->details.sdl_type) {
2422 0 : if (zend_hash_find(ptr_map, (char*)&pheader->encode, sizeof(encodePtr), (void**)&penc) == FAILURE) {
2423 : assert(0);
2424 : }
2425 0 : pheader->encode = *penc;
2426 : }
2427 0 : if (pheader->element) {
2428 0 : if (zend_hash_find(ptr_map, (char*)&pheader->element, sizeof(sdlTypePtr), (void**)&ptype) == FAILURE) {
2429 : assert(0);
2430 : }
2431 0 : pheader->element = *ptype;
2432 : }
2433 :
2434 0 : if (pheader->headerfaults) {
2435 0 : pheader->headerfaults = make_persistent_sdl_function_headers(pheader->headerfaults, ptr_map);
2436 : }
2437 :
2438 0 : if (zend_hash_get_current_key_ex(headers, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2439 0 : zend_hash_add(pheaders, key.s, key_len, (void*)&pheader, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL);
2440 : } else {
2441 0 : zend_hash_next_index_insert(pheaders, (void*)&pheader, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL);
2442 : }
2443 :
2444 0 : zend_hash_move_forward(headers);
2445 : }
2446 :
2447 0 : return pheaders;
2448 : }
2449 :
2450 :
2451 : static void make_persistent_sdl_soap_body(sdlSoapBindingFunctionBodyPtr body, HashTable *ptr_map)
2452 2 : {
2453 2 : if (body->ns) {
2454 2 : body->ns = strdup(body->ns);
2455 : }
2456 :
2457 2 : if (body->headers) {
2458 0 : body->headers = make_persistent_sdl_function_headers(body->headers, ptr_map);
2459 : }
2460 2 : }
2461 :
2462 :
2463 : static HashTable* make_persistent_sdl_parameters(HashTable *params, HashTable *ptr_map)
2464 2 : {
2465 : HashTable *pparams;
2466 : sdlParamPtr *tmp, pparam;
2467 : sdlTypePtr *ptype;
2468 : encodePtr *penc;
2469 : ulong index;
2470 : zstr key;
2471 : uint key_len;
2472 :
2473 2 : pparams = malloc(sizeof(HashTable));
2474 2 : zend_hash_init(pparams, zend_hash_num_elements(params), NULL, delete_parameter_persistent, 1);
2475 :
2476 2 : zend_hash_internal_pointer_reset(params);
2477 8 : while (zend_hash_get_current_data(params, (void**)&tmp) == SUCCESS) {
2478 4 : pparam = malloc(sizeof(sdlParam));
2479 4 : memset(pparam, 0, sizeof(sdlParam));
2480 4 : *pparam = **tmp;
2481 :
2482 4 : if (pparam->paramName) {
2483 4 : pparam->paramName = strdup(pparam->paramName);
2484 : }
2485 :
2486 4 : if (pparam->encode && pparam->encode->details.sdl_type) {
2487 2 : if (zend_hash_find(ptr_map, (char*)&pparam->encode, sizeof(encodePtr), (void**)&penc) == FAILURE) {
2488 : assert(0);
2489 : }
2490 2 : pparam->encode = *penc;
2491 : }
2492 4 : if (pparam->element) {
2493 0 : if (zend_hash_find(ptr_map, (char*)&pparam->element, sizeof(sdlTypePtr), (void**)&ptype) == FAILURE) {
2494 : assert(0);
2495 : }
2496 0 : pparam->element = *ptype;
2497 : }
2498 :
2499 4 : if (zend_hash_get_current_key_ex(params, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2500 0 : zend_hash_add(pparams, key.s, key_len, (void*)&pparam, sizeof(sdlParamPtr), NULL);
2501 : } else {
2502 4 : zend_hash_next_index_insert(pparams, (void*)&pparam, sizeof(sdlParamPtr), NULL);
2503 : }
2504 :
2505 4 : zend_hash_move_forward(params);
2506 : }
2507 :
2508 :
2509 2 : return pparams;
2510 : }
2511 :
2512 : static HashTable* make_persistent_sdl_function_faults(sdlFunctionPtr func, HashTable *faults, HashTable *ptr_map)
2513 0 : {
2514 : HashTable *pfaults;
2515 : sdlFaultPtr *tmp, pfault;
2516 : ulong index;
2517 : zstr key;
2518 : uint key_len;
2519 :
2520 0 : pfaults = malloc(sizeof(HashTable));
2521 0 : zend_hash_init(pfaults, zend_hash_num_elements(faults), NULL, delete_fault_persistent, 1);
2522 :
2523 0 : zend_hash_internal_pointer_reset(faults);
2524 0 : while (zend_hash_get_current_data(faults, (void**)&tmp) == SUCCESS) {
2525 0 : pfault = malloc(sizeof(sdlFault));
2526 0 : memset(pfault, 0, sizeof(sdlFault));
2527 0 : *pfault = **tmp;
2528 :
2529 0 : if (pfault->name) {
2530 0 : pfault->name = strdup(pfault->name);
2531 : }
2532 0 : if (pfault->details) {
2533 0 : pfault->details = make_persistent_sdl_parameters(pfault->details, ptr_map);
2534 : }
2535 :
2536 0 : if (func->binding->bindingType == BINDING_SOAP && pfault->bindingAttributes) {
2537 : sdlSoapBindingFunctionFaultPtr soap_binding;
2538 :
2539 0 : soap_binding = malloc(sizeof(sdlSoapBindingFunctionFault));
2540 0 : memset(soap_binding, 0, sizeof(sdlSoapBindingFunctionFault));
2541 0 : *soap_binding = *(sdlSoapBindingFunctionFaultPtr)pfault->bindingAttributes;
2542 0 : if (soap_binding->ns) {
2543 0 : soap_binding->ns = strdup(soap_binding->ns);
2544 : }
2545 0 : pfault->bindingAttributes = soap_binding;
2546 : }
2547 :
2548 0 : if (zend_hash_get_current_key_ex(faults, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2549 0 : zend_hash_add(pfaults, key.s, key_len, (void*)&pfault, sizeof(sdlParamPtr), NULL);
2550 : } else {
2551 0 : zend_hash_next_index_insert(pfaults, (void*)&pfault, sizeof(sdlParamPtr), NULL);
2552 : }
2553 :
2554 0 : zend_hash_move_forward(faults);
2555 : }
2556 :
2557 :
2558 0 : return pfaults;
2559 : }
2560 :
2561 :
2562 : static sdlAttributePtr make_persistent_sdl_attribute(sdlAttributePtr attr, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
2563 2 : {
2564 : sdlAttributePtr pattr;
2565 : ulong index;
2566 : zstr key;
2567 : uint key_len;
2568 :
2569 2 : pattr = malloc(sizeof(sdlAttribute));
2570 2 : memset(pattr, 0, sizeof(sdlAttribute));
2571 :
2572 2 : *pattr = *attr;
2573 :
2574 2 : if (pattr->name) {
2575 2 : pattr->name = strdup(pattr->name);
2576 : }
2577 2 : if (pattr->namens) {
2578 2 : pattr->namens = strdup(pattr->namens);
2579 : }
2580 2 : if (pattr->ref) {
2581 0 : pattr->ref = strdup(pattr->ref);
2582 : }
2583 2 : if (pattr->def) {
2584 0 : pattr->def = strdup(pattr->def);
2585 : }
2586 2 : if (pattr->fixed) {
2587 0 : pattr->fixed = strdup(pattr->fixed);
2588 : }
2589 :
2590 : /* we do not want to process defaultEncoding's here */
2591 2 : if (pattr->encode) {
2592 0 : make_persistent_sdl_encoder_ref(&pattr->encode, ptr_map, bp_encoders);
2593 : }
2594 :
2595 2 : if (pattr->extraAttributes) {
2596 : sdlExtraAttributePtr *tmp, pextra;
2597 :
2598 2 : pattr->extraAttributes = malloc(sizeof(HashTable));
2599 2 : zend_hash_init(pattr->extraAttributes, zend_hash_num_elements(attr->extraAttributes), NULL, delete_extra_attribute_persistent, 1);
2600 :
2601 2 : zend_hash_internal_pointer_reset(pattr->extraAttributes);
2602 4 : while (zend_hash_get_current_data(attr->extraAttributes, (void**)&tmp) == SUCCESS) {
2603 0 : pextra = malloc(sizeof(sdlExtraAttribute));
2604 0 : memset(pextra, 0, sizeof(sdlExtraAttribute));
2605 0 : if ((*tmp)->ns) {
2606 0 : pextra->ns = strdup((*tmp)->ns);
2607 : }
2608 0 : if ((*tmp)->val) {
2609 0 : pextra->val = strdup((*tmp)->val);
2610 : }
2611 :
2612 0 : if (zend_hash_get_current_key_ex(attr->extraAttributes, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2613 0 : zend_hash_add(pattr->extraAttributes, key.s, key_len, (void*)&pextra, sizeof(sdlExtraAttributePtr), NULL);
2614 : }
2615 :
2616 0 : zend_hash_move_forward(attr->extraAttributes);
2617 : }
2618 : }
2619 :
2620 2 : return pattr;
2621 : }
2622 :
2623 :
2624 : static sdlContentModelPtr make_persistent_sdl_model(sdlContentModelPtr model, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
2625 23 : {
2626 : sdlContentModelPtr pmodel;
2627 : sdlContentModelPtr *tmp, pcontent;
2628 :
2629 23 : pmodel = malloc(sizeof(sdlContentModel));
2630 23 : memset(pmodel, 0, sizeof(sdlContentModel));
2631 23 : *pmodel = *model;
2632 :
2633 23 : switch (pmodel->kind) {
2634 : case XSD_CONTENT_ELEMENT:
2635 17 : if (pmodel->u.element) {
2636 17 : make_persistent_sdl_type_ref(&pmodel->u.element, ptr_map, bp_types);
2637 : }
2638 17 : break;
2639 :
2640 : case XSD_CONTENT_SEQUENCE:
2641 : case XSD_CONTENT_ALL:
2642 : case XSD_CONTENT_CHOICE:
2643 6 : pmodel->u.content = malloc(sizeof(HashTable));
2644 6 : zend_hash_init(pmodel->u.content, zend_hash_num_elements(model->u.content), NULL, delete_model_persistent, 1);
2645 :
2646 6 : zend_hash_internal_pointer_reset(model->u.content);
2647 29 : while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
2648 17 : pcontent = make_persistent_sdl_model(*tmp, ptr_map, bp_types, bp_encoders);
2649 17 : zend_hash_next_index_insert(pmodel->u.content, (void*)&pcontent, sizeof(sdlContentModelPtr), NULL);
2650 17 : zend_hash_move_forward(model->u.content);
2651 : }
2652 6 : break;
2653 :
2654 : case XSD_CONTENT_GROUP_REF:
2655 0 : if (pmodel->u.group_ref) {
2656 0 : pmodel->u.group_ref = strdup(pmodel->u.group_ref);
2657 : }
2658 0 : break;
2659 :
2660 : case XSD_CONTENT_GROUP:
2661 0 : if (pmodel->u.group) {
2662 0 : make_persistent_sdl_type_ref(&pmodel->u.group, ptr_map, bp_types);
2663 : }
2664 : break;
2665 :
2666 : default:
2667 : break;
2668 : }
2669 :
2670 23 : return pmodel;
2671 : }
2672 :
2673 :
2674 : static sdlTypePtr make_persistent_sdl_type(sdlTypePtr type, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
2675 25 : {
2676 : ulong index;
2677 : zstr key;
2678 : uint key_len;
2679 25 : sdlTypePtr ptype = NULL;
2680 :
2681 25 : ptype = malloc(sizeof(sdlType));
2682 25 : memset(ptype, 0, sizeof(sdlType));
2683 :
2684 25 : *ptype = *type;
2685 :
2686 25 : if (ptype->name) {
2687 25 : ptype->name = strdup(ptype->name);
2688 : }
2689 25 : if (ptype->namens) {
2690 25 : ptype->namens = strdup(ptype->namens);
2691 : }
2692 25 : if (ptype->def) {
2693 0 : ptype->def = strdup(ptype->def);
2694 : }
2695 25 : if (ptype->fixed) {
2696 0 : ptype->fixed = strdup(ptype->fixed);
2697 : }
2698 25 : if (ptype->ref) {
2699 0 : ptype->ref = strdup(ptype->ref);
2700 : }
2701 :
2702 : /* we do not want to process defaultEncoding's here */
2703 25 : if (ptype->encode) {
2704 19 : make_persistent_sdl_encoder_ref(&ptype->encode, ptr_map, bp_encoders);
2705 : }
2706 :
2707 25 : if (ptype->restrictions) {
2708 0 : ptype->restrictions = malloc(sizeof(sdlRestrictions));
2709 0 : memset(ptype->restrictions, 0, sizeof(sdlRestrictions));
2710 0 : *ptype->restrictions = *type->restrictions;
2711 :
2712 0 : if (ptype->restrictions->minExclusive) {
2713 0 : make_persistent_restriction_int(&ptype->restrictions->minExclusive);
2714 : }
2715 0 : if (ptype->restrictions->maxExclusive) {
2716 0 : make_persistent_restriction_int(&ptype->restrictions->maxExclusive);
2717 : }
2718 0 : if (ptype->restrictions->minInclusive) {
2719 0 : make_persistent_restriction_int(&ptype->restrictions->minInclusive);
2720 : }
2721 0 : if (ptype->restrictions->maxInclusive) {
2722 0 : make_persistent_restriction_int(&ptype->restrictions->maxInclusive);
2723 : }
2724 0 : if (ptype->restrictions->totalDigits) {
2725 0 : make_persistent_restriction_int(&ptype->restrictions->totalDigits);
2726 : }
2727 0 : if (ptype->restrictions->fractionDigits) {
2728 0 : make_persistent_restriction_int(&ptype->restrictions->fractionDigits);
2729 : }
2730 0 : if (ptype->restrictions->length) {
2731 0 : make_persistent_restriction_int(&ptype->restrictions->length);
2732 : }
2733 0 : if (ptype->restrictions->minLength) {
2734 0 : make_persistent_restriction_int(&ptype->restrictions->minLength);
2735 : }
2736 0 : if (ptype->restrictions->maxLength) {
2737 0 : make_persistent_restriction_int(&ptype->restrictions->maxLength);
2738 : }
2739 0 : if (ptype->restrictions->whiteSpace) {
2740 0 : make_persistent_restriction_char(&ptype->restrictions->whiteSpace);
2741 : }
2742 0 : if (ptype->restrictions->pattern) {
2743 0 : make_persistent_restriction_char(&ptype->restrictions->pattern);
2744 : }
2745 :
2746 0 : if (type->restrictions->enumeration) {
2747 : sdlRestrictionCharPtr tmp;
2748 :
2749 0 : ptype->restrictions->enumeration = malloc(sizeof(HashTable));
2750 0 : zend_hash_init(ptype->restrictions->enumeration, zend_hash_num_elements(type->restrictions->enumeration), NULL, delete_restriction_var_char_persistent, 1);
2751 0 : zend_hash_copy(ptype->restrictions->enumeration, type->restrictions->enumeration, make_persistent_restriction_char, (void*)&tmp, sizeof(sdlRestrictionCharPtr));
2752 : }
2753 : }
2754 :
2755 25 : if (ptype->elements) {
2756 : sdlTypePtr *tmp, pelem;
2757 :
2758 6 : ptype->elements = malloc(sizeof(HashTable));
2759 6 : zend_hash_init(ptype->elements, zend_hash_num_elements(type->elements), NULL, delete_type_persistent, 1);
2760 :
2761 6 : zend_hash_internal_pointer_reset(type->elements);
2762 29 : while (zend_hash_get_current_data(type->elements, (void **)&tmp) == SUCCESS) {
2763 17 : pelem = make_persistent_sdl_type(*tmp, ptr_map, bp_types, bp_encoders);
2764 17 : if (zend_hash_get_current_key_ex(type->elements, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2765 17 : zend_hash_add(ptype->elements, key.s, key_len, (void*)&pelem, sizeof(sdlTypePtr), NULL);
2766 : } else {
2767 0 : zend_hash_next_index_insert(ptype->elements, (void*)&pelem, sizeof(sdlTypePtr), NULL);
2768 : }
2769 17 : zend_hash_add(ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pelem, sizeof(sdlTypePtr), NULL);
2770 17 : zend_hash_move_forward(type->elements);
2771 : }
2772 : }
2773 :
2774 25 : if (ptype->attributes) {
2775 : sdlAttributePtr *tmp, pattr;
2776 :
2777 2 : ptype->attributes = malloc(sizeof(HashTable));
2778 2 : zend_hash_init(ptype->attributes, zend_hash_num_elements(type->attributes), NULL, delete_attribute_persistent, 1);
2779 :
2780 2 : zend_hash_internal_pointer_reset(type->attributes);
2781 6 : while (zend_hash_get_current_data(type->attributes, (void **)&tmp) == SUCCESS) {
2782 2 : pattr = make_persistent_sdl_attribute(*tmp, ptr_map, bp_types, bp_encoders);
2783 2 : if (zend_hash_get_current_key_ex(type->attributes, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2784 2 : zend_hash_add(ptype->attributes, key.s, key_len, (void*)&pattr, sizeof(sdlAttributePtr), NULL);
2785 : } else {
2786 0 : zend_hash_next_index_insert(ptype->attributes, (void*)&pattr, sizeof(sdlAttributePtr), NULL);
2787 : }
2788 2 : zend_hash_move_forward(type->attributes);
2789 : }
2790 : }
2791 :
2792 25 : if (type->model) {
2793 6 : ptype->model = make_persistent_sdl_model(ptype->model, ptr_map, bp_types, bp_encoders);
2794 : }
2795 :
2796 25 : return ptype;
2797 : }
2798 :
2799 : static encodePtr make_persistent_sdl_encoder(encodePtr enc, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
2800 8 : {
2801 8 : encodePtr penc = NULL;
2802 :
2803 8 : penc = malloc(sizeof(encode));
2804 8 : memset(penc, 0, sizeof(encode));
2805 :
2806 8 : *penc = *enc;
2807 :
2808 8 : if (penc->details.type_str) {
2809 8 : penc->details.type_str = strdup(penc->details.type_str);
2810 : }
2811 8 : if (penc->details.ns) {
2812 8 : penc->details.ns = strdup(penc->details.ns);
2813 : }
2814 :
2815 8 : if (penc->details.sdl_type) {
2816 8 : make_persistent_sdl_type_ref(&penc->details.sdl_type, ptr_map, bp_types);
2817 : }
2818 :
2819 8 : return penc;
2820 : }
2821 :
2822 : static sdlBindingPtr make_persistent_sdl_binding(sdlBindingPtr bind, HashTable *ptr_map)
2823 1 : {
2824 1 : sdlBindingPtr pbind = NULL;
2825 :
2826 1 : pbind = malloc(sizeof(sdlBinding));
2827 1 : memset(pbind, 0, sizeof(sdlBinding));
2828 :
2829 1 : *pbind = *bind;
2830 :
2831 1 : if (pbind->name) {
2832 1 : pbind->name = strdup(pbind->name);
2833 : }
2834 1 : if (pbind->location) {
2835 1 : pbind->location = strdup(pbind->location);
2836 : }
2837 :
2838 1 : if (pbind->bindingType == BINDING_SOAP && pbind->bindingAttributes) {
2839 : sdlSoapBindingPtr soap_binding;
2840 :
2841 1 : soap_binding = malloc(sizeof(sdlSoapBinding));
2842 1 : memset(soap_binding, 0, sizeof(sdlSoapBinding));
2843 1 : *soap_binding = *(sdlSoapBindingPtr)pbind->bindingAttributes;
2844 1 : pbind->bindingAttributes = soap_binding;
2845 : }
2846 :
2847 1 : return pbind;
2848 : }
2849 :
2850 : static sdlFunctionPtr make_persistent_sdl_function(sdlFunctionPtr func, HashTable *ptr_map)
2851 1 : {
2852 1 : sdlFunctionPtr pfunc = NULL;
2853 :
2854 1 : pfunc = malloc(sizeof(sdlFunction));
2855 1 : memset(pfunc, 0, sizeof(sdlFunction));
2856 :
2857 1 : *pfunc = *func;
2858 :
2859 1 : if (pfunc->functionName) {
2860 1 : pfunc->functionName = strdup(pfunc->functionName);
2861 : }
2862 1 : if (pfunc->requestName) {
2863 1 : pfunc->requestName = strdup(pfunc->requestName);
2864 : }
2865 1 : if (pfunc->responseName) {
2866 1 : pfunc->responseName = strdup(pfunc->responseName);
2867 : }
2868 :
2869 1 : if (pfunc->binding) {
2870 : sdlBindingPtr *tmp;
2871 :
2872 1 : if (zend_hash_find(ptr_map, (char*)&pfunc->binding, sizeof(pfunc->binding), (void**)&tmp) == FAILURE) {
2873 : assert(0);
2874 : }
2875 1 : pfunc->binding = *tmp;
2876 :
2877 1 : if (pfunc->binding->bindingType == BINDING_SOAP && pfunc->bindingAttributes) {
2878 : sdlSoapBindingFunctionPtr soap_binding;
2879 :
2880 1 : soap_binding = malloc(sizeof(sdlSoapBindingFunction));
2881 1 : memset(soap_binding, 0, sizeof(sdlSoapBindingFunction));
2882 1 : *soap_binding = *(sdlSoapBindingFunctionPtr)pfunc->bindingAttributes;
2883 1 : if (soap_binding->soapAction) {
2884 1 : soap_binding->soapAction = strdup(soap_binding->soapAction);
2885 : }
2886 1 : make_persistent_sdl_soap_body(&soap_binding->input, ptr_map);
2887 1 : make_persistent_sdl_soap_body(&soap_binding->output, ptr_map);
2888 1 : pfunc->bindingAttributes = soap_binding;
2889 : }
2890 :
2891 1 : if (pfunc->requestParameters) {
2892 1 : pfunc->requestParameters = make_persistent_sdl_parameters(pfunc->requestParameters, ptr_map);
2893 : }
2894 1 : if (pfunc->responseParameters) {
2895 1 : pfunc->responseParameters = make_persistent_sdl_parameters(pfunc->responseParameters, ptr_map);
2896 : }
2897 1 : if (pfunc->faults) {
2898 0 : pfunc->faults = make_persistent_sdl_function_faults(pfunc, pfunc->faults, ptr_map);
2899 : }
2900 : }
2901 :
2902 1 : return pfunc;
2903 : }
2904 :
2905 : static sdlPtr make_persistent_sdl(sdlPtr sdl TSRMLS_DC)
2906 1 : {
2907 1 : sdlPtr psdl = NULL;
2908 : HashTable ptr_map;
2909 : HashTable bp_types, bp_encoders;
2910 : ulong index;
2911 : zstr key;
2912 : uint key_len;
2913 :
2914 1 : zend_hash_init(&bp_types, 0, NULL, NULL, 0);
2915 1 : zend_hash_init(&bp_encoders, 0, NULL, NULL, 0);
2916 1 : zend_hash_init(&ptr_map, 0, NULL, NULL, 0);
2917 :
2918 1 : psdl = malloc(sizeof(*sdl));
2919 1 : memset(psdl, 0, sizeof(*sdl));
2920 :
2921 1 : if (sdl->source) {
2922 1 : psdl->source = strdup(sdl->source);
2923 : }
2924 1 : if (sdl->target_ns) {
2925 1 : psdl->target_ns = strdup(sdl->target_ns);
2926 : }
2927 :
2928 1 : if (sdl->groups) {
2929 : sdlTypePtr *tmp;
2930 : sdlTypePtr ptype;
2931 :
2932 0 : psdl->groups = malloc(sizeof(HashTable));
2933 0 : zend_hash_init(psdl->groups, zend_hash_num_elements(sdl->groups), NULL, delete_type_persistent, 1);
2934 :
2935 0 : zend_hash_internal_pointer_reset(sdl->groups);
2936 0 : while (zend_hash_get_current_data(sdl->groups, (void **)&tmp) == SUCCESS) {
2937 0 : ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
2938 0 : if (zend_hash_get_current_key_ex(sdl->groups, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2939 0 : zend_hash_add(psdl->groups, key.s, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2940 : } else {
2941 0 : zend_hash_next_index_insert(psdl->groups, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2942 : }
2943 0 : zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
2944 0 : zend_hash_move_forward(sdl->groups);
2945 : }
2946 : }
2947 :
2948 1 : if (sdl->types) {
2949 : sdlTypePtr *tmp;
2950 : sdlTypePtr ptype;
2951 :
2952 1 : psdl->types = malloc(sizeof(HashTable));
2953 1 : zend_hash_init(psdl->types, zend_hash_num_elements(sdl->types), NULL, delete_type_persistent, 1);
2954 :
2955 1 : zend_hash_internal_pointer_reset(sdl->types);
2956 10 : while (zend_hash_get_current_data(sdl->types, (void **)&tmp) == SUCCESS) {
2957 8 : ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
2958 8 : if (zend_hash_get_current_key_ex(sdl->types, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2959 0 : zend_hash_add(psdl->types, key.s, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2960 : } else {
2961 8 : zend_hash_next_index_insert(psdl->types, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2962 : }
2963 8 : zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
2964 8 : zend_hash_move_forward(sdl->types);
2965 : }
2966 : }
2967 :
2968 1 : if (sdl->elements) {
2969 : sdlTypePtr *tmp;
2970 : sdlTypePtr ptype;
2971 :
2972 0 : psdl->elements = malloc(sizeof(HashTable));
2973 0 : zend_hash_init(psdl->elements, zend_hash_num_elements(sdl->elements), NULL, delete_type_persistent, 1);
2974 :
2975 0 : zend_hash_internal_pointer_reset(sdl->elements);
2976 0 : while (zend_hash_get_current_data(sdl->elements, (void **)&tmp) == SUCCESS) {
2977 0 : ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
2978 0 : if (zend_hash_get_current_key_ex(sdl->elements, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2979 0 : zend_hash_add(psdl->elements, key.s, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2980 : } else {
2981 0 : zend_hash_next_index_insert(psdl->elements, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2982 : }
2983 0 : zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
2984 0 : zend_hash_move_forward(sdl->elements);
2985 : }
2986 : }
2987 :
2988 1 : if (sdl->encoders) {
2989 : encodePtr *tmp;
2990 : encodePtr penc;
2991 :
2992 1 : psdl->encoders = malloc(sizeof(HashTable));
2993 1 : zend_hash_init(psdl->encoders, zend_hash_num_elements(sdl->encoders), NULL, delete_encoder_persistent, 1);
2994 :
2995 1 : zend_hash_internal_pointer_reset(sdl->encoders);
2996 10 : while (zend_hash_get_current_data(sdl->encoders, (void **)&tmp) == SUCCESS) {
2997 8 : penc = make_persistent_sdl_encoder(*tmp, &ptr_map, &bp_types, &bp_encoders);
2998 8 : if (zend_hash_get_current_key_ex(sdl->encoders, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2999 8 : zend_hash_add(psdl->encoders, key.s, key_len, (void*)&penc, sizeof(encodePtr), NULL);
3000 : } else {
3001 0 : zend_hash_next_index_insert(psdl->encoders, (void*)&penc, sizeof(encodePtr), NULL);
3002 : }
3003 8 : zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&penc, sizeof(encodePtr), NULL);
3004 8 : zend_hash_move_forward(sdl->encoders);
3005 : }
3006 : }
3007 :
3008 : /* do backpatching here */
3009 1 : if (zend_hash_num_elements(&bp_types)) {
3010 0 : sdlTypePtr **tmp, *ptype = NULL;
3011 :
3012 0 : zend_hash_internal_pointer_reset(&bp_types);
3013 0 : while (zend_hash_get_current_data(&bp_types, (void**)&tmp) == SUCCESS) {
3014 0 : if (zend_hash_find(&ptr_map, (char*)(*tmp), sizeof(**tmp), (void**)&ptype) == FAILURE) {
3015 : assert(0);
3016 : }
3017 0 : **tmp = *ptype;
3018 0 : zend_hash_move_forward(&bp_types);
3019 : }
3020 : }
3021 1 : if (zend_hash_num_elements(&bp_encoders)) {
3022 1 : encodePtr **tmp, *penc = NULL;
3023 :
3024 1 : zend_hash_internal_pointer_reset(&bp_encoders);
3025 5 : while (zend_hash_get_current_data(&bp_encoders, (void**)&tmp) == SUCCESS) {
3026 3 : if (zend_hash_find(&ptr_map, (char*)(*tmp), sizeof(**tmp), (void**)&penc) == FAILURE) {
3027 : assert(0);
3028 : }
3029 3 : **tmp = *penc;
3030 3 : zend_hash_move_forward(&bp_encoders);
3031 : }
3032 : }
3033 :
3034 :
3035 1 : if (sdl->bindings) {
3036 : sdlBindingPtr *tmp;
3037 : sdlBindingPtr pbind;
3038 :
3039 1 : psdl->bindings = malloc(sizeof(HashTable));
3040 1 : zend_hash_init(psdl->bindings, zend_hash_num_elements(sdl->bindings), NULL, delete_binding_persistent, 1);
3041 :
3042 1 : zend_hash_internal_pointer_reset(sdl->bindings);
3043 3 : while (zend_hash_get_current_data(sdl->bindings, (void **)&tmp) == SUCCESS) {
3044 1 : pbind = make_persistent_sdl_binding(*tmp, &ptr_map);
3045 1 : if (zend_hash_get_current_key_ex(sdl->bindings, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
3046 1 : zend_hash_add(psdl->bindings, key.s, key_len, (void*)&pbind, sizeof(sdlBindingPtr), NULL);
3047 : } else {
3048 0 : zend_hash_next_index_insert(psdl->bindings, (void*)&pbind, sizeof(sdlBindingPtr), NULL);
3049 : }
3050 1 : zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pbind, sizeof(sdlBindingPtr), NULL);
3051 1 : zend_hash_move_forward(sdl->bindings);
3052 : }
3053 : }
3054 :
3055 1 : zend_hash_init(&psdl->functions, zend_hash_num_elements(&sdl->functions), NULL, delete_function_persistent, 1);
3056 1 : if (zend_hash_num_elements(&sdl->functions)) {
3057 : sdlFunctionPtr *tmp;
3058 : sdlFunctionPtr pfunc;
3059 :
3060 1 : zend_hash_internal_pointer_reset(&sdl->functions);
3061 3 : while (zend_hash_get_current_data(&sdl->functions, (void **)&tmp) == SUCCESS) {
3062 1 : pfunc = make_persistent_sdl_function(*tmp, &ptr_map);
3063 1 : if (zend_hash_get_current_key_ex(&sdl->functions, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
3064 1 : zend_hash_add(&psdl->functions, key.s, key_len, (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
3065 : } else {
3066 0 : zend_hash_next_index_insert(&psdl->functions, (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
3067 : }
3068 1 : zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
3069 1 : zend_hash_move_forward(&sdl->functions);
3070 : }
3071 : }
3072 :
3073 1 : if (sdl->requests) {
3074 : sdlFunctionPtr *tmp;
3075 : sdlFunctionPtr *preq;
3076 :
3077 0 : psdl->requests = malloc(sizeof(HashTable));
3078 0 : zend_hash_init(psdl->requests, zend_hash_num_elements(sdl->requests), NULL, NULL, 1);
3079 :
3080 0 : zend_hash_internal_pointer_reset(sdl->requests);
3081 0 : while (zend_hash_get_current_data(sdl->requests, (void **)&tmp) == SUCCESS) {
3082 0 : if (zend_hash_find(&ptr_map, (char*)tmp, sizeof(*tmp), (void**)&preq) == FAILURE) {
3083 : assert(0);
3084 : }
3085 0 : *tmp = *preq;
3086 0 : if (zend_hash_get_current_key_ex(sdl->requests, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
3087 0 : zend_hash_add(psdl->requests, key.s, key_len, (void*)&preq, sizeof(sdlFunctionPtr), NULL);
3088 : }
3089 0 : zend_hash_move_forward(sdl->requests);
3090 : }
3091 : }
3092 :
3093 1 : zend_hash_destroy(&ptr_map);
3094 1 : zend_hash_destroy(&bp_encoders);
3095 1 : zend_hash_destroy(&bp_types);
3096 :
3097 1 : return psdl;
3098 : }
3099 :
3100 : typedef struct _sdl_cache_bucket {
3101 : sdlPtr sdl;
3102 : time_t time;
3103 : } sdl_cache_bucket;
3104 :
3105 : static void delete_psdl(void *data)
3106 1 : {
3107 1 : sdl_cache_bucket *p = (sdl_cache_bucket*)data;
3108 1 : sdlPtr tmp = p->sdl;
3109 :
3110 1 : zend_hash_destroy(&tmp->functions);
3111 1 : if (tmp->source) {
3112 1 : free(tmp->source);
3113 : }
3114 1 : if (tmp->target_ns) {
3115 1 : free(tmp->target_ns);
3116 : }
3117 1 : if (tmp->elements) {
3118 0 : zend_hash_destroy(tmp->elements);
3119 0 : free(tmp->elements);
3120 : }
3121 1 : if (tmp->encoders) {
3122 1 : zend_hash_destroy(tmp->encoders);
3123 1 : free(tmp->encoders);
3124 : }
3125 1 : if (tmp->types) {
3126 1 : zend_hash_destroy(tmp->types);
3127 1 : free(tmp->types);
3128 : }
3129 1 : if (tmp->groups) {
3130 0 : zend_hash_destroy(tmp->groups);
3131 0 : free(tmp->groups);
3132 : }
3133 1 : if (tmp->bindings) {
3134 1 : zend_hash_destroy(tmp->bindings);
3135 1 : free(tmp->bindings);
3136 : }
3137 1 : if (tmp->requests) {
3138 0 : zend_hash_destroy(tmp->requests);
3139 0 : free(tmp->requests);
3140 : }
3141 1 : free(tmp);
3142 1 : }
3143 :
3144 : sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
3145 704 : {
3146 : char fn[MAXPATHLEN];
3147 704 : sdlPtr sdl = NULL;
3148 704 : char* old_error_code = SOAP_GLOBAL(error_code);
3149 704 : int uri_len = 0;
3150 704 : php_stream_context *context=NULL;
3151 704 : zval *orig_context = NULL, *new_context = NULL;
3152 704 : smart_str headers = {0};
3153 704 : char* key = NULL;
3154 704 : time_t t = time(0);
3155 : zval **tmp;
3156 :
3157 1408 : if (strchr(uri,':') != NULL || IS_ABSOLUTE_PATH(uri, uri_len)) {
3158 704 : uri_len = strlen(uri);
3159 0 : } else if (VCWD_REALPATH(uri, fn) == NULL) {
3160 0 : cache_wsdl = WSDL_CACHE_NONE;
3161 : } else {
3162 0 : uri = fn;
3163 0 : uri_len = strlen(uri);
3164 : }
3165 :
3166 704 : if ((cache_wsdl & WSDL_CACHE_MEMORY) && SOAP_GLOBAL(mem_cache)) {
3167 : sdl_cache_bucket *p;
3168 :
3169 9 : if (SUCCESS == zend_hash_find(SOAP_GLOBAL(mem_cache), uri, uri_len+1, (void*)&p)) {
3170 9 : if (p->time < t - SOAP_GLOBAL(cache_ttl)) {
3171 : /* in-memory cache entry is expired */
3172 0 : zend_hash_del(&EG(persistent_list), uri, uri_len+1);
3173 : } else {
3174 9 : return p->sdl;
3175 : }
3176 : }
3177 : }
3178 :
3179 695 : if ((cache_wsdl & WSDL_CACHE_DISK) && (uri_len < MAXPATHLEN)) {
3180 7 : time_t t = time(0);
3181 : char md5str[33];
3182 : PHP_MD5_CTX context;
3183 : unsigned char digest[16];
3184 7 : int len = strlen(SOAP_GLOBAL(cache_dir));
3185 : time_t cached;
3186 7 : char *user = php_get_current_user();
3187 7 : int user_len = user ? strlen(user) + 1 : 0;
3188 :
3189 7 : md5str[0] = '\0';
3190 7 : PHP_MD5Init(&context);
3191 7 : PHP_MD5Update(&context, (unsigned char*)uri, uri_len);
3192 7 : PHP_MD5Final(digest, &context);
3193 7 : make_digest(md5str, digest);
3194 7 : key = emalloc(len+sizeof("/wsdl-")-1+user_len+sizeof(md5str));
3195 7 : memcpy(key,SOAP_GLOBAL(cache_dir),len);
3196 7 : memcpy(key+len,"/wsdl-",sizeof("/wsdl-")-1);
3197 7 : len += sizeof("/wsdl-")-1;
3198 7 : if (user_len) {
3199 7 : memcpy(key+len, user, user_len-1);
3200 7 : len += user_len-1;
3201 7 : key[len++] = '-';
3202 : }
3203 7 : memcpy(key+len,md5str,sizeof(md5str));
3204 :
3205 7 : if ((sdl = get_sdl_from_cache(key, uri, t-SOAP_GLOBAL(cache_ttl), &cached TSRMLS_CC)) != NULL) {
3206 2 : t = cached;
3207 2 : efree(key);
3208 2 : goto cache_in_memory;
3209 : }
3210 : }
3211 :
3212 693 : if (this_ptr) {
3213 : soap_client_object *client;
3214 :
3215 287 : client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
3216 :
3217 287 : if (client->stream_context) {
3218 0 : context = client->stream_context;
3219 : } else {
3220 287 : context = php_stream_context_alloc();
3221 : }
3222 :
3223 287 : if (client->proxy_host) {
3224 : zval *str_proxy;
3225 0 : smart_str proxy = {0};
3226 :
3227 0 : smart_str_appends(&proxy,"tcp://");
3228 0 : smart_str_appends(&proxy, client->proxy_host);
3229 0 : smart_str_appends(&proxy,":");
3230 0 : smart_str_append_unsigned(&proxy, client->proxy_port);
3231 0 : smart_str_0(&proxy);
3232 0 : MAKE_STD_ZVAL(str_proxy);
3233 0 : ZVAL_STRING(str_proxy, proxy.c, 1);
3234 0 : smart_str_free(&proxy);
3235 :
3236 0 : if (!context) {
3237 0 : context = php_stream_context_alloc();
3238 : }
3239 0 : php_stream_context_set_option(context, "http", "proxy", str_proxy);
3240 0 : zval_ptr_dtor(&str_proxy);
3241 :
3242 0 : MAKE_STD_ZVAL(str_proxy);
3243 0 : ZVAL_BOOL(str_proxy, 1);
3244 0 : php_stream_context_set_option(context, "http", "request_fulluri", str_proxy);
3245 0 : zval_ptr_dtor(&str_proxy);
3246 :
3247 0 : proxy_authentication(this_ptr, &headers TSRMLS_CC);
3248 : }
3249 :
3250 287 : basic_authentication(this_ptr, &headers TSRMLS_CC);
3251 :
3252 : /* Use HTTP/1.1 with "Connection: close" by default */
3253 287 : if (php_stream_context_get_option(context, "http", "protocol_version", &tmp) == FAILURE) {
3254 : zval *http_version;
3255 :
3256 287 : MAKE_STD_ZVAL(http_version);
3257 287 : ZVAL_DOUBLE(http_version, 1.1);
3258 287 : php_stream_context_set_option(context, "http", "protocol_version", http_version);
3259 287 : zval_ptr_dtor(&http_version);
3260 287 : smart_str_appendl(&headers, "Connection: close", sizeof("Connection: close")-1);
3261 : }
3262 :
3263 : }
3264 :
3265 693 : if (headers.len > 0) {
3266 : zval *str_headers;
3267 :
3268 287 : if (!context) {
3269 0 : context = php_stream_context_alloc();
3270 : }
3271 :
3272 287 : smart_str_0(&headers);
3273 287 : MAKE_STD_ZVAL(str_headers);
3274 287 : ZVAL_STRING(str_headers, headers.c, 1);
3275 287 : php_stream_context_set_option(context, "http", "header", str_headers);
3276 287 : smart_str_free(&headers);
3277 287 : zval_ptr_dtor(&str_headers);
3278 : }
3279 :
3280 693 : if (context) {
3281 287 : MAKE_STD_ZVAL(new_context);
3282 287 : php_stream_context_to_zval(context, new_context);
3283 287 : orig_context = php_libxml_switch_context(new_context TSRMLS_CC);
3284 : }
3285 :
3286 693 : SOAP_GLOBAL(error_code) = "WSDL";
3287 :
3288 693 : sdl = load_wsdl(uri TSRMLS_CC);
3289 690 : if (sdl) {
3290 690 : sdl->is_persistent = 0;
3291 : }
3292 :
3293 690 : SOAP_GLOBAL(error_code) = old_error_code;
3294 :
3295 690 : if (context) {
3296 284 : php_libxml_switch_context(orig_context TSRMLS_CC);
3297 284 : zval_ptr_dtor(&new_context);
3298 : }
3299 :
3300 690 : if ((cache_wsdl & WSDL_CACHE_DISK) && key) {
3301 4 : if (sdl) {
3302 4 : add_sdl_to_cache(key, uri, t, sdl TSRMLS_CC);
3303 : }
3304 4 : efree(key);
3305 : }
3306 :
3307 692 : cache_in_memory:
3308 692 : if (cache_wsdl & WSDL_CACHE_MEMORY) {
3309 1 : if (sdl) {
3310 : sdlPtr psdl;
3311 : sdl_cache_bucket p;
3312 :
3313 1 : if (SOAP_GLOBAL(mem_cache) == NULL) {
3314 1 : SOAP_GLOBAL(mem_cache) = malloc(sizeof(HashTable));
3315 1 : zend_hash_init(SOAP_GLOBAL(mem_cache), 0, NULL, delete_psdl, 1);
3316 0 : } else if (SOAP_GLOBAL(cache_limit) > 0 &&
3317 : SOAP_GLOBAL(cache_limit) <= zend_hash_num_elements(SOAP_GLOBAL(mem_cache))) {
3318 : /* in-memory cache overflow */
3319 : sdl_cache_bucket *q;
3320 : HashPosition pos;
3321 0 : time_t latest = t;
3322 0 : char *key = NULL;
3323 : uint key_len;
3324 : ulong idx;
3325 :
3326 0 : for (zend_hash_internal_pointer_reset_ex(SOAP_GLOBAL(mem_cache), &pos);
3327 0 : zend_hash_get_current_data_ex(SOAP_GLOBAL(mem_cache), (void **) &q, &pos) == SUCCESS;
3328 0 : zend_hash_move_forward_ex(SOAP_GLOBAL(mem_cache), &pos)) {
3329 0 : if (q->time < latest) {
3330 0 : latest = q->time;
3331 0 : zend_hash_get_current_key_ex(SOAP_GLOBAL(mem_cache), (zstr*)&key, &key_len, &idx, 0, &pos);
3332 : }
3333 : }
3334 0 : if (key) {
3335 0 : zend_hash_del(SOAP_GLOBAL(mem_cache), key, key_len);
3336 : } else {
3337 0 : return sdl;
3338 : }
3339 : }
3340 :
3341 1 : psdl = make_persistent_sdl(sdl TSRMLS_CC);
3342 1 : psdl->is_persistent = 1;
3343 1 : p.time = t;
3344 1 : p.sdl = psdl;
3345 :
3346 1 : if (SUCCESS == zend_hash_update(SOAP_GLOBAL(mem_cache), uri,
3347 : uri_len+1, (void*)&p, sizeof(sdl_cache_bucket), NULL)) {
3348 : /* remove non-persitent sdl structure */
3349 1 : delete_sdl_impl(sdl);
3350 : /* and replace it with persistent one */
3351 1 : sdl = psdl;
3352 : } else {
3353 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to register persistent entry");
3354 : /* clean up persistent sdl */
3355 0 : delete_psdl(&p);
3356 : /* keep non-persistent sdl and return it */
3357 : }
3358 : }
3359 : }
3360 :
3361 692 : return sdl;
3362 : }
3363 :
3364 : /* Deletes */
3365 : void delete_sdl_impl(void *handle)
3366 684 : {
3367 684 : sdlPtr tmp = (sdlPtr)handle;
3368 :
3369 684 : zend_hash_destroy(&tmp->functions);
3370 684 : if (tmp->source) {
3371 684 : efree(tmp->source);
3372 : }
3373 684 : if (tmp->target_ns) {
3374 684 : efree(tmp->target_ns);
3375 : }
3376 684 : if (tmp->elements) {
3377 264 : zend_hash_destroy(tmp->elements);
3378 264 : efree(tmp->elements);
3379 : }
3380 684 : if (tmp->encoders) {
3381 643 : zend_hash_destroy(tmp->encoders);
3382 643 : efree(tmp->encoders);
3383 : }
3384 684 : if (tmp->types) {
3385 662 : zend_hash_destroy(tmp->types);
3386 662 : efree(tmp->types);
3387 : }
3388 684 : if (tmp->groups) {
3389 2 : zend_hash_destroy(tmp->groups);
3390 2 : efree(tmp->groups);
3391 : }
3392 684 : if (tmp->bindings) {
3393 684 : zend_hash_destroy(tmp->bindings);
3394 684 : efree(tmp->bindings);
3395 : }
3396 684 : if (tmp->requests) {
3397 0 : zend_hash_destroy(tmp->requests);
3398 0 : efree(tmp->requests);
3399 : }
3400 684 : efree(tmp);
3401 684 : }
3402 :
3403 : void delete_sdl(void *handle)
3404 693 : {
3405 693 : sdlPtr tmp = (sdlPtr)handle;
3406 :
3407 693 : if (!tmp->is_persistent) {
3408 683 : delete_sdl_impl(tmp);
3409 : }
3410 693 : }
3411 :
3412 : static void delete_binding(void *data)
3413 833 : {
3414 833 : sdlBindingPtr binding = *((sdlBindingPtr*)data);
3415 :
3416 833 : if (binding->location) {
3417 833 : efree(binding->location);
3418 : }
3419 833 : if (binding->name) {
3420 833 : efree(binding->name);
3421 : }
3422 :
3423 833 : if (binding->bindingType == BINDING_SOAP) {
3424 832 : sdlSoapBindingPtr soapBind = binding->bindingAttributes;
3425 832 : if (soapBind) {
3426 832 : efree(soapBind);
3427 : }
3428 : }
3429 833 : efree(binding);
3430 833 : }
3431 :
3432 : static void delete_binding_persistent(void *data)
3433 1 : {
3434 1 : sdlBindingPtr binding = *((sdlBindingPtr*)data);
3435 :
3436 1 : if (binding->location) {
3437 1 : free(binding->location);
3438 : }
3439 1 : if (binding->name) {
3440 1 : free(binding->name);
3441 : }
3442 :
3443 1 : if (binding->bindingType == BINDING_SOAP) {
3444 1 : sdlSoapBindingPtr soapBind = binding->bindingAttributes;
3445 1 : if (soapBind) {
3446 1 : free(soapBind);
3447 : }
3448 : }
3449 1 : free(binding);
3450 1 : }
3451 :
3452 : static void delete_sdl_soap_binding_function_body(sdlSoapBindingFunctionBody body)
3453 14762 : {
3454 14762 : if (body.ns) {
3455 6597 : efree(body.ns);
3456 : }
3457 14762 : if (body.headers) {
3458 840 : zend_hash_destroy(body.headers);
3459 840 : efree(body.headers);
3460 : }
3461 14762 : }
3462 :
3463 : static void delete_sdl_soap_binding_function_body_persistent(sdlSoapBindingFunctionBody body)
3464 2 : {
3465 2 : if (body.ns) {
3466 2 : free(body.ns);
3467 : }
3468 2 : if (body.headers) {
3469 0 : zend_hash_destroy(body.headers);
3470 0 : free(body.headers);
3471 : }
3472 2 : }
3473 :
3474 : static void delete_function(void *data)
3475 7382 : {
3476 7382 : sdlFunctionPtr function = *((sdlFunctionPtr*)data);
3477 :
3478 7382 : if (function->functionName) {
3479 7382 : efree(function->functionName);
3480 : }
3481 7382 : if (function->requestName) {
3482 7382 : efree(function->requestName);
3483 : }
3484 7382 : if (function->responseName) {
3485 7141 : efree(function->responseName);
3486 : }
3487 7382 : if (function->requestParameters) {
3488 7381 : zend_hash_destroy(function->requestParameters);
3489 7381 : efree(function->requestParameters);
3490 : }
3491 7382 : if (function->responseParameters) {
3492 7141 : zend_hash_destroy(function->responseParameters);
3493 7141 : efree(function->responseParameters);
3494 : }
3495 7382 : if (function->faults) {
3496 684 : zend_hash_destroy(function->faults);
3497 684 : efree(function->faults);
3498 : }
3499 :
3500 7382 : if (function->bindingAttributes &&
3501 : function->binding && function->binding->bindingType == BINDING_SOAP) {
3502 7381 : sdlSoapBindingFunctionPtr soapFunction = function->bindingAttributes;
3503 7381 : if (soapFunction->soapAction) {
3504 5813 : efree(soapFunction->soapAction);
3505 : }
3506 7381 : delete_sdl_soap_binding_function_body(soapFunction->input);
3507 7381 : delete_sdl_soap_binding_function_body(soapFunction->output);
3508 7381 : efree(soapFunction);
3509 : }
3510 7382 : efree(function);
3511 7382 : }
3512 :
3513 : static void delete_function_persistent(void *data)
3514 1 : {
3515 1 : sdlFunctionPtr function = *((sdlFunctionPtr*)data);
3516 :
3517 1 : if (function->functionName) {
3518 1 : free(function->functionName);
3519 : }
3520 1 : if (function->requestName) {
3521 1 : free(function->requestName);
3522 : }
3523 1 : if (function->responseName) {
3524 1 : free(function->responseName);
3525 : }
3526 1 : if (function->requestParameters) {
3527 1 : zend_hash_destroy(function->requestParameters);
3528 1 : free(function->requestParameters);
3529 : }
3530 1 : if (function->responseParameters) {
3531 1 : zend_hash_destroy(function->responseParameters);
3532 1 : free(function->responseParameters);
3533 : }
3534 1 : if (function->faults) {
3535 0 : zend_hash_destroy(function->faults);
3536 0 : free(function->faults);
3537 : }
3538 :
3539 1 : if (function->bindingAttributes &&
3540 : function->binding && function->binding->bindingType == BINDING_SOAP) {
3541 1 : sdlSoapBindingFunctionPtr soapFunction = function->bindingAttributes;
3542 1 : if (soapFunction->soapAction) {
3543 1 : free(soapFunction->soapAction);
3544 : }
3545 1 : delete_sdl_soap_binding_function_body_persistent(soapFunction->input);
3546 1 : delete_sdl_soap_binding_function_body_persistent(soapFunction->output);
3547 1 : free(soapFunction);
3548 : }
3549 1 : free(function);
3550 1 : }
3551 :
3552 : static void delete_parameter(void *data)
3553 15606 : {
3554 15606 : sdlParamPtr param = *((sdlParamPtr*)data);
3555 15606 : if (param->paramName) {
3556 15606 : efree(param->paramName);
3557 : }
3558 15606 : efree(param);
3559 15606 : }
3560 :
3561 : static void delete_parameter_persistent(void *data)
3562 4 : {
3563 4 : sdlParamPtr param = *((sdlParamPtr*)data);
3564 4 : if (param->paramName) {
3565 4 : free(param->paramName);
3566 : }
3567 4 : free(param);
3568 4 : }
3569 :
3570 : static void delete_header(void *data)
3571 1533 : {
3572 1533 : sdlSoapBindingFunctionHeaderPtr hdr = *((sdlSoapBindingFunctionHeaderPtr*)data);
3573 1533 : if (hdr->name) {
3574 1533 : efree(hdr->name);
3575 : }
3576 1533 : if (hdr->ns) {
3577 1526 : efree(hdr->ns);
3578 : }
3579 1533 : if (hdr->headerfaults) {
3580 68 : zend_hash_destroy(hdr->headerfaults);
3581 68 : efree(hdr->headerfaults);
3582 : }
3583 1533 : efree(hdr);
3584 1533 : }
3585 :
3586 : static void delete_header_persistent(void *data)
3587 0 : {
3588 0 : sdlSoapBindingFunctionHeaderPtr hdr = *((sdlSoapBindingFunctionHeaderPtr*)data);
3589 0 : if (hdr->name) {
3590 0 : free(hdr->name);
3591 : }
3592 0 : if (hdr->ns) {
3593 0 : free(hdr->ns);
3594 : }
3595 0 : if (hdr->headerfaults) {
3596 0 : zend_hash_destroy(hdr->headerfaults);
3597 0 : free(hdr->headerfaults);
3598 : }
3599 0 : free(hdr);
3600 0 : }
3601 :
3602 : static void delete_fault(void *data)
3603 1212 : {
3604 1212 : sdlFaultPtr fault = *((sdlFaultPtr*)data);
3605 1212 : if (fault->name) {
3606 1212 : efree(fault->name);
3607 : }
3608 1212 : if (fault->details) {
3609 1212 : zend_hash_destroy(fault->details);
3610 1212 : efree(fault->details);
3611 : }
3612 1212 : if (fault->bindingAttributes) {
3613 1178 : sdlSoapBindingFunctionFaultPtr binding = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
3614 :
3615 1178 : if (binding->ns) {
3616 610 : efree(binding->ns);
3617 : }
3618 1178 : efree(fault->bindingAttributes);
3619 : }
3620 1212 : efree(fault);
3621 1212 : }
3622 :
3623 : static void delete_fault_persistent(void *data)
3624 0 : {
3625 0 : sdlFaultPtr fault = *((sdlFaultPtr*)data);
3626 0 : if (fault->name) {
3627 0 : free(fault->name);
3628 : }
3629 0 : if (fault->details) {
3630 0 : zend_hash_destroy(fault->details);
3631 0 : free(fault->details);
3632 : }
3633 0 : if (fault->bindingAttributes) {
3634 0 : sdlSoapBindingFunctionFaultPtr binding = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
3635 :
3636 0 : if (binding->ns) {
3637 0 : free(binding->ns);
3638 : }
3639 0 : free(fault->bindingAttributes);
3640 : }
3641 0 : free(fault);
3642 0 : }
3643 :
3644 : static void delete_document(void *doc_ptr)
3645 713 : {
3646 713 : xmlDocPtr doc = *((xmlDocPtr*)doc_ptr);
3647 713 : xmlFreeDoc(doc);
3648 713 : }
3649 :
|