1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2014 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 *parameter);
44 static void delete_parameter_persistent(void *parameter);
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 php_ignore_value(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 if (zend_hash_get_current_key_ex(attr->extraAttributes, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2648 pextra = malloc(sizeof(sdlExtraAttribute));
2649 memset(pextra, 0, sizeof(sdlExtraAttribute));
2650
2651 if ((*tmp)->ns) {
2652 pextra->ns = strdup((*tmp)->ns);
2653 }
2654 if ((*tmp)->val) {
2655 pextra->val = strdup((*tmp)->val);
2656 }
2657
2658 zend_hash_add(pattr->extraAttributes, key, key_len, (void*)&pextra, sizeof(sdlExtraAttributePtr), NULL);
2659 }
2660
2661 zend_hash_move_forward(attr->extraAttributes);
2662 }
2663 }
2664
2665 return pattr;
2666 }
2667
2668
make_persistent_sdl_model(sdlContentModelPtr model,HashTable * ptr_map,HashTable * bp_types,HashTable * bp_encoders)2669 static sdlContentModelPtr make_persistent_sdl_model(sdlContentModelPtr model, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
2670 {
2671 sdlContentModelPtr pmodel;
2672 sdlContentModelPtr *tmp, pcontent;
2673
2674 pmodel = malloc(sizeof(sdlContentModel));
2675 memset(pmodel, 0, sizeof(sdlContentModel));
2676 *pmodel = *model;
2677
2678 switch (pmodel->kind) {
2679 case XSD_CONTENT_ELEMENT:
2680 if (pmodel->u.element) {
2681 make_persistent_sdl_type_ref(&pmodel->u.element, ptr_map, bp_types);
2682 }
2683 break;
2684
2685 case XSD_CONTENT_SEQUENCE:
2686 case XSD_CONTENT_ALL:
2687 case XSD_CONTENT_CHOICE:
2688 pmodel->u.content = malloc(sizeof(HashTable));
2689 zend_hash_init(pmodel->u.content, zend_hash_num_elements(model->u.content), NULL, delete_model_persistent, 1);
2690
2691 zend_hash_internal_pointer_reset(model->u.content);
2692 while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
2693 pcontent = make_persistent_sdl_model(*tmp, ptr_map, bp_types, bp_encoders);
2694 zend_hash_next_index_insert(pmodel->u.content, (void*)&pcontent, sizeof(sdlContentModelPtr), NULL);
2695 zend_hash_move_forward(model->u.content);
2696 }
2697 break;
2698
2699 case XSD_CONTENT_GROUP_REF:
2700 if (pmodel->u.group_ref) {
2701 pmodel->u.group_ref = strdup(pmodel->u.group_ref);
2702 }
2703 break;
2704
2705 case XSD_CONTENT_GROUP:
2706 if (pmodel->u.group) {
2707 make_persistent_sdl_type_ref(&pmodel->u.group, ptr_map, bp_types);
2708 }
2709 break;
2710
2711 default:
2712 break;
2713 }
2714
2715 return pmodel;
2716 }
2717
2718
make_persistent_sdl_type(sdlTypePtr type,HashTable * ptr_map,HashTable * bp_types,HashTable * bp_encoders)2719 static sdlTypePtr make_persistent_sdl_type(sdlTypePtr type, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
2720 {
2721 ulong index;
2722 char *key;
2723 uint key_len;
2724 sdlTypePtr ptype = NULL;
2725
2726 ptype = malloc(sizeof(sdlType));
2727 memset(ptype, 0, sizeof(sdlType));
2728
2729 *ptype = *type;
2730
2731 if (ptype->name) {
2732 ptype->name = strdup(ptype->name);
2733 }
2734 if (ptype->namens) {
2735 ptype->namens = strdup(ptype->namens);
2736 }
2737 if (ptype->def) {
2738 ptype->def = strdup(ptype->def);
2739 }
2740 if (ptype->fixed) {
2741 ptype->fixed = strdup(ptype->fixed);
2742 }
2743 if (ptype->ref) {
2744 ptype->ref = strdup(ptype->ref);
2745 }
2746
2747 /* we do not want to process defaultEncoding's here */
2748 if (ptype->encode) {
2749 make_persistent_sdl_encoder_ref(&ptype->encode, ptr_map, bp_encoders);
2750 }
2751
2752 if (ptype->restrictions) {
2753 ptype->restrictions = malloc(sizeof(sdlRestrictions));
2754 memset(ptype->restrictions, 0, sizeof(sdlRestrictions));
2755 *ptype->restrictions = *type->restrictions;
2756
2757 if (ptype->restrictions->minExclusive) {
2758 make_persistent_restriction_int(&ptype->restrictions->minExclusive);
2759 }
2760 if (ptype->restrictions->maxExclusive) {
2761 make_persistent_restriction_int(&ptype->restrictions->maxExclusive);
2762 }
2763 if (ptype->restrictions->minInclusive) {
2764 make_persistent_restriction_int(&ptype->restrictions->minInclusive);
2765 }
2766 if (ptype->restrictions->maxInclusive) {
2767 make_persistent_restriction_int(&ptype->restrictions->maxInclusive);
2768 }
2769 if (ptype->restrictions->totalDigits) {
2770 make_persistent_restriction_int(&ptype->restrictions->totalDigits);
2771 }
2772 if (ptype->restrictions->fractionDigits) {
2773 make_persistent_restriction_int(&ptype->restrictions->fractionDigits);
2774 }
2775 if (ptype->restrictions->length) {
2776 make_persistent_restriction_int(&ptype->restrictions->length);
2777 }
2778 if (ptype->restrictions->minLength) {
2779 make_persistent_restriction_int(&ptype->restrictions->minLength);
2780 }
2781 if (ptype->restrictions->maxLength) {
2782 make_persistent_restriction_int(&ptype->restrictions->maxLength);
2783 }
2784 if (ptype->restrictions->whiteSpace) {
2785 make_persistent_restriction_char(&ptype->restrictions->whiteSpace);
2786 }
2787 if (ptype->restrictions->pattern) {
2788 make_persistent_restriction_char(&ptype->restrictions->pattern);
2789 }
2790
2791 if (type->restrictions->enumeration) {
2792 sdlRestrictionCharPtr tmp;
2793
2794 ptype->restrictions->enumeration = malloc(sizeof(HashTable));
2795 zend_hash_init(ptype->restrictions->enumeration, zend_hash_num_elements(type->restrictions->enumeration), NULL, delete_restriction_var_char_persistent, 1);
2796 zend_hash_copy(ptype->restrictions->enumeration, type->restrictions->enumeration, make_persistent_restriction_char, (void*)&tmp, sizeof(sdlRestrictionCharPtr));
2797 }
2798 }
2799
2800 if (ptype->elements) {
2801 sdlTypePtr *tmp, pelem;
2802
2803 ptype->elements = malloc(sizeof(HashTable));
2804 zend_hash_init(ptype->elements, zend_hash_num_elements(type->elements), NULL, delete_type_persistent, 1);
2805
2806 zend_hash_internal_pointer_reset(type->elements);
2807 while (zend_hash_get_current_data(type->elements, (void **)&tmp) == SUCCESS) {
2808 pelem = make_persistent_sdl_type(*tmp, ptr_map, bp_types, bp_encoders);
2809 if (zend_hash_get_current_key_ex(type->elements, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2810 zend_hash_add(ptype->elements, key, key_len, (void*)&pelem, sizeof(sdlTypePtr), NULL);
2811 } else {
2812 zend_hash_next_index_insert(ptype->elements, (void*)&pelem, sizeof(sdlTypePtr), NULL);
2813 }
2814 zend_hash_add(ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pelem, sizeof(sdlTypePtr), NULL);
2815 zend_hash_move_forward(type->elements);
2816 }
2817 }
2818
2819 if (ptype->attributes) {
2820 sdlAttributePtr *tmp, pattr;
2821
2822 ptype->attributes = malloc(sizeof(HashTable));
2823 zend_hash_init(ptype->attributes, zend_hash_num_elements(type->attributes), NULL, delete_attribute_persistent, 1);
2824
2825 zend_hash_internal_pointer_reset(type->attributes);
2826 while (zend_hash_get_current_data(type->attributes, (void **)&tmp) == SUCCESS) {
2827 pattr = make_persistent_sdl_attribute(*tmp, ptr_map, bp_types, bp_encoders);
2828 if (zend_hash_get_current_key_ex(type->attributes, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2829 zend_hash_add(ptype->attributes, key, key_len, (void*)&pattr, sizeof(sdlAttributePtr), NULL);
2830 } else {
2831 zend_hash_next_index_insert(ptype->attributes, (void*)&pattr, sizeof(sdlAttributePtr), NULL);
2832 }
2833 zend_hash_move_forward(type->attributes);
2834 }
2835 }
2836
2837 if (type->model) {
2838 ptype->model = make_persistent_sdl_model(ptype->model, ptr_map, bp_types, bp_encoders);
2839 }
2840
2841 return ptype;
2842 }
2843
make_persistent_sdl_encoder(encodePtr enc,HashTable * ptr_map,HashTable * bp_types,HashTable * bp_encoders)2844 static encodePtr make_persistent_sdl_encoder(encodePtr enc, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
2845 {
2846 encodePtr penc = NULL;
2847
2848 penc = malloc(sizeof(encode));
2849 memset(penc, 0, sizeof(encode));
2850
2851 *penc = *enc;
2852
2853 if (penc->details.type_str) {
2854 penc->details.type_str = strdup(penc->details.type_str);
2855 }
2856 if (penc->details.ns) {
2857 penc->details.ns = strdup(penc->details.ns);
2858 }
2859
2860 if (penc->details.sdl_type) {
2861 make_persistent_sdl_type_ref(&penc->details.sdl_type, ptr_map, bp_types);
2862 }
2863
2864 return penc;
2865 }
2866
make_persistent_sdl_binding(sdlBindingPtr bind,HashTable * ptr_map)2867 static sdlBindingPtr make_persistent_sdl_binding(sdlBindingPtr bind, HashTable *ptr_map)
2868 {
2869 sdlBindingPtr pbind = NULL;
2870
2871 pbind = malloc(sizeof(sdlBinding));
2872 memset(pbind, 0, sizeof(sdlBinding));
2873
2874 *pbind = *bind;
2875
2876 if (pbind->name) {
2877 pbind->name = strdup(pbind->name);
2878 }
2879 if (pbind->location) {
2880 pbind->location = strdup(pbind->location);
2881 }
2882
2883 if (pbind->bindingType == BINDING_SOAP && pbind->bindingAttributes) {
2884 sdlSoapBindingPtr soap_binding;
2885
2886 soap_binding = malloc(sizeof(sdlSoapBinding));
2887 memset(soap_binding, 0, sizeof(sdlSoapBinding));
2888 *soap_binding = *(sdlSoapBindingPtr)pbind->bindingAttributes;
2889 pbind->bindingAttributes = soap_binding;
2890 }
2891
2892 return pbind;
2893 }
2894
make_persistent_sdl_function(sdlFunctionPtr func,HashTable * ptr_map)2895 static sdlFunctionPtr make_persistent_sdl_function(sdlFunctionPtr func, HashTable *ptr_map)
2896 {
2897 sdlFunctionPtr pfunc = NULL;
2898
2899 pfunc = malloc(sizeof(sdlFunction));
2900 memset(pfunc, 0, sizeof(sdlFunction));
2901
2902 *pfunc = *func;
2903
2904 if (pfunc->functionName) {
2905 pfunc->functionName = strdup(pfunc->functionName);
2906 }
2907 if (pfunc->requestName) {
2908 pfunc->requestName = strdup(pfunc->requestName);
2909 }
2910 if (pfunc->responseName) {
2911 pfunc->responseName = strdup(pfunc->responseName);
2912 }
2913
2914 if (pfunc->binding) {
2915 sdlBindingPtr *tmp;
2916
2917 if (zend_hash_find(ptr_map, (char*)&pfunc->binding, sizeof(pfunc->binding), (void**)&tmp) == FAILURE) {
2918 assert(0);
2919 }
2920 pfunc->binding = *tmp;
2921
2922 if (pfunc->binding->bindingType == BINDING_SOAP && pfunc->bindingAttributes) {
2923 sdlSoapBindingFunctionPtr soap_binding;
2924
2925 soap_binding = malloc(sizeof(sdlSoapBindingFunction));
2926 memset(soap_binding, 0, sizeof(sdlSoapBindingFunction));
2927 *soap_binding = *(sdlSoapBindingFunctionPtr)pfunc->bindingAttributes;
2928 if (soap_binding->soapAction) {
2929 soap_binding->soapAction = strdup(soap_binding->soapAction);
2930 }
2931 make_persistent_sdl_soap_body(&soap_binding->input, ptr_map);
2932 make_persistent_sdl_soap_body(&soap_binding->output, ptr_map);
2933 pfunc->bindingAttributes = soap_binding;
2934 }
2935
2936 if (pfunc->requestParameters) {
2937 pfunc->requestParameters = make_persistent_sdl_parameters(pfunc->requestParameters, ptr_map);
2938 }
2939 if (pfunc->responseParameters) {
2940 pfunc->responseParameters = make_persistent_sdl_parameters(pfunc->responseParameters, ptr_map);
2941 }
2942 if (pfunc->faults) {
2943 pfunc->faults = make_persistent_sdl_function_faults(pfunc, pfunc->faults, ptr_map);
2944 }
2945 }
2946
2947 return pfunc;
2948 }
2949
make_persistent_sdl(sdlPtr sdl TSRMLS_DC)2950 static sdlPtr make_persistent_sdl(sdlPtr sdl TSRMLS_DC)
2951 {
2952 sdlPtr psdl = NULL;
2953 HashTable ptr_map;
2954 HashTable bp_types, bp_encoders;
2955 ulong index;
2956 char *key;
2957 uint key_len;
2958
2959 zend_hash_init(&bp_types, 0, NULL, NULL, 0);
2960 zend_hash_init(&bp_encoders, 0, NULL, NULL, 0);
2961 zend_hash_init(&ptr_map, 0, NULL, NULL, 0);
2962
2963 psdl = malloc(sizeof(*sdl));
2964 memset(psdl, 0, sizeof(*sdl));
2965
2966 if (sdl->source) {
2967 psdl->source = strdup(sdl->source);
2968 }
2969 if (sdl->target_ns) {
2970 psdl->target_ns = strdup(sdl->target_ns);
2971 }
2972
2973 if (sdl->groups) {
2974 sdlTypePtr *tmp;
2975 sdlTypePtr ptype;
2976
2977 psdl->groups = malloc(sizeof(HashTable));
2978 zend_hash_init(psdl->groups, zend_hash_num_elements(sdl->groups), NULL, delete_type_persistent, 1);
2979
2980 zend_hash_internal_pointer_reset(sdl->groups);
2981 while (zend_hash_get_current_data(sdl->groups, (void **)&tmp) == SUCCESS) {
2982 ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
2983 if (zend_hash_get_current_key_ex(sdl->groups, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2984 zend_hash_add(psdl->groups, key, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2985 } else {
2986 zend_hash_next_index_insert(psdl->groups, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2987 }
2988 zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
2989 zend_hash_move_forward(sdl->groups);
2990 }
2991 }
2992
2993 if (sdl->types) {
2994 sdlTypePtr *tmp;
2995 sdlTypePtr ptype;
2996
2997 psdl->types = malloc(sizeof(HashTable));
2998 zend_hash_init(psdl->types, zend_hash_num_elements(sdl->types), NULL, delete_type_persistent, 1);
2999
3000 zend_hash_internal_pointer_reset(sdl->types);
3001 while (zend_hash_get_current_data(sdl->types, (void **)&tmp) == SUCCESS) {
3002 ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
3003 if (zend_hash_get_current_key_ex(sdl->types, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
3004 zend_hash_add(psdl->types, key, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
3005 } else {
3006 zend_hash_next_index_insert(psdl->types, (void*)&ptype, sizeof(sdlTypePtr), NULL);
3007 }
3008 zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
3009 zend_hash_move_forward(sdl->types);
3010 }
3011 }
3012
3013 if (sdl->elements) {
3014 sdlTypePtr *tmp;
3015 sdlTypePtr ptype;
3016
3017 psdl->elements = malloc(sizeof(HashTable));
3018 zend_hash_init(psdl->elements, zend_hash_num_elements(sdl->elements), NULL, delete_type_persistent, 1);
3019
3020 zend_hash_internal_pointer_reset(sdl->elements);
3021 while (zend_hash_get_current_data(sdl->elements, (void **)&tmp) == SUCCESS) {
3022 ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
3023 if (zend_hash_get_current_key_ex(sdl->elements, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
3024 zend_hash_add(psdl->elements, key, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
3025 } else {
3026 zend_hash_next_index_insert(psdl->elements, (void*)&ptype, sizeof(sdlTypePtr), NULL);
3027 }
3028 zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
3029 zend_hash_move_forward(sdl->elements);
3030 }
3031 }
3032
3033 if (sdl->encoders) {
3034 encodePtr *tmp;
3035 encodePtr penc;
3036
3037 psdl->encoders = malloc(sizeof(HashTable));
3038 zend_hash_init(psdl->encoders, zend_hash_num_elements(sdl->encoders), NULL, delete_encoder_persistent, 1);
3039
3040 zend_hash_internal_pointer_reset(sdl->encoders);
3041 while (zend_hash_get_current_data(sdl->encoders, (void **)&tmp) == SUCCESS) {
3042 penc = make_persistent_sdl_encoder(*tmp, &ptr_map, &bp_types, &bp_encoders);
3043 if (zend_hash_get_current_key_ex(sdl->encoders, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
3044 zend_hash_add(psdl->encoders, key, key_len, (void*)&penc, sizeof(encodePtr), NULL);
3045 } else {
3046 zend_hash_next_index_insert(psdl->encoders, (void*)&penc, sizeof(encodePtr), NULL);
3047 }
3048 zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&penc, sizeof(encodePtr), NULL);
3049 zend_hash_move_forward(sdl->encoders);
3050 }
3051 }
3052
3053 /* do backpatching here */
3054 if (zend_hash_num_elements(&bp_types)) {
3055 sdlTypePtr **tmp, *ptype = NULL;
3056
3057 zend_hash_internal_pointer_reset(&bp_types);
3058 while (zend_hash_get_current_data(&bp_types, (void**)&tmp) == SUCCESS) {
3059 if (zend_hash_find(&ptr_map, (char*)(*tmp), sizeof(**tmp), (void**)&ptype) == FAILURE) {
3060 assert(0);
3061 }
3062 **tmp = *ptype;
3063 zend_hash_move_forward(&bp_types);
3064 }
3065 }
3066 if (zend_hash_num_elements(&bp_encoders)) {
3067 encodePtr **tmp, *penc = NULL;
3068
3069 zend_hash_internal_pointer_reset(&bp_encoders);
3070 while (zend_hash_get_current_data(&bp_encoders, (void**)&tmp) == SUCCESS) {
3071 if (zend_hash_find(&ptr_map, (char*)(*tmp), sizeof(**tmp), (void**)&penc) == FAILURE) {
3072 assert(0);
3073 }
3074 **tmp = *penc;
3075 zend_hash_move_forward(&bp_encoders);
3076 }
3077 }
3078
3079
3080 if (sdl->bindings) {
3081 sdlBindingPtr *tmp;
3082 sdlBindingPtr pbind;
3083
3084 psdl->bindings = malloc(sizeof(HashTable));
3085 zend_hash_init(psdl->bindings, zend_hash_num_elements(sdl->bindings), NULL, delete_binding_persistent, 1);
3086
3087 zend_hash_internal_pointer_reset(sdl->bindings);
3088 while (zend_hash_get_current_data(sdl->bindings, (void **)&tmp) == SUCCESS) {
3089 pbind = make_persistent_sdl_binding(*tmp, &ptr_map);
3090 if (zend_hash_get_current_key_ex(sdl->bindings, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
3091 zend_hash_add(psdl->bindings, key, key_len, (void*)&pbind, sizeof(sdlBindingPtr), NULL);
3092 } else {
3093 zend_hash_next_index_insert(psdl->bindings, (void*)&pbind, sizeof(sdlBindingPtr), NULL);
3094 }
3095 zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pbind, sizeof(sdlBindingPtr), NULL);
3096 zend_hash_move_forward(sdl->bindings);
3097 }
3098 }
3099
3100 zend_hash_init(&psdl->functions, zend_hash_num_elements(&sdl->functions), NULL, delete_function_persistent, 1);
3101 if (zend_hash_num_elements(&sdl->functions)) {
3102 sdlFunctionPtr *tmp;
3103 sdlFunctionPtr pfunc;
3104
3105 zend_hash_internal_pointer_reset(&sdl->functions);
3106 while (zend_hash_get_current_data(&sdl->functions, (void **)&tmp) == SUCCESS) {
3107 pfunc = make_persistent_sdl_function(*tmp, &ptr_map);
3108 if (zend_hash_get_current_key_ex(&sdl->functions, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
3109 zend_hash_add(&psdl->functions, key, key_len, (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
3110 } else {
3111 zend_hash_next_index_insert(&psdl->functions, (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
3112 }
3113 zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
3114 zend_hash_move_forward(&sdl->functions);
3115 }
3116 }
3117
3118 if (sdl->requests) {
3119 sdlFunctionPtr *tmp;
3120 sdlFunctionPtr *preq;
3121
3122 psdl->requests = malloc(sizeof(HashTable));
3123 zend_hash_init(psdl->requests, zend_hash_num_elements(sdl->requests), NULL, NULL, 1);
3124
3125 zend_hash_internal_pointer_reset(sdl->requests);
3126 while (zend_hash_get_current_data(sdl->requests, (void **)&tmp) == SUCCESS) {
3127 if (zend_hash_find(&ptr_map, (char*)tmp, sizeof(*tmp), (void**)&preq) == FAILURE) {
3128 assert(0);
3129 }
3130 *tmp = *preq;
3131 if (zend_hash_get_current_key_ex(sdl->requests, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
3132 zend_hash_add(psdl->requests, key, key_len, (void*)&preq, sizeof(sdlFunctionPtr), NULL);
3133 }
3134 zend_hash_move_forward(sdl->requests);
3135 }
3136 }
3137
3138 zend_hash_destroy(&ptr_map);
3139 zend_hash_destroy(&bp_encoders);
3140 zend_hash_destroy(&bp_types);
3141
3142 return psdl;
3143 }
3144
3145 typedef struct _sdl_cache_bucket {
3146 sdlPtr sdl;
3147 time_t time;
3148 } sdl_cache_bucket;
3149
delete_psdl(void * data)3150 static void delete_psdl(void *data)
3151 {
3152 sdl_cache_bucket *p = (sdl_cache_bucket*)data;
3153 sdlPtr tmp = p->sdl;
3154
3155 zend_hash_destroy(&tmp->functions);
3156 if (tmp->source) {
3157 free(tmp->source);
3158 }
3159 if (tmp->target_ns) {
3160 free(tmp->target_ns);
3161 }
3162 if (tmp->elements) {
3163 zend_hash_destroy(tmp->elements);
3164 free(tmp->elements);
3165 }
3166 if (tmp->encoders) {
3167 zend_hash_destroy(tmp->encoders);
3168 free(tmp->encoders);
3169 }
3170 if (tmp->types) {
3171 zend_hash_destroy(tmp->types);
3172 free(tmp->types);
3173 }
3174 if (tmp->groups) {
3175 zend_hash_destroy(tmp->groups);
3176 free(tmp->groups);
3177 }
3178 if (tmp->bindings) {
3179 zend_hash_destroy(tmp->bindings);
3180 free(tmp->bindings);
3181 }
3182 if (tmp->requests) {
3183 zend_hash_destroy(tmp->requests);
3184 free(tmp->requests);
3185 }
3186 free(tmp);
3187 }
3188
get_sdl(zval * this_ptr,char * uri,long cache_wsdl TSRMLS_DC)3189 sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
3190 {
3191 char fn[MAXPATHLEN];
3192 sdlPtr sdl = NULL;
3193 char* old_error_code = SOAP_GLOBAL(error_code);
3194 int uri_len = 0;
3195 php_stream_context *context=NULL;
3196 zval **tmp, **proxy_host, **proxy_port, *orig_context = NULL, *new_context = NULL;
3197 smart_str headers = {0};
3198 char* key = NULL;
3199 time_t t = time(0);
3200 zend_bool has_proxy_authorization = 0;
3201 zend_bool has_authorization = 0;
3202
3203 if (strchr(uri,':') != NULL || IS_ABSOLUTE_PATH(uri, uri_len)) {
3204 uri_len = strlen(uri);
3205 } else if (VCWD_REALPATH(uri, fn) == NULL) {
3206 cache_wsdl = WSDL_CACHE_NONE;
3207 } else {
3208 uri = fn;
3209 uri_len = strlen(uri);
3210 }
3211
3212 if ((cache_wsdl & WSDL_CACHE_MEMORY) && SOAP_GLOBAL(mem_cache)) {
3213 sdl_cache_bucket *p;
3214
3215 if (SUCCESS == zend_hash_find(SOAP_GLOBAL(mem_cache), uri, uri_len+1, (void*)&p)) {
3216 if (p->time < t - SOAP_GLOBAL(cache_ttl)) {
3217 /* in-memory cache entry is expired */
3218 zend_hash_del(&EG(persistent_list), uri, uri_len+1);
3219 } else {
3220 return p->sdl;
3221 }
3222 }
3223 }
3224
3225 if ((cache_wsdl & WSDL_CACHE_DISK) && (uri_len < MAXPATHLEN)) {
3226 time_t t = time(0);
3227 char md5str[33];
3228 PHP_MD5_CTX context;
3229 unsigned char digest[16];
3230 int len = strlen(SOAP_GLOBAL(cache_dir));
3231 time_t cached;
3232 char *user = php_get_current_user(TSRMLS_C);
3233 int user_len = user ? strlen(user) + 1 : 0;
3234
3235 md5str[0] = '\0';
3236 PHP_MD5Init(&context);
3237 PHP_MD5Update(&context, (unsigned char*)uri, uri_len);
3238 PHP_MD5Final(digest, &context);
3239 make_digest(md5str, digest);
3240 key = emalloc(len+sizeof("/wsdl-")-1+user_len+sizeof(md5str));
3241 memcpy(key,SOAP_GLOBAL(cache_dir),len);
3242 memcpy(key+len,"/wsdl-",sizeof("/wsdl-")-1);
3243 len += sizeof("/wsdl-")-1;
3244 if (user_len) {
3245 memcpy(key+len, user, user_len-1);
3246 len += user_len-1;
3247 key[len++] = '-';
3248 }
3249 memcpy(key+len,md5str,sizeof(md5str));
3250
3251 if ((sdl = get_sdl_from_cache(key, uri, t-SOAP_GLOBAL(cache_ttl), &cached TSRMLS_CC)) != NULL) {
3252 t = cached;
3253 efree(key);
3254 goto cache_in_memory;
3255 }
3256 }
3257
3258 if (SUCCESS == zend_hash_find(Z_OBJPROP_P(this_ptr),
3259 "_stream_context", sizeof("_stream_context"), (void**)&tmp)) {
3260 context = php_stream_context_from_zval(*tmp, 0);
3261 } else {
3262 context = php_stream_context_alloc(TSRMLS_C);
3263 }
3264
3265 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_user_agent", sizeof("_user_agent"), (void **) &tmp) == SUCCESS &&
3266 Z_TYPE_PP(tmp) == IS_STRING && Z_STRLEN_PP(tmp) > 0) {
3267 smart_str_appends(&headers, "User-Agent: ");
3268 smart_str_appends(&headers, Z_STRVAL_PP(tmp));
3269 smart_str_appends(&headers, "\r\n");
3270 }
3271
3272 if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_host", sizeof("_proxy_host"), (void **) &proxy_host) == SUCCESS &&
3273 Z_TYPE_PP(proxy_host) == IS_STRING &&
3274 zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_port", sizeof("_proxy_port"), (void **) &proxy_port) == SUCCESS &&
3275 Z_TYPE_PP(proxy_port) == IS_LONG) {
3276 zval str_port, *str_proxy;
3277 smart_str proxy = {0};
3278 str_port = **proxy_port;
3279 zval_copy_ctor(&str_port);
3280 convert_to_string(&str_port);
3281 smart_str_appends(&proxy,"tcp://");
3282 smart_str_appends(&proxy,Z_STRVAL_PP(proxy_host));
3283 smart_str_appends(&proxy,":");
3284 smart_str_appends(&proxy,Z_STRVAL(str_port));
3285 smart_str_0(&proxy);
3286 zval_dtor(&str_port);
3287 MAKE_STD_ZVAL(str_proxy);
3288 ZVAL_STRING(str_proxy, proxy.c, 1);
3289 smart_str_free(&proxy);
3290
3291 if (!context) {
3292 context = php_stream_context_alloc(TSRMLS_C);
3293 }
3294 php_stream_context_set_option(context, "http", "proxy", str_proxy);
3295 zval_ptr_dtor(&str_proxy);
3296
3297 if (uri_len < sizeof("https://")-1 ||
3298 strncasecmp(uri, "https://", sizeof("https://")-1) != 0) {
3299 MAKE_STD_ZVAL(str_proxy);
3300 ZVAL_BOOL(str_proxy, 1);
3301 php_stream_context_set_option(context, "http", "request_fulluri", str_proxy);
3302 zval_ptr_dtor(&str_proxy);
3303 }
3304
3305 has_proxy_authorization = proxy_authentication(this_ptr, &headers TSRMLS_CC);
3306 }
3307
3308 has_authorization = basic_authentication(this_ptr, &headers TSRMLS_CC);
3309
3310 /* Use HTTP/1.1 with "Connection: close" by default */
3311 if (php_stream_context_get_option(context, "http", "protocol_version", &tmp) == FAILURE) {
3312 zval *http_version;
3313 MAKE_STD_ZVAL(http_version);
3314 ZVAL_DOUBLE(http_version, 1.1);
3315 php_stream_context_set_option(context, "http", "protocol_version", http_version);
3316 zval_ptr_dtor(&http_version);
3317 smart_str_appendl(&headers, "Connection: close\r\n", sizeof("Connection: close\r\n")-1);
3318 }
3319
3320 if (headers.len > 0) {
3321 zval *str_headers;
3322
3323 if (!context) {
3324 context = php_stream_context_alloc(TSRMLS_C);
3325 } else {
3326 http_context_headers(context, has_authorization, has_proxy_authorization, 0, &headers TSRMLS_CC);
3327 }
3328
3329 smart_str_0(&headers);
3330 MAKE_STD_ZVAL(str_headers);
3331 ZVAL_STRING(str_headers, headers.c, 1);
3332 php_stream_context_set_option(context, "http", "header", str_headers);
3333 smart_str_free(&headers);
3334 zval_ptr_dtor(&str_headers);
3335 }
3336
3337 if (context) {
3338 MAKE_STD_ZVAL(new_context);
3339 php_stream_context_to_zval(context, new_context);
3340 orig_context = php_libxml_switch_context(new_context TSRMLS_CC);
3341 }
3342
3343 SOAP_GLOBAL(error_code) = "WSDL";
3344
3345 sdl = load_wsdl(this_ptr, uri TSRMLS_CC);
3346 if (sdl) {
3347 sdl->is_persistent = 0;
3348 }
3349
3350 SOAP_GLOBAL(error_code) = old_error_code;
3351
3352 if (context) {
3353 php_libxml_switch_context(orig_context TSRMLS_CC);
3354 zval_ptr_dtor(&new_context);
3355 }
3356
3357 if ((cache_wsdl & WSDL_CACHE_DISK) && key) {
3358 if (sdl) {
3359 add_sdl_to_cache(key, uri, t, sdl TSRMLS_CC);
3360 }
3361 efree(key);
3362 }
3363
3364 cache_in_memory:
3365 if (cache_wsdl & WSDL_CACHE_MEMORY) {
3366 if (sdl) {
3367 sdlPtr psdl;
3368 sdl_cache_bucket p;
3369
3370 if (SOAP_GLOBAL(mem_cache) == NULL) {
3371 SOAP_GLOBAL(mem_cache) = malloc(sizeof(HashTable));
3372 zend_hash_init(SOAP_GLOBAL(mem_cache), 0, NULL, delete_psdl, 1);
3373 } else if (SOAP_GLOBAL(cache_limit) > 0 &&
3374 SOAP_GLOBAL(cache_limit) <= zend_hash_num_elements(SOAP_GLOBAL(mem_cache))) {
3375 /* in-memory cache overflow */
3376 sdl_cache_bucket *q;
3377 HashPosition pos;
3378 time_t latest = t;
3379 char *key = NULL;
3380 uint key_len;
3381 ulong idx;
3382
3383 for (zend_hash_internal_pointer_reset_ex(SOAP_GLOBAL(mem_cache), &pos);
3384 zend_hash_get_current_data_ex(SOAP_GLOBAL(mem_cache), (void **) &q, &pos) == SUCCESS;
3385 zend_hash_move_forward_ex(SOAP_GLOBAL(mem_cache), &pos)) {
3386 if (q->time < latest) {
3387 latest = q->time;
3388 zend_hash_get_current_key_ex(SOAP_GLOBAL(mem_cache), &key, &key_len, &idx, 0, &pos);
3389 }
3390 }
3391 if (key) {
3392 zend_hash_del(SOAP_GLOBAL(mem_cache), key, key_len);
3393 } else {
3394 return sdl;
3395 }
3396 }
3397
3398 psdl = make_persistent_sdl(sdl TSRMLS_CC);
3399 psdl->is_persistent = 1;
3400 p.time = t;
3401 p.sdl = psdl;
3402
3403 if (SUCCESS == zend_hash_update(SOAP_GLOBAL(mem_cache), uri,
3404 uri_len+1, (void*)&p, sizeof(sdl_cache_bucket), NULL)) {
3405 /* remove non-persitent sdl structure */
3406 delete_sdl_impl(sdl);
3407 /* and replace it with persistent one */
3408 sdl = psdl;
3409 } else {
3410 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to register persistent entry");
3411 /* clean up persistent sdl */
3412 delete_psdl(&p);
3413 /* keep non-persistent sdl and return it */
3414 }
3415 }
3416 }
3417
3418 return sdl;
3419 }
3420
3421 /* Deletes */
delete_sdl_impl(void * handle)3422 void delete_sdl_impl(void *handle)
3423 {
3424 sdlPtr tmp = (sdlPtr)handle;
3425
3426 zend_hash_destroy(&tmp->functions);
3427 if (tmp->source) {
3428 efree(tmp->source);
3429 }
3430 if (tmp->target_ns) {
3431 efree(tmp->target_ns);
3432 }
3433 if (tmp->elements) {
3434 zend_hash_destroy(tmp->elements);
3435 efree(tmp->elements);
3436 }
3437 if (tmp->encoders) {
3438 zend_hash_destroy(tmp->encoders);
3439 efree(tmp->encoders);
3440 }
3441 if (tmp->types) {
3442 zend_hash_destroy(tmp->types);
3443 efree(tmp->types);
3444 }
3445 if (tmp->groups) {
3446 zend_hash_destroy(tmp->groups);
3447 efree(tmp->groups);
3448 }
3449 if (tmp->bindings) {
3450 zend_hash_destroy(tmp->bindings);
3451 efree(tmp->bindings);
3452 }
3453 if (tmp->requests) {
3454 zend_hash_destroy(tmp->requests);
3455 efree(tmp->requests);
3456 }
3457 efree(tmp);
3458 }
3459
delete_sdl(void * handle)3460 void delete_sdl(void *handle)
3461 {
3462 sdlPtr tmp = (sdlPtr)handle;
3463
3464 if (!tmp->is_persistent) {
3465 delete_sdl_impl(tmp);
3466 }
3467 }
3468
delete_binding(void * data)3469 static void delete_binding(void *data)
3470 {
3471 sdlBindingPtr binding = *((sdlBindingPtr*)data);
3472
3473 if (binding->location) {
3474 efree(binding->location);
3475 }
3476 if (binding->name) {
3477 efree(binding->name);
3478 }
3479
3480 if (binding->bindingType == BINDING_SOAP) {
3481 sdlSoapBindingPtr soapBind = binding->bindingAttributes;
3482 if (soapBind) {
3483 efree(soapBind);
3484 }
3485 }
3486 efree(binding);
3487 }
3488
delete_binding_persistent(void * data)3489 static void delete_binding_persistent(void *data)
3490 {
3491 sdlBindingPtr binding = *((sdlBindingPtr*)data);
3492
3493 if (binding->location) {
3494 free(binding->location);
3495 }
3496 if (binding->name) {
3497 free(binding->name);
3498 }
3499
3500 if (binding->bindingType == BINDING_SOAP) {
3501 sdlSoapBindingPtr soapBind = binding->bindingAttributes;
3502 if (soapBind) {
3503 free(soapBind);
3504 }
3505 }
3506 free(binding);
3507 }
3508
delete_sdl_soap_binding_function_body(sdlSoapBindingFunctionBody body)3509 static void delete_sdl_soap_binding_function_body(sdlSoapBindingFunctionBody body)
3510 {
3511 if (body.ns) {
3512 efree(body.ns);
3513 }
3514 if (body.headers) {
3515 zend_hash_destroy(body.headers);
3516 efree(body.headers);
3517 }
3518 }
3519
delete_sdl_soap_binding_function_body_persistent(sdlSoapBindingFunctionBody body)3520 static void delete_sdl_soap_binding_function_body_persistent(sdlSoapBindingFunctionBody body)
3521 {
3522 if (body.ns) {
3523 free(body.ns);
3524 }
3525 if (body.headers) {
3526 zend_hash_destroy(body.headers);
3527 free(body.headers);
3528 }
3529 }
3530
delete_function(void * data)3531 static void delete_function(void *data)
3532 {
3533 sdlFunctionPtr function = *((sdlFunctionPtr*)data);
3534
3535 if (function->functionName) {
3536 efree(function->functionName);
3537 }
3538 if (function->requestName) {
3539 efree(function->requestName);
3540 }
3541 if (function->responseName) {
3542 efree(function->responseName);
3543 }
3544 if (function->requestParameters) {
3545 zend_hash_destroy(function->requestParameters);
3546 efree(function->requestParameters);
3547 }
3548 if (function->responseParameters) {
3549 zend_hash_destroy(function->responseParameters);
3550 efree(function->responseParameters);
3551 }
3552 if (function->faults) {
3553 zend_hash_destroy(function->faults);
3554 efree(function->faults);
3555 }
3556
3557 if (function->bindingAttributes &&
3558 function->binding && function->binding->bindingType == BINDING_SOAP) {
3559 sdlSoapBindingFunctionPtr soapFunction = function->bindingAttributes;
3560 if (soapFunction->soapAction) {
3561 efree(soapFunction->soapAction);
3562 }
3563 delete_sdl_soap_binding_function_body(soapFunction->input);
3564 delete_sdl_soap_binding_function_body(soapFunction->output);
3565 efree(soapFunction);
3566 }
3567 efree(function);
3568 }
3569
delete_function_persistent(void * data)3570 static void delete_function_persistent(void *data)
3571 {
3572 sdlFunctionPtr function = *((sdlFunctionPtr*)data);
3573
3574 if (function->functionName) {
3575 free(function->functionName);
3576 }
3577 if (function->requestName) {
3578 free(function->requestName);
3579 }
3580 if (function->responseName) {
3581 free(function->responseName);
3582 }
3583 if (function->requestParameters) {
3584 zend_hash_destroy(function->requestParameters);
3585 free(function->requestParameters);
3586 }
3587 if (function->responseParameters) {
3588 zend_hash_destroy(function->responseParameters);
3589 free(function->responseParameters);
3590 }
3591 if (function->faults) {
3592 zend_hash_destroy(function->faults);
3593 free(function->faults);
3594 }
3595
3596 if (function->bindingAttributes &&
3597 function->binding && function->binding->bindingType == BINDING_SOAP) {
3598 sdlSoapBindingFunctionPtr soapFunction = function->bindingAttributes;
3599 if (soapFunction->soapAction) {
3600 free(soapFunction->soapAction);
3601 }
3602 delete_sdl_soap_binding_function_body_persistent(soapFunction->input);
3603 delete_sdl_soap_binding_function_body_persistent(soapFunction->output);
3604 free(soapFunction);
3605 }
3606 free(function);
3607 }
3608
delete_parameter(void * data)3609 static void delete_parameter(void *data)
3610 {
3611 sdlParamPtr param = *((sdlParamPtr*)data);
3612 if (param->paramName) {
3613 efree(param->paramName);
3614 }
3615 efree(param);
3616 }
3617
delete_parameter_persistent(void * data)3618 static void delete_parameter_persistent(void *data)
3619 {
3620 sdlParamPtr param = *((sdlParamPtr*)data);
3621 if (param->paramName) {
3622 free(param->paramName);
3623 }
3624 free(param);
3625 }
3626
delete_header(void * data)3627 static void delete_header(void *data)
3628 {
3629 sdlSoapBindingFunctionHeaderPtr hdr = *((sdlSoapBindingFunctionHeaderPtr*)data);
3630 if (hdr->name) {
3631 efree(hdr->name);
3632 }
3633 if (hdr->ns) {
3634 efree(hdr->ns);
3635 }
3636 if (hdr->headerfaults) {
3637 zend_hash_destroy(hdr->headerfaults);
3638 efree(hdr->headerfaults);
3639 }
3640 efree(hdr);
3641 }
3642
delete_header_persistent(void * data)3643 static void delete_header_persistent(void *data)
3644 {
3645 sdlSoapBindingFunctionHeaderPtr hdr = *((sdlSoapBindingFunctionHeaderPtr*)data);
3646 if (hdr->name) {
3647 free(hdr->name);
3648 }
3649 if (hdr->ns) {
3650 free(hdr->ns);
3651 }
3652 if (hdr->headerfaults) {
3653 zend_hash_destroy(hdr->headerfaults);
3654 free(hdr->headerfaults);
3655 }
3656 free(hdr);
3657 }
3658
delete_fault(void * data)3659 static void delete_fault(void *data)
3660 {
3661 sdlFaultPtr fault = *((sdlFaultPtr*)data);
3662 if (fault->name) {
3663 efree(fault->name);
3664 }
3665 if (fault->details) {
3666 zend_hash_destroy(fault->details);
3667 efree(fault->details);
3668 }
3669 if (fault->bindingAttributes) {
3670 sdlSoapBindingFunctionFaultPtr binding = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
3671
3672 if (binding->ns) {
3673 efree(binding->ns);
3674 }
3675 efree(fault->bindingAttributes);
3676 }
3677 efree(fault);
3678 }
3679
delete_fault_persistent(void * data)3680 static void delete_fault_persistent(void *data)
3681 {
3682 sdlFaultPtr fault = *((sdlFaultPtr*)data);
3683 if (fault->name) {
3684 free(fault->name);
3685 }
3686 if (fault->details) {
3687 zend_hash_destroy(fault->details);
3688 free(fault->details);
3689 }
3690 if (fault->bindingAttributes) {
3691 sdlSoapBindingFunctionFaultPtr binding = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
3692
3693 if (binding->ns) {
3694 free(binding->ns);
3695 }
3696 free(fault->bindingAttributes);
3697 }
3698 free(fault);
3699 }
3700
delete_document(void * doc_ptr)3701 static void delete_document(void *doc_ptr)
3702 {
3703 xmlDocPtr doc = *((xmlDocPtr*)doc_ptr);
3704 xmlFreeDoc(doc);
3705 }
3706
3707