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