dmitry Tue Feb 10 08:41:22 2004 EDT Modified files: /php-src/ext/soap TODO php_encoding.c php_packet_soap.c php_schema.c php_schema.h php_sdl.c php_sdl.h php_soap.h soap.c Log: WSDL caching was implemented
http://cvs.php.net/diff.php/php-src/ext/soap/TODO?r1=1.40&r2=1.41&ty=u Index: php-src/ext/soap/TODO diff -u php-src/ext/soap/TODO:1.40 php-src/ext/soap/TODO:1.41 --- php-src/ext/soap/TODO:1.40 Thu Feb 5 15:26:02 2004 +++ php-src/ext/soap/TODO Tue Feb 10 08:41:21 2004 @@ -3,7 +3,7 @@ - make sure soapserver.map(), soap_encode_to_xml() and soap_encode_to_zval() are really need - reimplement SoapObject::__getfunctions() and SoapObject::__gettypes() to return structures instead of strings -- memory leaks (libxml and WSDL/Schema use malloc to cache WSDL) +? memory leaks (libxml and WSDL/Schema use malloc to cache WSDL) - error handling??? SOAP @@ -57,7 +57,7 @@ - support for <opperation> <fault> ? server part support for "document" style encoding - function/method overloading/redeclaration (test(int); test(string)) -- wsdl caching ++ wsdl caching - wsdl auto generation ? SOAP binding - <soap:body> parts attribute http://cvs.php.net/diff.php/php-src/ext/soap/php_encoding.c?r1=1.51&r2=1.52&ty=u Index: php-src/ext/soap/php_encoding.c diff -u php-src/ext/soap/php_encoding.c:1.51 php-src/ext/soap/php_encoding.c:1.52 --- php-src/ext/soap/php_encoding.c:1.51 Fri Feb 6 09:22:33 2004 +++ php-src/ext/soap/php_encoding.c Tue Feb 10 08:41:21 2004 @@ -17,7 +17,7 @@ | Dmitry Stogov <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: php_encoding.c,v 1.51 2004/02/06 14:22:33 dmitry Exp $ */ +/* $Id: php_encoding.c,v 1.52 2004/02/10 13:41:21 dmitry Exp $ */ #include <time.h> @@ -826,7 +826,7 @@ } } case XSD_CONTENT_GROUP: - model_to_zval_object(ret, model->u.group, data, sdl TSRMLS_CC); + model_to_zval_object(ret, model->u.group->model, data, sdl TSRMLS_CC); default: break; } @@ -1023,7 +1023,7 @@ return 0; } case XSD_CONTENT_GROUP: { - return model_to_xml_object(node, model->u.group, prop, style, model->min_occurs > 0); + return model_to_xml_object(node, model->u.group->model, prop, style, model->min_occurs > 0); } default: break; @@ -1555,7 +1555,7 @@ int dimension = 1; int* dims = NULL; int* pos = NULL; - xmlAttrPtr attr; + xmlAttrPtr attr; sdlPtr sdl; sdlAttributePtr *arrayType; sdlExtraAttributePtr *ext; http://cvs.php.net/diff.php/php-src/ext/soap/php_packet_soap.c?r1=1.32&r2=1.33&ty=u Index: php-src/ext/soap/php_packet_soap.c diff -u php-src/ext/soap/php_packet_soap.c:1.32 php-src/ext/soap/php_packet_soap.c:1.33 --- php-src/ext/soap/php_packet_soap.c:1.32 Thu Feb 5 04:28:09 2004 +++ php-src/ext/soap/php_packet_soap.c Tue Feb 10 08:41:21 2004 @@ -17,7 +17,7 @@ | Dmitry Stogov <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: php_packet_soap.c,v 1.32 2004/02/05 09:28:09 dmitry Exp $ */ +/* $Id: php_packet_soap.c,v 1.33 2004/02/10 13:41:21 dmitry Exp $ */ #include "php_soap.h" @@ -240,63 +240,66 @@ char *name, *ns = NULL; zval* tmp; sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes; - int res_count = zend_hash_num_elements(fn->responseParameters); + int res_count; hdrs = fnb->output.headers; - zend_hash_internal_pointer_reset(fn->responseParameters); - while (zend_hash_get_current_data(fn->responseParameters, (void **)&h_param) == SUCCESS) { - param = (*h_param); - if (fnb->style == SOAP_DOCUMENT) { - name = param->encode->details.type_str; - ns = param->encode->details.ns; - } else { - name = fn->responseName; - /* ns = ? */ - } - - /* Get value of parameter */ - cur = get_node_ex(resp, name, ns); - if (!cur) { - cur = get_node(resp, name); - /* TODO: produce warning invalid ns */ - } - if (cur) { + if (fn->responseParameters) { + res_count = zend_hash_num_elements(fn->responseParameters); + zend_hash_internal_pointer_reset(fn->responseParameters); + while (zend_hash_get_current_data(fn->responseParameters, (void **)&h_param) == SUCCESS) { + param = (*h_param); if (fnb->style == SOAP_DOCUMENT) { - val = cur; + name = param->encode->details.type_str; + ns = param->encode->details.ns; } else { - val = get_node(cur->children, param->paramName); - if (val == NULL && res_count == 1) { - val = get_node(cur->children, "return"); - } - if (val == NULL && res_count == 1) { - val = get_node(cur->children, "result"); + name = fn->responseName; + /* ns = ? */ + } + + /* Get value of parameter */ + cur = get_node_ex(resp, name, ns); + if (!cur) { + cur = get_node(resp, name); + /* TODO: produce warning invalid ns */ + } + if (cur) { + if (fnb->style == SOAP_DOCUMENT) { + val = cur; + } else { + val = get_node(cur->children, param->paramName); + if (val == NULL && res_count == 1) { + val = get_node(cur->children, "return"); + } + if (val == NULL && res_count == 1) { + val = get_node(cur->children, "result"); + } } } - } - if (!val) { - /* TODO: may be "nil" is not OK? */ - MAKE_STD_ZVAL(tmp); - ZVAL_NULL(tmp); + if (!val) { + /* TODO: may be "nil" is not OK? */ + MAKE_STD_ZVAL(tmp); + ZVAL_NULL(tmp); /* - add_soap_fault(this_ptr, "Client", "Can't find response data", NULL, NULL TSRMLS_CC); - xmlFreeDoc(response); - return FALSE; + add_soap_fault(this_ptr, "Client", "Can't find response data", NULL, NULL TSRMLS_CC); + xmlFreeDoc(response); + return FALSE; */ - } else { - /* Decoding value of parameter */ - if (param != NULL) { - tmp = master_to_zval(param->encode, val); } else { - tmp = master_to_zval(NULL, val); + /* Decoding value of parameter */ + if (param != NULL) { + tmp = master_to_zval(param->encode, val); + } else { + tmp = master_to_zval(NULL, val); + } } - } - add_assoc_zval(return_value, param->paramName, tmp); + add_assoc_zval(return_value, param->paramName, tmp); - param_count++; + param_count++; - zend_hash_move_forward(fn->responseParameters); + zend_hash_move_forward(fn->responseParameters); + } } } else { /* Function hasn't WSDL description */ http://cvs.php.net/diff.php/php-src/ext/soap/php_schema.c?r1=1.40&r2=1.41&ty=u Index: php-src/ext/soap/php_schema.c diff -u php-src/ext/soap/php_schema.c:1.40 php-src/ext/soap/php_schema.c:1.41 --- php-src/ext/soap/php_schema.c:1.40 Fri Feb 6 11:52:14 2004 +++ php-src/ext/soap/php_schema.c Tue Feb 10 08:41:21 2004 @@ -17,7 +17,7 @@ | Dmitry Stogov <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: php_schema.c,v 1.40 2004/02/06 16:52:14 dmitry Exp $ */ +/* $Id: php_schema.c,v 1.41 2004/02/10 13:41:21 dmitry Exp $ */ #include "php_soap.h" #include "libxml/uri.h" @@ -46,13 +46,6 @@ static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type); -static void delete_model(void *handle); -static void delete_type(void *data); -static void delete_extra_attribute(void *attribute); -static void delete_attribute(void *attribute); -static void delete_restriction_var_int(void *rvi); -static void delete_schema_restriction_var_char(void *srvc); - static encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const char *ns, const char *type) { smart_str nscat = {0}; @@ -697,7 +690,7 @@ schema_restriction_var_char(trav, &enumval); if (cur_type->restrictions->enumeration == NULL) { cur_type->restrictions->enumeration = sdl_malloc(sizeof(HashTable)); - zend_hash_init(cur_type->restrictions->enumeration, 0, NULL, delete_schema_restriction_var_char, SDL_PERSISTENT); + zend_hash_init(cur_type->restrictions->enumeration, 0, NULL, delete_restriction_var_char, SDL_PERSISTENT); } zend_hash_add(cur_type->restrictions->enumeration, enumval->value, strlen(enumval->value)+1, &enumval, sizeof(sdlRestrictionCharPtr), NULL); } else { @@ -2113,7 +2106,7 @@ schema_type_fixup(ctx,*tmp); efree(model->u.group_ref); model->kind = XSD_CONTENT_GROUP; - model->u.group = (*tmp)->model; + model->u.group = (*tmp); } else { php_error(E_ERROR, "SOAP-ERROR: Parsing Schema: unresolved group 'ref' attribute"); } @@ -2231,7 +2224,7 @@ } } -static void delete_model(void *handle) +void delete_model(void *handle) { sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle); switch (tmp->kind) { @@ -2251,7 +2244,7 @@ sdl_free(tmp); } -static void delete_type(void *data) +void delete_type(void *data) { sdlTypePtr type = *((sdlTypePtr*)data); if (type->name) { @@ -2287,8 +2280,8 @@ delete_restriction_var_int(&type->restrictions->length); delete_restriction_var_int(&type->restrictions->minLength); delete_restriction_var_int(&type->restrictions->maxLength); - delete_schema_restriction_var_char(&type->restrictions->whiteSpace); - delete_schema_restriction_var_char(&type->restrictions->pattern); + delete_restriction_var_char(&type->restrictions->whiteSpace); + delete_restriction_var_char(&type->restrictions->pattern); if (type->restrictions->enumeration) { zend_hash_destroy(type->restrictions->enumeration); sdl_free(type->restrictions->enumeration); @@ -2298,7 +2291,7 @@ sdl_free(type); } -static void delete_extra_attribute(void *attribute) +void delete_extra_attribute(void *attribute) { sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute); @@ -2311,7 +2304,7 @@ sdl_free(attr); } -static void delete_attribute(void *attribute) +void delete_attribute(void *attribute) { sdlAttributePtr attr = *((sdlAttributePtr*)attribute); @@ -2334,7 +2327,7 @@ sdl_free(attr); } -static void delete_restriction_var_int(void *rvi) +void delete_restriction_var_int(void *rvi) { sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi); if (ptr) { @@ -2342,7 +2335,7 @@ } } -static void delete_schema_restriction_var_char(void *srvc) +void delete_restriction_var_char(void *srvc) { sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc); if (ptr) { http://cvs.php.net/diff.php/php-src/ext/soap/php_schema.h?r1=1.10&r2=1.11&ty=u Index: php-src/ext/soap/php_schema.h diff -u php-src/ext/soap/php_schema.h:1.10 php-src/ext/soap/php_schema.h:1.11 --- php-src/ext/soap/php_schema.h:1.10 Fri Feb 6 06:56:03 2004 +++ php-src/ext/soap/php_schema.h Tue Feb 10 08:41:21 2004 @@ -17,7 +17,7 @@ | Dmitry Stogov <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: php_schema.h,v 1.10 2004/02/06 11:56:03 dmitry Exp $ */ +/* $Id: php_schema.h,v 1.11 2004/02/10 13:41:21 dmitry Exp $ */ #ifndef PHP_SCHEMA_H #define PHP_SCHEMA_H @@ -25,4 +25,10 @@ int load_schema(sdlCtx *ctx, xmlNodePtr schema); void schema_pass2(sdlCtx *ctx); +void delete_model(void *handle); +void delete_type(void *data); +void delete_extra_attribute(void *attribute); +void delete_attribute(void *attribute); +void delete_restriction_var_int(void *rvi); +void delete_restriction_var_char(void *srvc); #endif http://cvs.php.net/diff.php/php-src/ext/soap/php_sdl.c?r1=1.53&r2=1.54&ty=u Index: php-src/ext/soap/php_sdl.c diff -u php-src/ext/soap/php_sdl.c:1.53 php-src/ext/soap/php_sdl.c:1.54 --- php-src/ext/soap/php_sdl.c:1.53 Fri Feb 6 11:54:34 2004 +++ php-src/ext/soap/php_sdl.c Tue Feb 10 08:41:21 2004 @@ -17,14 +17,25 @@ | Dmitry Stogov <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: php_sdl.c,v 1.53 2004/02/06 16:54:34 dmitry Exp $ */ +/* $Id: php_sdl.c,v 1.54 2004/02/10 13:41:21 dmitry Exp $ */ #include "php_soap.h" #include "libxml/uri.h" +#include "ext/standard/md5.h" +#include "tsrm_virtual_cwd.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#ifndef O_BINARY +# define O_BINARY 0 +#endif + static void delete_binding(void *binding); static void delete_function(void *function); -static void delete_paramater(void *paramater); +static void delete_parameter(void *paramater); static void delete_header(void *header); static void delete_document(void *doc_ptr); @@ -149,8 +160,6 @@ return; } - /* TODO: WSDL Caching */ - wsdl = soap_xmlParseFile(struri); if (!wsdl) { @@ -403,7 +412,7 @@ message = *tmp; parameters = sdl_malloc(sizeof(HashTable)); - zend_hash_init(parameters, 0, NULL, delete_paramater, SDL_PERSISTENT); + zend_hash_init(parameters, 0, NULL, delete_parameter, SDL_PERSISTENT); trav = message->children; FOREACHNODE(trav, "part", part) { @@ -751,7 +760,1059 @@ return ctx.sdl; } -sdlPtr get_sdl(char *uri) +#define WSDL_CACHE_VERSION 01 + +#define WSDL_CACHE_GET(ret,type,buf) memcpy(&ret,*buf,sizeof(type)); *buf += sizeof(type); +#define WSDL_CACHE_GET_INT(ret,buf) ret = ((int)(*buf)[0])+((int)(*buf)[1]<<8)+((int)(*buf)[2]<<16)+((int)(*buf)[3]<<24); *buf += 4; +#define WSDL_CACHE_GET_1(ret,type,buf) ret = (type)(**buf); (*buf)++; +#define WSDL_CACHE_GET_N(ret,n,buf) memcpy(ret,*buf,n); *buf += n; +#define WSDL_CACHE_SKIP(n,buf) *buf += n; + +#define WSDL_CACHE_PUT_INT(val,buf) smart_str_appendc(buf,val & 0xff); \ + smart_str_appendc(buf,(val >> 8) & 0xff); \ + smart_str_appendc(buf,(val >> 16) & 0xff); \ + smart_str_appendc(buf,(val >> 24) & 0xff); +#define WSDL_CACHE_PUT_1(val,buf) smart_str_appendc(buf,val); +#define WSDL_CACHE_PUT_N(val,n,buf) smart_str_appendl(buf,(char*)val,n); + +static char* sdl_deserialize_string(char **in) +{ + char *s; + int len; + + WSDL_CACHE_GET_INT(len, in); + if (len == 0) { + return NULL; + } else { + s = sdl_malloc(len+1); + WSDL_CACHE_GET_N(s, len, in); + s[len] = '\0'; + return s; + } +} + +static void sdl_deserialize_key(HashTable* ht, void* data, char **in) +{ + int len; + + WSDL_CACHE_GET_INT(len, in); + if (len == 0) { + zend_hash_next_index_insert(ht, &data, sizeof(void*), NULL); + } else { + zend_hash_add(ht, *in, len, &data, sizeof(void*), NULL); + WSDL_CACHE_SKIP(len, in); + } +} + +static void sdl_deserialize_attribute(sdlAttributePtr attr, encodePtr *encoders, char **in) +{ + int i; + + attr->name = sdl_deserialize_string(in); + attr->ref = sdl_deserialize_string(in); + attr->def = sdl_deserialize_string(in); + attr->fixed = sdl_deserialize_string(in); + WSDL_CACHE_GET_1(attr->form, sdlForm, in); + WSDL_CACHE_GET_1(attr->use, sdlUse, in); + WSDL_CACHE_GET_INT(i, in); + attr->encode = encoders[i]; + WSDL_CACHE_GET_INT(i, in); + if (i > 0) { + attr->extraAttributes = sdl_malloc(sizeof(HashTable)); + zend_hash_init(attr->extraAttributes, i, NULL, delete_extra_attribute, SDL_PERSISTENT); + while (i > 0) { + sdlExtraAttributePtr x = sdl_malloc(sizeof(sdlExtraAttribute)); + sdl_deserialize_key(attr->extraAttributes, x, in); + x->ns = sdl_deserialize_string(in); + x->val = sdl_deserialize_string(in); + --i; + } + } +} + +static sdlRestrictionIntPtr sdl_deserialize_resriction_int(char **in) +{ + if (**in == 1) { + sdlRestrictionIntPtr x = sdl_malloc(sizeof(sdlRestrictionInt)); + WSDL_CACHE_SKIP(1, in); + WSDL_CACHE_GET_INT(x->value, in); + WSDL_CACHE_GET_1(x->fixed, char, in); + return x; + } else { + WSDL_CACHE_SKIP(1, in); + return NULL; + } +} + +static sdlRestrictionCharPtr sdl_deserialize_resriction_char(char **in) +{ + if (**in == 1) { + sdlRestrictionCharPtr x = sdl_malloc(sizeof(sdlRestrictionChar)); + WSDL_CACHE_SKIP(1, in); + x->value = sdl_deserialize_string(in); + WSDL_CACHE_GET_1(x->fixed, char, in); + return x; + } else { + WSDL_CACHE_SKIP(1, in); + return NULL; + } +} + +static sdlContentModelPtr sdl_deserialize_model(sdlTypePtr *types, sdlTypePtr *elements, char **in) +{ + int i; + sdlContentModelPtr model = sdl_malloc(sizeof(sdlContentModel)); + + WSDL_CACHE_GET_1(model->kind, sdlContentKind, in); + WSDL_CACHE_GET_INT(model->min_occurs, in); + WSDL_CACHE_GET_INT(model->max_occurs, in); + switch (model->kind) { + case XSD_CONTENT_ELEMENT: + WSDL_CACHE_GET_INT(i, in); + model->u.element = elements[i]; + break; + case XSD_CONTENT_SEQUENCE: + case XSD_CONTENT_ALL: + case XSD_CONTENT_CHOICE: + WSDL_CACHE_GET_INT(i, in); + if (i > 0) { + model->u.content = sdl_malloc(sizeof(HashTable)); + zend_hash_init(model->u.content, i, NULL, delete_model, SDL_PERSISTENT); + while (i > 0) { + sdlContentModelPtr x = sdl_deserialize_model(types, elements, in); + zend_hash_next_index_insert(model->u.content,&x,sizeof(sdlContentModelPtr),NULL); + i--; + } + } + break; + case XSD_CONTENT_GROUP_REF: + model->u.group_ref = sdl_deserialize_string(in); + break; + case XSD_CONTENT_GROUP: + WSDL_CACHE_GET_INT(i, in); + model->u.group = types[i]; + break; + default: + break; + } + return model; +} + +static void sdl_deserialize_type(sdlTypePtr type, sdlTypePtr *types, encodePtr *encoders, char **in) +{ + int i; + sdlTypePtr *elements = NULL; + + WSDL_CACHE_GET_1(type->kind, sdlTypeKind, in); + type->name = sdl_deserialize_string(in); + type->namens = sdl_deserialize_string(in); + type->def = sdl_deserialize_string(in); + type->fixed = sdl_deserialize_string(in); + type->ref = sdl_deserialize_string(in); + WSDL_CACHE_GET_1(type->nillable, char, in); + + WSDL_CACHE_GET_INT(i, in); + type->encode = encoders[i]; + + if (**in == 1) { + WSDL_CACHE_SKIP(1, in); + type->restrictions = sdl_malloc(sizeof(sdlRestrictions)); + /*memset(type->restrictions, 0, sizeof(sdlRestrictions));*/ + type->restrictions->minExclusive = sdl_deserialize_resriction_int(in); + type->restrictions->minInclusive = sdl_deserialize_resriction_int(in); + type->restrictions->maxExclusive = sdl_deserialize_resriction_int(in); + type->restrictions->maxInclusive = sdl_deserialize_resriction_int(in); + type->restrictions->totalDigits = sdl_deserialize_resriction_int(in); + type->restrictions->fractionDigits = sdl_deserialize_resriction_int(in); + type->restrictions->length = sdl_deserialize_resriction_int(in); + type->restrictions->minLength = sdl_deserialize_resriction_int(in); + type->restrictions->maxLength = sdl_deserialize_resriction_int(in); + type->restrictions->whiteSpace = sdl_deserialize_resriction_char(in); + type->restrictions->pattern = sdl_deserialize_resriction_char(in); + WSDL_CACHE_GET_INT(i, in); + if (i > 0) { + type->restrictions->enumeration = sdl_malloc(sizeof(HashTable)); + zend_hash_init(type->restrictions->enumeration, i, NULL, delete_restriction_var_char, SDL_PERSISTENT); + while (i > 0) { + sdlRestrictionCharPtr x = sdl_deserialize_resriction_char(in); + sdl_deserialize_key(type->restrictions->enumeration, x, in); + --i; + } + } else { + type->restrictions->enumeration = NULL; + } + } else { + WSDL_CACHE_SKIP(1, in); + } + + WSDL_CACHE_GET_INT(i, in); + if (i > 0) { + elements = do_alloca((i+1) * sizeof(sdlTypePtr)); + elements[0] = NULL; + type->elements = sdl_malloc(sizeof(HashTable)); + zend_hash_init(type->elements, i, NULL, delete_type, SDL_PERSISTENT); + while (i > 0) { + sdlTypePtr t = sdl_malloc(sizeof(sdlType)); + memset(t, 0, sizeof(sdlType)); + sdl_deserialize_key(type->elements, t, in); + sdl_deserialize_type(t, types, encoders, in); + elements[i] = t; + --i; + } + } + + WSDL_CACHE_GET_INT(i, in); + if (i > 0) { + type->attributes = sdl_malloc(sizeof(HashTable)); + zend_hash_init(type->attributes, i, NULL, delete_attribute, SDL_PERSISTENT); + while (i > 0) { + sdlAttributePtr attr = sdl_malloc(sizeof(sdlAttribute)); + memset(attr, 0, sizeof(sdlAttribute)); + sdl_deserialize_key(type->attributes, attr, in); + sdl_deserialize_attribute(attr, encoders, in); + --i; + } + } + + if (**in != 0) { + WSDL_CACHE_SKIP(1, in); + type->model = sdl_deserialize_model(types, elements, in); + } else { + WSDL_CACHE_SKIP(1, in); + } + if (elements != NULL) { + free_alloca(elements); + } +} + +static void sdl_deserialize_encoder(encodePtr enc, sdlTypePtr *types, char **in) +{ + int i; + + WSDL_CACHE_GET_INT(enc->details.type, in); + enc->details.type_str = sdl_deserialize_string(in); + enc->details.ns = sdl_deserialize_string(in); + WSDL_CACHE_GET_INT(i, in); + enc->details.sdl_type = types[i]; + enc->to_xml = sdl_guess_convert_xml; + enc->to_zval = sdl_guess_convert_zval; +} + +static void sdl_deserialize_soap_body(sdlSoapBindingFunctionBodyPtr body, encodePtr *encoders, sdlTypePtr *types, char **in) +{ + int i, n; + + WSDL_CACHE_GET_1(body->use, sdlEncodingUse, in); + body->ns = sdl_deserialize_string(in); + body->parts = sdl_deserialize_string(in); + body->encodingStyle = sdl_deserialize_string(in); + WSDL_CACHE_GET_INT(i, in); + if (i > 0) { + body->headers = sdl_malloc(sizeof(HashTable)); + zend_hash_init(body->headers, i, NULL, delete_header, SDL_PERSISTENT); + while (i > 0) { + sdlSoapBindingFunctionHeaderPtr tmp = sdl_malloc(sizeof(sdlSoapBindingFunctionHeader)); + sdl_deserialize_key(body->headers, tmp, in); + WSDL_CACHE_GET_1(tmp->use, sdlEncodingUse, in); + tmp->name = sdl_deserialize_string(in); + tmp->ns = sdl_deserialize_string(in); + tmp->encodingStyle = sdl_deserialize_string(in); + WSDL_CACHE_GET_INT(n, in); + tmp->encode = encoders[n]; + WSDL_CACHE_GET_INT(n, in); + tmp->element = types[n]; + --i; + } + } +} + +static HashTable* sdl_deserialize_parameters(encodePtr *encoders, sdlTypePtr *types, char **in) +{ + int i, n; + HashTable *ht; + + WSDL_CACHE_GET_INT(i, in); + if (i == 0) {return NULL;} + ht = sdl_malloc(sizeof(HashTable)); + zend_hash_init(ht, i, NULL, delete_parameter, SDL_PERSISTENT); + while (i > 0) { + sdlParamPtr param = sdl_malloc(sizeof(sdlParam)); + sdl_deserialize_key(ht, param, in); + param->paramName = sdl_deserialize_string(in); + WSDL_CACHE_GET_INT(param->order, in); + WSDL_CACHE_GET_INT(n, in); + param->encode = encoders[n]; + WSDL_CACHE_GET_INT(n, in); + param->element = types[n]; + --i; + } + return ht; +} + +static sdlPtr get_sdl_from_cache(const char *fn, const char *uri, time_t t) +{ + sdlPtr sdl; + time_t old_t; + int i, num_groups, num_types, num_elements, num_encoders, num_bindings, num_func; + sdlFunctionPtr *functions; + sdlBindingPtr *bindings; + sdlTypePtr *types; + encodePtr *encoders; + encodePtr enc; + + int f; + struct stat st; + char *in, *buf; + + f = open(fn, O_RDONLY|O_BINARY); + if (f < 0) { + return NULL; + } + if (fstat(f, &st) != 0) { + close(f); + return NULL; + } + buf = in = do_alloca(st.st_size); + if (read(f, in, st.st_size) != st.st_size) { + close(f); + free_alloca(in); + return NULL; + } + close(f); + + if (strncmp(in,"wsdl",4) != 0 || in[4] != WSDL_CACHE_VERSION || in[5] != '\0') { + unlink(fn); + free_alloca(buf); + return NULL; + } + in += 6; + + WSDL_CACHE_GET(old_t, time_t, &in); + if (old_t < t) { + unlink(fn); + free_alloca(buf); + return NULL; + } + + WSDL_CACHE_GET_INT(i, &in); + if (i == 0 && strncmp(in, uri, i) != 0) { + unlink(fn); + free_alloca(buf); + return NULL; + } + WSDL_CACHE_SKIP(i, &in); + + sdl = sdl_malloc(sizeof(*sdl)); + memset(sdl, 0, sizeof(*sdl)); + + sdl->source = sdl_deserialize_string(&in); + sdl->target_ns = sdl_deserialize_string(&in); + + WSDL_CACHE_GET_INT(num_groups, &in); + WSDL_CACHE_GET_INT(num_types, &in); + WSDL_CACHE_GET_INT(num_elements, &in); + WSDL_CACHE_GET_INT(num_encoders, &in); + + i = num_groups+num_types+num_elements; + types = do_alloca((i+1)*sizeof(sdlTypePtr)); + types[0] = NULL; + while (i > 0) { + types[i] = sdl_malloc(sizeof(sdlType)); + memset(types[i], 0, sizeof(sdlType)); + i--; + } + + i = num_encoders; + enc = defaultEncoding; + while (enc->details.type != END_KNOWN_TYPES) { + i++; enc++; + } + encoders = do_alloca((i+1)*sizeof(encodePtr)); + i = num_encoders; + encoders[0] = NULL; + while (i > 0) { + encoders[i] = sdl_malloc(sizeof(encode)); + memset(encoders[i], 0, sizeof(encode)); + i--; + } + i = num_encoders; + enc = defaultEncoding; + while (enc->details.type != END_KNOWN_TYPES) { + encoders[++i] = enc++; + } + + i = 1; + if (num_groups > 0) { + sdl->groups = sdl_malloc(sizeof(HashTable)); + zend_hash_init(sdl->groups, num_groups, NULL, delete_type, SDL_PERSISTENT); + while (i < num_groups+1) { + sdl_deserialize_key(sdl->groups, types[i], &in); + sdl_deserialize_type(types[i], types, encoders, &in); + i++; + } + } + + if (num_types > 0) { + sdl->types = sdl_malloc(sizeof(HashTable)); + zend_hash_init(sdl->types, num_types, NULL, delete_type, SDL_PERSISTENT); + while (i < num_groups+num_types+1) { + sdl_deserialize_key(sdl->types, types[i], &in); + sdl_deserialize_type(types[i], types, encoders, &in); + i++; + } + } + + if (num_elements > 0) { + sdl->elements = sdl_malloc(sizeof(HashTable)); + zend_hash_init(sdl->elements, num_elements, NULL, delete_type, SDL_PERSISTENT); + while (i < num_groups+num_types+num_elements+1) { + sdl_deserialize_key(sdl->elements, types[i], &in); + sdl_deserialize_type(types[i], types, encoders, &in); + i++; + } + } + + i = 1; + if (num_encoders > 0) { + sdl->encoders = sdl_malloc(sizeof(HashTable)); + zend_hash_init(sdl->encoders, num_encoders, NULL, delete_encoder, SDL_PERSISTENT); + while (i < num_encoders+1) { + sdl_deserialize_key(sdl->encoders, encoders[i], &in); + sdl_deserialize_encoder(encoders[i], types, &in); + i++; + } + } + + /* deserialize bindings */ + WSDL_CACHE_GET_INT(num_bindings, &in); + bindings = do_alloca(num_bindings*sizeof(sdlBindingPtr)); + if (num_bindings > 0) { + sdl->bindings = sdl_malloc(sizeof(HashTable)); + zend_hash_init(sdl->bindings, num_bindings, NULL, delete_binding, SDL_PERSISTENT); + for (i = 0; i < num_bindings; i++) { + sdlBindingPtr binding = sdl_malloc(sizeof(sdlBinding)); + memset(binding, 0, sizeof(sdlBinding)); + sdl_deserialize_key(sdl->bindings, binding, &in); + binding->name = sdl_deserialize_string(&in); + binding->location = sdl_deserialize_string(&in); + WSDL_CACHE_GET_1(binding->bindingType,sdlBindingType,&in); + if (binding->bindingType == BINDING_SOAP) { + if (*in != 0) { + sdlSoapBindingPtr soap_binding = binding->bindingAttributes = sdl_malloc(sizeof(sdlSoapBinding)); + WSDL_CACHE_GET_1(soap_binding->style,sdlEncodingStyle,&in); + soap_binding->transport = sdl_deserialize_string(&in); + } else { + WSDL_CACHE_SKIP(1,&in); + } + } + bindings[i] = binding; + } + } + + /* deserialize functions */ + WSDL_CACHE_GET_INT(num_func, &in); + zend_hash_init(&sdl->functions, num_func, NULL, delete_function, SDL_PERSISTENT); + functions = do_alloca(num_func*sizeof(sdlFunctionPtr)); + for (i = 0; i < num_func; i++) { + int binding_num; + sdlFunctionPtr func = sdl_malloc(sizeof(sdlFunction)); + sdl_deserialize_key(&sdl->functions, func, &in); + func->functionName = sdl_deserialize_string(&in); + func->requestName = sdl_deserialize_string(&in); + func->responseName = sdl_deserialize_string(&in); + + WSDL_CACHE_GET_INT(binding_num, &in); + if (binding_num == 0) { + func->binding = NULL; + } else { + func->binding = bindings[binding_num-1]; + } + if (func->binding && func->binding->bindingType == BINDING_SOAP) { + if (*in != 0) { + sdlSoapBindingFunctionPtr binding = func->bindingAttributes = sdl_malloc(sizeof(sdlSoapBindingFunction)); + memset(binding, 0, sizeof(sdlSoapBindingFunction)); + WSDL_CACHE_GET_1(binding->style,sdlEncodingStyle,&in); + binding->soapAction = sdl_deserialize_string(&in); + sdl_deserialize_soap_body(&binding->input, encoders, types, &in); + sdl_deserialize_soap_body(&binding->output, encoders, types, &in); + /*sdl_deserialize_soap_body(&binding->fault, encoders, types, &in);*/ + } else { + WSDL_CACHE_SKIP(1, &in); + } + } + + func->requestParameters = sdl_deserialize_parameters(encoders, types, &in); + func->responseParameters = sdl_deserialize_parameters(encoders, types, &in); + functions[i] = func; + } + + /* deserialize requests */ + WSDL_CACHE_GET_INT(i, &in); + if (i > 0) { + sdl->requests = sdl_malloc(sizeof(HashTable)); + zend_hash_init(sdl->requests, i, NULL, NULL, SDL_PERSISTENT); + while (i > 0) { + int function_num; + + WSDL_CACHE_GET_INT(function_num, &in); + sdl_deserialize_key(sdl->requests, functions[function_num], &in); + i--; + } + } + + free_alloca(functions); + free_alloca(bindings); + free_alloca(encoders); + free_alloca(types); + free_alloca(buf); + return sdl; +} + +static void sdl_serialize_string(const char *str, smart_str *out) +{ + int i; + + if (str) { + i = strlen(str); + } else { + i = 0; + } + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + WSDL_CACHE_PUT_N(str, i, out); + } +} + +static void sdl_serialize_key(HashTable *ht, smart_str *out) +{ + char *key; + uint key_len; + ulong index; + + if (zend_hash_get_current_key_ex(ht, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) { + WSDL_CACHE_PUT_INT(key_len, out); + WSDL_CACHE_PUT_N(key, key_len, out); + } else { + WSDL_CACHE_PUT_INT(0, out); + } +} + +static void sdl_serialize_encoder_ref(encodePtr enc, HashTable *tmp_encoders, smart_str *out) { + if (enc) { + int *encoder_num; + if (zend_hash_find(tmp_encoders, (char*)&enc, sizeof(enc), (void**)&encoder_num) == SUCCESS) { + WSDL_CACHE_PUT_INT(*encoder_num, out); + } else { + WSDL_CACHE_PUT_INT(0, out); + } + } else { + WSDL_CACHE_PUT_INT(0, out); + } +} + +static void sdl_serialize_type_ref(sdlTypePtr type, HashTable *tmp_types, smart_str *out) { + if (type) { + int *type_num; + if (zend_hash_find(tmp_types, (char*)&type, sizeof(type), (void**)&type_num) == SUCCESS) { + WSDL_CACHE_PUT_INT(*type_num, out); + } else { + WSDL_CACHE_PUT_INT(0, out); + } + } else { + WSDL_CACHE_PUT_INT(0,out); + } +} + +static void sdl_serialize_attribute(sdlAttributePtr attr, HashTable *tmp_encoders, smart_str *out) +{ + int i; + + sdl_serialize_string(attr->name, out); + sdl_serialize_string(attr->ref, out); + sdl_serialize_string(attr->def, out); + sdl_serialize_string(attr->fixed, out); + WSDL_CACHE_PUT_1(attr->form, out); + WSDL_CACHE_PUT_1(attr->use, out); + sdl_serialize_encoder_ref(attr->encode, tmp_encoders, out); + if (attr->extraAttributes) { + i = zend_hash_num_elements(attr->extraAttributes); + } else { + i = 0; + } + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + sdlExtraAttributePtr *tmp; + zend_hash_internal_pointer_reset(attr->extraAttributes); + while (zend_hash_get_current_data(attr->extraAttributes, (void**)&tmp) == SUCCESS) { + sdl_serialize_key(attr->extraAttributes, out); + sdl_serialize_string((*tmp)->ns, out); + sdl_serialize_string((*tmp)->val, out); + zend_hash_move_forward(attr->extraAttributes); + } + } +} + +static void sdl_serialize_model(sdlContentModelPtr model, HashTable *tmp_types, HashTable *tmp_elements, smart_str *out) +{ + WSDL_CACHE_PUT_1(model->kind, out); + WSDL_CACHE_PUT_INT(model->min_occurs, out); + WSDL_CACHE_PUT_INT(model->max_occurs, out); + switch (model->kind) { + case XSD_CONTENT_ELEMENT: + sdl_serialize_type_ref(model->u.element, tmp_elements, out); + break; + case XSD_CONTENT_SEQUENCE: + case XSD_CONTENT_ALL: + case XSD_CONTENT_CHOICE: { + sdlContentModelPtr *tmp; + int i = zend_hash_num_elements(model->u.content); + + WSDL_CACHE_PUT_INT(i, out); + zend_hash_internal_pointer_reset(model->u.content); + while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) { + sdl_serialize_model(*tmp, tmp_types, tmp_elements, out); + zend_hash_move_forward(model->u.content); + } + } + break; + case XSD_CONTENT_GROUP_REF: + sdl_serialize_string(model->u.group_ref,out); + break; + case XSD_CONTENT_GROUP: + sdl_serialize_type_ref(model->u.group, tmp_types, out); + break; + default: + break; + } +} + +static void sdl_serialize_resriction_int(sdlRestrictionIntPtr x, smart_str *out) +{ + if (x) { + WSDL_CACHE_PUT_1(1, out); + WSDL_CACHE_PUT_INT(x->value, out); + WSDL_CACHE_PUT_1(x->fixed, out); + } else { + WSDL_CACHE_PUT_1(0, out); + } +} + +static void sdl_serialize_resriction_char(sdlRestrictionCharPtr x, smart_str *out) +{ + if (x) { + WSDL_CACHE_PUT_1(1, out); + sdl_serialize_string(x->value, out); + WSDL_CACHE_PUT_1(x->fixed, out); + } else { + WSDL_CACHE_PUT_1(0, out); + } +} + +static void sdl_serialize_type(sdlTypePtr type, HashTable *tmp_encoders, HashTable *tmp_types, smart_str *out) +{ + int i; + HashTable *tmp_elements = NULL; + + WSDL_CACHE_PUT_1(type->kind, out); + sdl_serialize_string(type->name, out); + sdl_serialize_string(type->namens, out); + sdl_serialize_string(type->def, out); + sdl_serialize_string(type->fixed, out); + sdl_serialize_string(type->ref, out); + WSDL_CACHE_PUT_1(type->nillable, out); + sdl_serialize_encoder_ref(type->encode, tmp_encoders, out); + + if (type->restrictions) { + WSDL_CACHE_PUT_1(1, out); + sdl_serialize_resriction_int(type->restrictions->minExclusive,out); + sdl_serialize_resriction_int(type->restrictions->minInclusive,out); + sdl_serialize_resriction_int(type->restrictions->maxExclusive,out); + sdl_serialize_resriction_int(type->restrictions->maxInclusive,out); + sdl_serialize_resriction_int(type->restrictions->totalDigits,out); + sdl_serialize_resriction_int(type->restrictions->fractionDigits,out); + sdl_serialize_resriction_int(type->restrictions->length,out); + sdl_serialize_resriction_int(type->restrictions->minLength,out); + sdl_serialize_resriction_int(type->restrictions->maxLength,out); + sdl_serialize_resriction_char(type->restrictions->whiteSpace,out); + sdl_serialize_resriction_char(type->restrictions->pattern,out); + if (type->restrictions->enumeration) { + i = zend_hash_num_elements(type->restrictions->enumeration); + } else { + i = 0; + } + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + sdlRestrictionCharPtr *tmp; + + zend_hash_internal_pointer_reset(type->restrictions->enumeration); + while (zend_hash_get_current_data(type->restrictions->enumeration, (void**)&tmp) == SUCCESS) { + sdl_serialize_resriction_char(*tmp, out); + sdl_serialize_key(type->restrictions->enumeration, out); + zend_hash_move_forward(type->restrictions->enumeration); + } + } + } else { + WSDL_CACHE_PUT_1(0, out); + } + if (type->elements) { + i = zend_hash_num_elements(type->elements); + } else { + i = 0; + } + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + sdlTypePtr *tmp; + + tmp_elements = emalloc(sizeof(HashTable)); + zend_hash_init(tmp_elements, 0, NULL, NULL, 0); + + zend_hash_internal_pointer_reset(type->elements); + while (zend_hash_get_current_data(type->elements, (void**)&tmp) == SUCCESS) { + sdl_serialize_key(type->elements, out); + sdl_serialize_type(*tmp, tmp_encoders, tmp_types, out); + zend_hash_add(tmp_elements, (char*)tmp, sizeof(*tmp), &i, sizeof(int), NULL); + i--; + zend_hash_move_forward(type->elements); + } + } + + if (type->attributes) { + i = zend_hash_num_elements(type->attributes); + } else { + i = 0; + } + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + sdlAttributePtr *tmp; + zend_hash_internal_pointer_reset(type->attributes); + while (zend_hash_get_current_data(type->attributes, (void**)&tmp) == SUCCESS) { + sdl_serialize_key(type->attributes, out); + sdl_serialize_attribute(*tmp, tmp_encoders, out); + zend_hash_move_forward(type->attributes); + } + } + if (type->model) { + WSDL_CACHE_PUT_1(1, out); + sdl_serialize_model(type->model, tmp_types, tmp_elements, out); + } else { + WSDL_CACHE_PUT_1(0, out); + } + if (tmp_elements != NULL) { + zend_hash_destroy(tmp_elements); + efree(tmp_elements); + } +} + +static void sdl_serialize_encoder(encodePtr enc, HashTable *tmp_types, smart_str *out) +{ + WSDL_CACHE_PUT_INT(enc->details.type, out); + sdl_serialize_string(enc->details.type_str, out); + sdl_serialize_string(enc->details.ns, out); + sdl_serialize_type_ref(enc->details.sdl_type, tmp_types, out); +} + +static void sdl_serialize_parameters(HashTable *ht, HashTable *tmp_encoders, HashTable *tmp_types, smart_str *out) +{ + int i; + + if (ht) { + i = zend_hash_num_elements(ht); + } else { + i = 0; + } + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + sdlParamPtr *tmp; + + zend_hash_internal_pointer_reset(ht); + while (zend_hash_get_current_data(ht, (void**)&tmp) == SUCCESS) { + sdl_serialize_key(ht, out); + sdl_serialize_string((*tmp)->paramName, out); + WSDL_CACHE_PUT_INT((*tmp)->order, out); + sdl_serialize_encoder_ref((*tmp)->encode, tmp_encoders, out); + sdl_serialize_type_ref((*tmp)->element, tmp_types, out); + zend_hash_move_forward(ht); + } + } +} + +static void sdl_serialize_soap_body(sdlSoapBindingFunctionBodyPtr body, HashTable *tmp_encoders, HashTable *tmp_types, smart_str *out) +{ + int i; + + WSDL_CACHE_PUT_1(body->use, out); + sdl_serialize_string(body->ns, out); + sdl_serialize_string(body->parts, out); + sdl_serialize_string(body->encodingStyle, out); + if (body->headers) { + i = zend_hash_num_elements(body->headers); + } else { + i = 0; + } + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + sdlSoapBindingFunctionHeaderPtr *tmp; + zend_hash_internal_pointer_reset(body->headers); + while (zend_hash_get_current_data(body->headers, (void**)&tmp) == SUCCESS) { + sdl_serialize_key(body->headers, out); + WSDL_CACHE_PUT_1((*tmp)->use, out); + sdl_serialize_string((*tmp)->name, out); + sdl_serialize_string((*tmp)->ns, out); + sdl_serialize_string((*tmp)->encodingStyle, out); + sdl_serialize_encoder_ref((*tmp)->encode, tmp_encoders, out); + sdl_serialize_type_ref((*tmp)->element, tmp_types, out); + zend_hash_move_forward(body->headers); + } + } +} + +static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr sdl) +{ + smart_str buf = {0}; + smart_str *out = &buf; + int i; + int type_num = 1; + int encoder_num = 1; + int f; + encodePtr enc; + HashTable tmp_types; + HashTable tmp_encoders; + HashTable tmp_bindings; + HashTable tmp_functions; + + f = open(fn,O_CREAT|O_WRONLY|O_EXCL|O_BINARY,S_IREAD|S_IWRITE); + if (f < 0) {return;} + + zend_hash_init(&tmp_types, 0, NULL, NULL, 0); + zend_hash_init(&tmp_encoders, 0, NULL, NULL, 0); + zend_hash_init(&tmp_bindings, 0, NULL, NULL, 0); + zend_hash_init(&tmp_functions, 0, NULL, NULL, 0); + + WSDL_CACHE_PUT_N("wsdl", 4, out); + WSDL_CACHE_PUT_1(WSDL_CACHE_VERSION,out); + WSDL_CACHE_PUT_1(0,out); + WSDL_CACHE_PUT_N(&t, sizeof(t), out); + + sdl_serialize_string(uri, out); + sdl_serialize_string(sdl->source, out); + sdl_serialize_string(sdl->target_ns, out); + + if (sdl->groups) { + i = zend_hash_num_elements(sdl->groups); + } else { + i = 0; + } + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + sdlTypePtr *tmp; + + zend_hash_internal_pointer_reset(sdl->groups); + while (zend_hash_get_current_data(sdl->groups, (void**)&tmp) == SUCCESS) { + zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL); + ++type_num; + zend_hash_move_forward(sdl->groups); + } + } + + if (sdl->types) { + i = zend_hash_num_elements(sdl->types); + } else { + i = 0; + } + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + sdlTypePtr *tmp; + + zend_hash_internal_pointer_reset(sdl->types); + while (zend_hash_get_current_data(sdl->types, (void**)&tmp) == SUCCESS) { + zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL); + ++type_num; + zend_hash_move_forward(sdl->types); + } + } + + if (sdl->elements) { + i = zend_hash_num_elements(sdl->elements); + } else { + i = 0; + } + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + sdlTypePtr *tmp; + + zend_hash_internal_pointer_reset(sdl->elements); + while (zend_hash_get_current_data(sdl->elements, (void**)&tmp) == SUCCESS) { + zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL); + ++type_num; + zend_hash_move_forward(sdl->elements); + } + } + + if (sdl->encoders) { + i = zend_hash_num_elements(sdl->encoders); + } else { + i = 0; + } + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + encodePtr *tmp; + + zend_hash_internal_pointer_reset(sdl->encoders); + while (zend_hash_get_current_data(sdl->encoders, (void**)&tmp) == SUCCESS) { + zend_hash_add(&tmp_encoders, (char*)tmp, sizeof(*tmp), (void**)&encoder_num, sizeof(encoder_num), NULL); + ++encoder_num; + zend_hash_move_forward(sdl->encoders); + } + } + enc = defaultEncoding; + while (enc->details.type != END_KNOWN_TYPES) { + zend_hash_add(&tmp_encoders, (char*)&enc, sizeof(encodePtr), (void**)&encoder_num, sizeof(encoder_num), NULL); + enc++; + ++encoder_num; + } + + if (sdl->groups) { + sdlTypePtr *tmp; + zend_hash_internal_pointer_reset(sdl->groups); + while (zend_hash_get_current_data(sdl->groups, (void**)&tmp) == SUCCESS) { + sdl_serialize_key(sdl->groups, out); + sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out); + zend_hash_move_forward(sdl->groups); + } + } + + if (sdl->types) { + sdlTypePtr *tmp; + zend_hash_internal_pointer_reset(sdl->types); + while (zend_hash_get_current_data(sdl->types, (void**)&tmp) == SUCCESS) { + sdl_serialize_key(sdl->types, out); + sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out); + zend_hash_move_forward(sdl->types); + } + } + + if (sdl->elements) { + sdlTypePtr *tmp; + zend_hash_internal_pointer_reset(sdl->elements); + while (zend_hash_get_current_data(sdl->elements, (void**)&tmp) == SUCCESS) { + sdl_serialize_key(sdl->elements, out); + sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out); + zend_hash_move_forward(sdl->elements); + } + } + + if (sdl->encoders) { + encodePtr *tmp; + zend_hash_internal_pointer_reset(sdl->encoders); + while (zend_hash_get_current_data(sdl->encoders, (void**)&tmp) == SUCCESS) { + sdl_serialize_key(sdl->encoders, out); + sdl_serialize_encoder(*tmp, &tmp_types, out); + zend_hash_move_forward(sdl->encoders); + } + } + + /* serialize bindings */ + if (sdl->bindings) { + i = zend_hash_num_elements(sdl->bindings); + } else { + i = 0; + } + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + sdlBindingPtr *tmp; + int binding_num = 1; + + zend_hash_internal_pointer_reset(sdl->bindings); + while (zend_hash_get_current_data(sdl->bindings, (void**)&tmp) == SUCCESS) { + sdl_serialize_key(sdl->bindings, out); + sdl_serialize_string((*tmp)->name, out); + sdl_serialize_string((*tmp)->location, out); + WSDL_CACHE_PUT_1((*tmp)->bindingType,out); + if ((*tmp)->bindingType == BINDING_SOAP && (*tmp)->bindingAttributes != NULL) { + sdlSoapBindingPtr binding = (sdlSoapBindingPtr)(*tmp)->bindingAttributes; + WSDL_CACHE_PUT_1(binding->style, out); + sdl_serialize_string(binding->transport, out); + } else { + WSDL_CACHE_PUT_1(0,out); + } + + zend_hash_add(&tmp_bindings, (char*)tmp, sizeof(*tmp), (void**)&binding_num, sizeof(binding_num), NULL); + binding_num++; + zend_hash_move_forward(sdl->bindings); + } + } + + /* serialize functions */ + i = zend_hash_num_elements(&sdl->functions); + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + sdlFunctionPtr *tmp; + int *binding_num; + int function_num = 1; + + zend_hash_internal_pointer_reset(&sdl->functions); + while (zend_hash_get_current_data(&sdl->functions, (void**)&tmp) == SUCCESS) { + sdl_serialize_key(&sdl->functions, out); + sdl_serialize_string((*tmp)->functionName, out); + sdl_serialize_string((*tmp)->requestName, out); + sdl_serialize_string((*tmp)->responseName, out); + + if ((*tmp)->binding == NULL || + zend_hash_find(&tmp_bindings,(char*)&(*tmp)->binding,sizeof((*tmp)->binding), (void**)&binding_num) != SUCCESS) { + } + WSDL_CACHE_PUT_INT(*binding_num, out); + if (binding_num >= 0) { + if ((*tmp)->binding->bindingType == BINDING_SOAP && (*tmp)->bindingAttributes != NULL) { + sdlSoapBindingFunctionPtr binding = (sdlSoapBindingFunctionPtr)(*tmp)->bindingAttributes; + WSDL_CACHE_PUT_1(binding->style, out); + sdl_serialize_string(binding->soapAction, out); + sdl_serialize_soap_body(&binding->input, &tmp_encoders, &tmp_types, out); + sdl_serialize_soap_body(&binding->output, &tmp_encoders, &tmp_types, out); + /*sdl_serialize_soap_body(&binding->fault, &tmp_encoders, &tmp_types, out);*/ + } else { + WSDL_CACHE_PUT_1(0,out); + } + } + sdl_serialize_parameters((*tmp)->requestParameters, &tmp_encoders, &tmp_types, out); + sdl_serialize_parameters((*tmp)->responseParameters, &tmp_encoders, &tmp_types, out); + + zend_hash_add(&tmp_functions, (char*)tmp, sizeof(*tmp), (void**)&function_num, sizeof(function_num), NULL); + function_num++; + zend_hash_move_forward(&sdl->functions); + } + } + + /* serialize requests */ + if (sdl->requests) { + i = zend_hash_num_elements(sdl->requests); + } else { + i = 0; + } + WSDL_CACHE_PUT_INT(i, out); + if (i > 0) { + sdlFunctionPtr *tmp; + int *function_num; + + zend_hash_internal_pointer_reset(sdl->requests); + while (zend_hash_get_current_data(sdl->requests, (void**)&tmp) == SUCCESS) { + if (zend_hash_find(&tmp_functions, (char*)tmp, sizeof(*tmp), (void**)&function_num) != SUCCESS) { + } + WSDL_CACHE_PUT_INT(*function_num, out); + sdl_serialize_key(sdl->requests, out); + zend_hash_move_forward(sdl->requests); + } + } + + write(f, buf.c, buf.len); + close(f); + smart_str_free(&buf); + zend_hash_destroy(&tmp_functions); + zend_hash_destroy(&tmp_bindings); + zend_hash_destroy(&tmp_encoders); + zend_hash_destroy(&tmp_types); +} + +sdlPtr get_sdl(char *uri TSRMLS_DC) { #ifdef SDL_CACHE sdlPtr tmp, *hndl; @@ -768,7 +1829,43 @@ return tmp; #else - return load_wsdl(uri); + if (SOAP_GLOBAL(cache_enabled)) { + char fn[MAXPATHLEN]; + char* key; + sdlPtr sdl; + time_t t = time(0); + + char md5str[33]; + PHP_MD5_CTX context; + unsigned char digest[16]; + int len = strlen(SOAP_GLOBAL(cache_dir)); + + if (strchr(uri,':') != NULL || IS_ABSOLUTE_PATH(uri,strlen(uri))) { + strcpy(fn, uri); + } else if (VCWD_REALPATH(uri, fn) == NULL) { + return load_wsdl(uri); + } + md5str[0] = '\0'; + PHP_MD5Init(&context); + PHP_MD5Update(&context, fn, strlen(fn)); + PHP_MD5Final(digest, &context); + make_digest(md5str, digest); + key = do_alloca(len+sizeof("/wsdl-")-1+sizeof(md5str)); + memcpy(key,SOAP_GLOBAL(cache_dir),len); + memcpy(key+len,"/wsdl-",sizeof("/wsdl-")-1); + memcpy(key+len+sizeof("/wsdl-")-1,md5str,sizeof(md5str)); + + if ((sdl = get_sdl_from_cache(key, fn, t-SOAP_GLOBAL(cache_ttl))) == NULL) { + sdl = load_wsdl(fn); + if (sdl != NULL) { + add_sdl_to_cache(key, fn, t, sdl); + } + } + free_alloca(key); + return sdl; + } else { + return load_wsdl(uri); + } #endif } @@ -884,13 +1981,13 @@ } delete_sdl_soap_binding_function_body(soapFunction->input); delete_sdl_soap_binding_function_body(soapFunction->output); - delete_sdl_soap_binding_function_body(soapFunction->falut); + delete_sdl_soap_binding_function_body(soapFunction->fault); sdl_free(soapFunction); } sdl_free(function); } -static void delete_paramater(void *data) +static void delete_parameter(void *data) { sdlParamPtr param = *((sdlParamPtr*)data); if (param->paramName) { http://cvs.php.net/diff.php/php-src/ext/soap/php_sdl.h?r1=1.25&r2=1.26&ty=u Index: php-src/ext/soap/php_sdl.h diff -u php-src/ext/soap/php_sdl.h:1.25 php-src/ext/soap/php_sdl.h:1.26 --- php-src/ext/soap/php_sdl.h:1.25 Fri Feb 6 09:22:33 2004 +++ php-src/ext/soap/php_sdl.h Tue Feb 10 08:41:21 2004 @@ -17,7 +17,7 @@ | Dmitry Stogov <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: php_sdl.h,v 1.25 2004/02/06 14:22:33 dmitry Exp $ */ +/* $Id: php_sdl.h,v 1.26 2004/02/10 13:41:21 dmitry Exp $ */ #ifndef PHP_SDL_H #define PHP_SDL_H @@ -38,14 +38,20 @@ #define XSD_WHITESPACE_PRESERVE 1 #define XSD_WHITESPACE_REPLACE 1 -#define BINDING_SOAP 1 -#define BINDING_HTTP 2 - -#define SOAP_RPC 1 -#define SOAP_DOCUMENT 2 - -#define SOAP_ENCODED 1 -#define SOAP_LITERAL 2 +typedef enum _sdlBindingType { + BINDING_SOAP = 1, + BINDING_HTTP = 2 +} sdlBindingType; + +typedef enum _sdlEncodingStyle { + SOAP_RPC = 1, + SOAP_DOCUMENT = 2 +} sdlEncodingStyle; + +typedef enum _sdlEncodingUse { + SOAP_ENCODED = 1, + SOAP_LITERAL = 2 +} sdlEncodingUse; struct _sdl { HashTable functions; /* array of sdlFunction */ @@ -74,42 +80,42 @@ } sdlCtx; struct _sdlBinding { - char *name; - char *location; - int bindingType; - void *bindingAttributes; /* sdlSoapBindingPtr */ + char *name; + char *location; + sdlBindingType bindingType; + void *bindingAttributes; /* sdlSoapBindingPtr */ }; /* Soap Binding Specfic stuff */ struct _sdlSoapBinding { - char *transport; - int style; + char *transport; + sdlEncodingStyle style; }; typedef struct _sdlSoapBindingFunctionHeader { - char *name; - char *ns; - int use; - sdlTypePtr element; - encodePtr encode; - char *encodingStyle; /* not implemented yet */ + char *name; + char *ns; + sdlEncodingUse use; + sdlTypePtr element; + encodePtr encode; + char *encodingStyle; /* not implemented yet */ } sdlSoapBindingFunctionHeader, *sdlSoapBindingFunctionHeaderPtr; struct _sdlSoapBindingFunctionBody { - char *ns; - int use; - char *parts; /* not implemented yet */ - char *encodingStyle; /* not implemented yet */ - HashTable *headers; /* array of sdlSoapBindingFunctionHeaderPtr */ + char *ns; + sdlEncodingUse use; + char *parts; /* not implemented yet */ + char *encodingStyle; /* not implemented yet */ + HashTable *headers; /* array of sdlSoapBindingFunctionHeaderPtr */ }; struct _sdlSoapBindingFunction { - char *soapAction; - int style; + char *soapAction; + sdlEncodingStyle style; - sdlSoapBindingFunctionBody input; - sdlSoapBindingFunctionBody output; - sdlSoapBindingFunctionBody falut; + sdlSoapBindingFunctionBody input; + sdlSoapBindingFunctionBody output; + sdlSoapBindingFunctionBody fault; }; struct _sdlRestrictionInt { @@ -155,7 +161,7 @@ int max_occurs; union { sdlTypePtr element; /* pointer to element */ - sdlContentModelPtr group; /* pointer to group */ + sdlTypePtr group; /* pointer to group */ HashTable *content; /* array of sdlContentModel for sequnce,all,choice*/ char *group_ref; /* reference to group */ } u; @@ -174,7 +180,7 @@ sdlTypeKind kind; char *name; char *namens; - int nillable; + char nillable; HashTable *elements; /* array of sdlTypePtr */ HashTable *attributes; /* array of sdlAttributePtr */ sdlRestrictionsPtr restrictions; @@ -231,7 +237,7 @@ encodePtr encode; }; -sdlPtr get_sdl(char *uri); +sdlPtr get_sdl(char *uri TSRMLS_DC); encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr data, const char *type); encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type); http://cvs.php.net/diff.php/php-src/ext/soap/php_soap.h?r1=1.27&r2=1.28&ty=u Index: php-src/ext/soap/php_soap.h diff -u php-src/ext/soap/php_soap.h:1.27 php-src/ext/soap/php_soap.h:1.28 --- php-src/ext/soap/php_soap.h:1.27 Fri Feb 6 06:56:03 2004 +++ php-src/ext/soap/php_soap.h Tue Feb 10 08:41:21 2004 @@ -17,7 +17,7 @@ | Dmitry Stogov <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: php_soap.h,v 1.27 2004/02/06 11:56:03 dmitry Exp $ */ +/* $Id: php_soap.h,v 1.28 2004/02/10 13:41:21 dmitry Exp $ */ #ifndef PHP_SOAP_H #define PHP_SOAP_H @@ -148,6 +148,9 @@ int soap_version; sdlPtr sdl; zend_bool use_soap_error_handler; + zend_bool cache_enabled; + char* cache_dir; + long cache_ttl; ZEND_END_MODULE_GLOBALS(soap) #ifdef PHP_WIN32 http://cvs.php.net/diff.php/php-src/ext/soap/soap.c?r1=1.76&r2=1.77&ty=u Index: php-src/ext/soap/soap.c diff -u php-src/ext/soap/soap.c:1.76 php-src/ext/soap/soap.c:1.77 --- php-src/ext/soap/soap.c:1.76 Mon Feb 9 04:31:12 2004 +++ php-src/ext/soap/soap.c Tue Feb 10 08:41:21 2004 @@ -17,7 +17,7 @@ | Dmitry Stogov <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: soap.c,v 1.76 2004/02/09 09:31:12 dmitry Exp $ */ +/* $Id: soap.c,v 1.77 2004/02/10 13:41:21 dmitry Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -278,6 +278,20 @@ ZEND_GET_MODULE(soap) #endif +PHP_INI_BEGIN() +STD_PHP_INI_ENTRY("soap.wsdl_cache_enabled", "1", PHP_INI_ALL, OnUpdateBool, + cache_enabled, zend_soap_globals, soap_globals) +STD_PHP_INI_ENTRY("soap.wsdl_cache_dir", "/tmp", PHP_INI_ALL, OnUpdateString, + cache_dir, zend_soap_globals, soap_globals) +#ifdef ZEND_ENGINE_2 +STD_PHP_INI_ENTRY("soap.wsdl_cache_ttl", "86400", PHP_INI_ALL, OnUpdateLong, + cache_ttl, zend_soap_globals, soap_globals) +#else +STD_PHP_INI_ENTRY("soap.wsdl_cache_ttl", "86400", PHP_INI_ALL, OnUpdateInt, + cache_ttl, zend_soap_globals, soap_globals) +#endif +PHP_INI_END() + static void php_soap_init_globals(zend_soap_globals *soap_globals) { int i; @@ -343,6 +357,7 @@ /* TODO: add ini entry for always use soap errors */ ZEND_INIT_MODULE_GLOBALS(soap, php_soap_init_globals, NULL); + REGISTER_INI_ENTRIES(); #ifndef ZEND_ENGINE_2 /* Enable php stream/wrapper support for libxml */ @@ -489,6 +504,7 @@ php_info_print_table_row(2, "Soap Client", "enabled"); php_info_print_table_row(2, "Soap Server", "enabled"); php_info_print_table_end(); + DISPLAY_INI_ENTRIES(); } #ifdef HAVE_PHP_DOMXML @@ -695,7 +711,7 @@ zend_hash_init(service->soap_functions.ft, 0, NULL, ZVAL_PTR_DTOR, 0); if (wsdl) { - service->sdl = get_sdl(Z_STRVAL_P(wsdl)); + service->sdl = get_sdl(Z_STRVAL_P(wsdl) TSRMLS_CC); if (service->uri == NULL) { if (service->sdl->target_ns) { service->uri = estrdup(service->sdl->target_ns); @@ -1130,6 +1146,7 @@ php_error(E_ERROR, "PHP-SOAP requires 'always_populate_raw_post_data' to be on please check your php.ini file"); } php_error(E_ERROR, "Can't find HTTP_RAW_POST_DATA"); + return; } } else { doc_request = soap_xmlParseMemory(arg,arg_len); @@ -1577,7 +1594,7 @@ old_soap_version = SOAP_GLOBAL(soap_version); SOAP_GLOBAL(soap_version) = soap_version; - sdl = get_sdl(Z_STRVAL_P(wsdl)); + sdl = get_sdl(Z_STRVAL_P(wsdl) TSRMLS_CC); ret = zend_list_insert(sdl, le_sdl); add_property_resource(this_ptr, "sdl", ret);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php