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