Browse Source

WSDL support was improved

support for message/part element attribute was implemented
 support for portType operation input/output name attribute was implemented
PEAR_1_4DEV
Dmitry Stogov 22 years ago
parent
commit
1dcf2467cf
  1. 30
      ext/soap/TODO
  2. 124
      ext/soap/php_sdl.c
  3. 1
      ext/soap/php_sdl.h
  4. 53
      ext/soap/soap.c

30
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
--------------

124
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);
}

1
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;
};

53
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;
}

Loading…
Cancel
Save