From 1dcf2467cfa4b4642ef9d1dbc821ed02091e33bb Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 16 Jan 2004 12:31:10 +0000 Subject: [PATCH] WSDL support was improved support for message/part element attribute was implemented support for portType operation input/output name attribute was implemented --- ext/soap/TODO | 30 +++++++---- ext/soap/php_sdl.c | 124 ++++++++++++++++++++++++++++++++++++--------- ext/soap/php_sdl.h | 1 + ext/soap/soap.c | 53 ++++++++++++------- 4 files changed, 155 insertions(+), 53 deletions(-) diff --git a/ext/soap/TODO b/ext/soap/TODO index 02b3f3aaa7..de30f9daf0 100644 --- a/ext/soap/TODO +++ b/ext/soap/TODO @@ -64,6 +64,7 @@ Encoding + references (id,href) + SOAP 1.2 (enc:id,enc:ref) - references to external resources +? support for "nillable" and "nil" - default values - root attribute ? provide schema 1999/2001 support??? @@ -73,13 +74,30 @@ Encoding WSDL ---- + wsdl and schema import ++ support for message/part element attribute ++ support for portType operation input/output name attribute + support for without +- support for portType operation parameterOrder attribute +- support for binding operation input/output name attribute +- support for + support for style "rpc"/"document" encoding (client part) - support for style "rpc"/"document" encoding (server part) How to get function name from request? May be SoapAction HTTP header? + support for "encoded"/"literal" encoding ? arrayType and "literal" encoding -? support for "nillable" and "nil" +- function/method overloading/redeclaration (test(int); test(string)) +- wsdl caching +- wsdl auto generation +? SOAP binding + - parts attribute + - + - and +- HTTP GET/POST binding +- MIME binding +- SOAP 1.2 bindings??? + +Schema +------ - support for user defined simple types - restiction + base @@ -120,16 +138,6 @@ WSDL - sequence - any ??? - attribute -- function/method overloading/redeclaration (test(int); test(string)) -- wsdl caching -- wsdl auto generation -? SOAP binding - ? - - "parts" - - - - and -- HTTP GET/POST binding -- MIME binding Error Handling -------------- diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index 1fe5a33f47..51d9667abc 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -28,6 +28,47 @@ encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr data, const char *type) return enc; } +encodePtr get_encoder_from_element(sdlPtr sdl, xmlNodePtr node, const char *type) +{ + encodePtr enc = NULL; + TSRMLS_FETCH(); + + if (sdl && sdl->types) { + xmlNsPtr nsptr; + char *ns, *cptype; + sdlTypePtr *sdl_type; + + parse_namespace(type, &cptype, &ns); + nsptr = xmlSearchNs(node->doc, node, ns); + if (nsptr != NULL) { + smart_str nscat = {0}; + + smart_str_appends(&nscat, nsptr->href); + smart_str_appendc(&nscat, ':'); + smart_str_appends(&nscat, cptype); + smart_str_0(&nscat); + + if (zend_hash_find(sdl->types, nscat.c, nscat.len + 1, (void **)&sdl_type) == SUCCESS) { + enc = (*sdl_type)->encode; + } else if (zend_hash_find(sdl->types, (char*)type, strlen(type) + 1, (void **)&sdl_type) == SUCCESS) { + enc = (*sdl_type)->encode; + } + smart_str_free(&nscat); + } else { + if (zend_hash_find(sdl->types, (char*)type, strlen(type) + 1, (void **)&sdl_type) == SUCCESS) { + enc = (*sdl_type)->encode; + } + } + + if (cptype) {efree(cptype);} + if (ns) {efree(ns);} + } + if (enc == NULL) { + enc = get_conversion(UNKNOWN_TYPE); + } + return enc; +} + encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type) { encodePtr enc = NULL; @@ -569,20 +610,28 @@ static sdlPtr load_wsdl(char *struri) } input = get_node(operation->children, "input"); + portTypeInput = get_node(portTypeOperation->children, "input"); + + output = get_node(operation->children, "output"); + portTypeOutput = get_node(portTypeOperation->children, "output"); + if (input != NULL) { - xmlAttrPtr message; + xmlAttrPtr message, name; xmlNodePtr part, trav3; char *ns, *ctype; - portTypeInput = get_node(portTypeOperation->children, "input"); if (portTypeInput) { message = get_attribute(portTypeInput->properties, "message"); if (message == NULL) { php_error(E_ERROR, "Error parsing wsdl (Missing name for \"input\" of \"%s\")", op_name->children->content); } - /* FIXME: may be input message name */ - function->requestName = strdup(function->functionName); + name = get_attribute(portTypeInput->properties, "name"); + if (name != NULL) { + function->requestName = strdup(name->children->content); + } else { + function->requestName = strdup(function->functionName); + } function->requestParameters = malloc(sizeof(HashTable)); zend_hash_init(function->requestParameters, 0, NULL, delete_paramater, 1); @@ -642,14 +691,14 @@ static sdlPtr load_wsdl(char *struri) param->paramName = strdup(name->children->content); - element = get_attribute(part->properties, "element"); - if (element != NULL) { - param->encode = get_encoder_from_prefix(ctx.root, part, element->children->content); - } - type = get_attribute(part->properties, "type"); if (type != NULL) { param->encode = get_encoder_from_prefix(ctx.root, part, type->children->content); + } else { + element = get_attribute(part->properties, "element"); + if (element != NULL) { + param->encode = get_encoder_from_element(ctx.root, part, element->children->content); + } } zend_hash_next_index_insert(function->requestParameters, ¶m, sizeof(sdlParamPtr), NULL); @@ -657,23 +706,23 @@ static sdlPtr load_wsdl(char *struri) ENDFOREACH(trav3); } - paramOrder = get_attribute(portTypeOperation->properties, "parameterOrder"); - if (paramOrder) { - /* FIXME: */ - } } - output = get_node(operation->children, "output"); if (output != NULL) { - xmlAttrPtr message; + xmlAttrPtr message, name; xmlNodePtr part, trav3; char *ns, *ctype; - portTypeOutput = get_node(portTypeOperation->children, "output"); if (portTypeOutput) { - /* FIXME: may be output message name */ - function->responseName = malloc(strlen(function->functionName) + strlen("Response") + 1); - sprintf(function->responseName, "%sResponse", function->functionName); + name = get_attribute(portTypeOutput->properties, "name"); + if (name != NULL) { + function->responseName = strdup(name->children->content); + } else if (input == NULL) { + function->responseName = strdup(function->functionName); + } else { + function->responseName = malloc(strlen(function->functionName) + strlen("Response") + 1); + sprintf(function->responseName, "%sResponse", function->functionName); + } function->responseParameters = malloc(sizeof(HashTable)); zend_hash_init(function->responseParameters, 0, NULL, delete_paramater, 1); @@ -737,14 +786,15 @@ static sdlPtr load_wsdl(char *struri) param->paramName = strdup(name->children->content); - element = get_attribute(part->properties, "element"); - if (element) { - param->encode = get_encoder_from_prefix(ctx.root, part, element->children->content); - } type = get_attribute(part->properties, "type"); if (type) { param->encode = get_encoder_from_prefix(ctx.root, part, type->children->content); + } else { + element = get_attribute(part->properties, "element"); + if (element) { + param->encode = get_encoder_from_element(ctx.root, part, element->children->content); + } } zend_hash_next_index_insert(function->responseParameters, ¶m, sizeof(sdlParamPtr), NULL); @@ -753,12 +803,34 @@ static sdlPtr load_wsdl(char *struri) } } + paramOrder = get_attribute(portTypeOperation->properties, "parameterOrder"); + if (paramOrder) { + /* FIXME: */ + } + fault = get_node(operation->children, "fault"); if (!fault) { } function->binding = tmpbinding; - zend_hash_add(&ctx.root->functions, php_strtolower(function->functionName, strlen(function->functionName)), strlen(function->functionName), &function, sizeof(sdlFunctionPtr), NULL); + + { + char *tmp = estrdup(function->functionName); + int len = strlen(tmp); + + zend_hash_add(&ctx.root->functions, php_strtolower(tmp, len), len+1, &function, sizeof(sdlFunctionPtr), NULL); + efree(tmp); + if (function->requestName != NULL && strcmp(function->requestName,function->functionName) != 0) { + if (ctx.root->requests == NULL) { + ctx.root->requests = malloc(sizeof(HashTable)); + zend_hash_init(ctx.root->requests, 0, NULL, NULL, 1); + } + tmp = estrdup(function->requestName); + len = strlen(tmp); + zend_hash_add(ctx.root->requests, php_strtolower(tmp, len), len+1, &function, sizeof(sdlFunctionPtr), NULL); + efree(tmp); + } + } } ENDFOREACH(trav2); @@ -827,6 +899,10 @@ void delete_sdl(void *handle) zend_hash_destroy(tmp->bindings); free(tmp->bindings); } + if (tmp->encoders) { + zend_hash_destroy(tmp->requests); + free(tmp->requests); + } free(tmp); } diff --git a/ext/soap/php_sdl.h b/ext/soap/php_sdl.h index 1e7baf7273..9b35bd2fcf 100644 --- a/ext/soap/php_sdl.h +++ b/ext/soap/php_sdl.h @@ -20,6 +20,7 @@ struct _sdl { HashTable *types; /* array of sdlTypesPtr */ HashTable *encoders; /* array of encodePtr */ HashTable *bindings; /* array of sdlBindings (key'd by name) */ + HashTable *requests; /* array of sdlFunction (references) */ char *target_ns; char *source; }; diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 7eee91f227..53ec1c9a7e 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -16,7 +16,7 @@ static void clear_soap_fault(zval *obj TSRMLS_DC); static void set_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail TSRMLS_DC); static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, int); -static sdlFunctionPtr get_function(sdlPtr sdl, char *function_name); +static sdlFunctionPtr get_function(sdlPtr sdl, const char *function_name); static void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *function_name, int *num_params, zval **parameters[], int *version TSRMLS_DC); static xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_name,char *uri,zval *ret, int version TSRMLS_DC); @@ -968,7 +968,7 @@ PHP_METHOD(soapserver, handle) soapServicePtr service; xmlDocPtr doc_request, doc_return; zval function_name, **params, **raw_post, *soap_obj, retval, **server_vars; - char *fn_name, cont_len[30], *response_name; + char *fn_name, cont_len[30]; int num_params = 0, size, i, call_status; xmlChar *buf; HashTable *function_table; @@ -1064,10 +1064,6 @@ PHP_METHOD(soapserver, handle) deseralize_function_call(service->sdl, doc_request, &function_name, &num_params, ¶ms, &soap_version TSRMLS_CC); xmlFreeDoc(doc_request); - fn_name = estrndup(Z_STRVAL(function_name),Z_STRLEN(function_name)); - response_name = emalloc(Z_STRLEN(function_name) + strlen("Response") + 1); - sprintf(response_name,"%sResponse",fn_name); - if (service->type == SOAP_CLASS) { soap_obj = NULL; #if HAVE_PHP_SESSION @@ -1139,7 +1135,9 @@ PHP_METHOD(soapserver, handle) } doc_return = NULL; - if (zend_hash_exists(function_table, php_strtolower(Z_STRVAL(function_name), Z_STRLEN(function_name)), Z_STRLEN(function_name) + 1)) { + + fn_name = estrndup(Z_STRVAL(function_name),Z_STRLEN(function_name)); + if (zend_hash_exists(function_table, php_strtolower(fn_name, Z_STRLEN(function_name)), Z_STRLEN(function_name) + 1)) { if (service->type == SOAP_CLASS) { call_status = call_user_function(NULL, &soap_obj, &function_name, &retval, num_params, params TSRMLS_CC); if (service->soap_class.persistance != SOAP_PERSISTENCE_SESSION) { @@ -1151,14 +1149,22 @@ PHP_METHOD(soapserver, handle) } else { php_error(E_ERROR, "Function (%s) doesn't exist", Z_STRVAL(function_name)); } + efree(fn_name); if (call_status == SUCCESS) { sdlFunctionPtr function; - /* TODO: make 'strict' (use the sdl defnintions) */ + char *response_name; function = get_function(service->sdl, Z_STRVAL(function_name)); + if (function && function->responseName) { + response_name = estrdup(function->responseName); + } else { + response_name = emalloc(Z_STRLEN(function_name) + strlen("Response") + 1); + sprintf(response_name,"%sResponse",Z_STRVAL(function_name)); + } SOAP_GLOBAL(overrides) = service->mapping; doc_return = seralize_response_call(function, response_name, service->uri, &retval, soap_version TSRMLS_CC); SOAP_GLOBAL(overrides) = NULL; + efree(response_name); } else { php_error(E_ERROR, "Function (%s) call failed", Z_STRVAL(function_name)); } @@ -1194,7 +1200,6 @@ PHP_METHOD(soapserver, handle) zval_dtor(&function_name); xmlFreeDoc(doc_return); - efree(response_name); efree(fn_name); php_write(buf, size TSRMLS_CC); @@ -1422,7 +1427,6 @@ zend_try { old_sdl = SOAP_GLOBAL(sdl); SOAP_GLOBAL(sdl) = sdl; if (sdl != NULL) { - php_strtolower(function, function_len); fn = get_function(sdl, function); if (fn != NULL) { sdlBindingPtr binding = fn->binding; @@ -1833,16 +1837,20 @@ static void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *functi php_error(E_ERROR,"looks like we got \"Body\" without function call\n"); } - INIT_ZVAL(tmp_function_name); - ZVAL_STRING(&tmp_function_name, (char *)func->name, 1); - - (*function_name) = tmp_function_name; - - function = get_function(sdl, php_strtolower((char *)func->name, strlen(func->name))); + function = get_function(sdl, func->name); if (sdl != NULL && function == NULL) { php_error(E_ERROR, "Error function \"%s\" doesn't exists for this service", func->name); } + INIT_ZVAL(tmp_function_name); + if (function != NULL) { + ZVAL_STRING(&tmp_function_name, (char *)function->functionName, 1); + } else{ + ZVAL_STRING(&tmp_function_name, (char *)func->name, 1); + } + + (*function_name) = tmp_function_name; + if (function != NULL) { sdlParamPtr *param; xmlNodePtr val; @@ -2252,14 +2260,23 @@ static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int inde return NULL; } -static sdlFunctionPtr get_function(sdlPtr sdl, char *function_name) +static sdlFunctionPtr get_function(sdlPtr sdl, const char *function_name) { sdlFunctionPtr *tmp; + + int len = strlen(function_name); + char *str = estrndup(function_name,len); + php_strtolower(str,len); if (sdl != NULL) { - if (zend_hash_find(&sdl->functions, function_name, strlen(function_name), (void **)&tmp) != FAILURE) { + if (zend_hash_find(&sdl->functions, str, len+1, (void **)&tmp) != FAILURE) { + efree(str); + return (*tmp); + } else if (sdl->requests != NULL && zend_hash_find(sdl->requests, str, len+1, (void **)&tmp) != FAILURE) { + efree(str); return (*tmp); } } + efree(str); return NULL; } -- 2.40.0