Annotation of embedaddon/php/ext/soap/php_sdl.c, revision 1.1.1.4
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.4 ! misho 5: | Copyright (c) 1997-2014 The PHP Group |
1.1 misho 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: */
1.1.1.2 misho 20: /* $Id$ */
1.1 misho 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);
1.1.1.3 misho 43: static void delete_parameter(void *parameter);
44: static void delete_parameter_persistent(void *parameter);
1.1 misho 45: static void delete_header(void *header);
46: static void delete_header_persistent(void *header);
47: static void delete_document(void *doc_ptr);
48:
49: encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr node, const xmlChar *type)
50: {
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:
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:
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:
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:
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:
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:
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:
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, '/');
1.1.1.2 misho 240: l1 = s ? (s - ctx->sdl->source) : strlen(ctx->sdl->source);
1.1 misho 241: s = strstr((char*)uri, "://");
242: if (!s) return;
243: s = strchr(s+3, '/');
1.1.1.2 misho 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: }
1.1 misho 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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
1.1.1.2 misho 2376: php_ignore_value(write(f, buf.c, buf.len));
1.1 misho 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:
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:
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:
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:
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:
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:
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:
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:
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:
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) {
1.1.1.4 ! misho 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));
1.1 misho 2650:
1.1.1.4 ! misho 2651: if ((*tmp)->ns) {
! 2652: pextra->ns = strdup((*tmp)->ns);
! 2653: }
! 2654: if ((*tmp)->val) {
! 2655: pextra->val = strdup((*tmp)->val);
! 2656: }
! 2657:
1.1 misho 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:
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:
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:
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:
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:
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:
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:
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:
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);
1.1.1.2 misho 3200: zend_bool has_proxy_authorization = 0;
3201: zend_bool has_authorization = 0;
1.1 misho 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;
1.1.1.2 misho 3232: char *user = php_get_current_user(TSRMLS_C);
1.1 misho 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 {
1.1.1.2 misho 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");
1.1 misho 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) {
1.1.1.2 misho 3292: context = php_stream_context_alloc(TSRMLS_C);
1.1 misho 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:
1.1.1.2 misho 3305: has_proxy_authorization = proxy_authentication(this_ptr, &headers TSRMLS_CC);
1.1 misho 3306: }
3307:
1.1.1.2 misho 3308: has_authorization = basic_authentication(this_ptr, &headers TSRMLS_CC);
1.1 misho 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);
1.1.1.2 misho 3317: smart_str_appendl(&headers, "Connection: close\r\n", sizeof("Connection: close\r\n")-1);
1.1 misho 3318: }
3319:
3320: if (headers.len > 0) {
3321: zval *str_headers;
3322:
3323: if (!context) {
1.1.1.2 misho 3324: context = php_stream_context_alloc(TSRMLS_C);
3325: } else {
3326: http_context_headers(context, has_authorization, has_proxy_authorization, 0, &headers TSRMLS_CC);
1.1 misho 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 */
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
3701: static void delete_document(void *doc_ptr)
3702: {
3703: xmlDocPtr doc = *((xmlDocPtr*)doc_ptr);
3704: xmlFreeDoc(doc);
3705: }
3706:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>