summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2004-01-16 12:31:10 +0000
committerDmitry Stogov <dmitry@php.net>2004-01-16 12:31:10 +0000
commit1dcf2467cfa4b4642ef9d1dbc821ed02091e33bb (patch)
treef0243f0097c2b58cfa28ddb82d6a39a6ed631009
parent88b2348f9fc359c0d6457efe1b71cdc98044054e (diff)
downloadphp-git-1dcf2467cfa4b4642ef9d1dbc821ed02091e33bb.tar.gz
WSDL support was improved
support for message/part element attribute was implemented support for portType operation input/output name attribute was implemented
-rw-r--r--ext/soap/TODO30
-rw-r--r--ext/soap/php_sdl.c124
-rw-r--r--ext/soap/php_sdl.h1
-rw-r--r--ext/soap/soap.c53
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 <opperation> without <input>
+- support for portType operation parameterOrder attribute
+- support for binding operation input/output name attribute
+- support for <opperation> <fault>
+ 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
+ - <soap:body> parts attribute
+ - <soap:fault>
+ - <soap:header> and <soap:headerfault>
+- 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
- ? <soap:body>
- - "parts"
- - <soap:fault>
- - <soap:header> and <soap:headerfault>
-- 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, &param, 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, &param, 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, &params, &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;
}