From 8f0ea19fcb4baa90edda4422cf376ec583cff96c Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 14 Jan 2004 12:49:02 +0000 Subject: WSDL: encoding rpc/document and encoded/literal --- ext/soap/TODO | 13 +++- ext/soap/php_encoding.c | 29 +++++++- ext/soap/php_encoding.h | 6 +- ext/soap/php_http.c | 2 +- ext/soap/php_sdl.c | 171 ++++++++++++++++++++++++++---------------------- ext/soap/soap.c | 166 +++++++++++++++++++++++++++++----------------- 6 files changed, 239 insertions(+), 148 deletions(-) (limited to 'ext') diff --git a/ext/soap/TODO b/ext/soap/TODO index 4c4c23de7f..f517b4408a 100644 --- a/ext/soap/TODO +++ b/ext/soap/TODO @@ -53,7 +53,7 @@ Encoding ? arrays of arrays - encoding of arrays with holes - full support for structures??? -- references (id,href) ++ references (id,href) - references to external resources - default values - root attribute @@ -65,8 +65,11 @@ WSDL ---- + wsdl and schema import + support for without -? support for style "rpc"/"document" encoding -? support for "encoded"/"literal" encoding ++ support for style "rpc"/"document" encoding (client part) +- support for style "rpc"/"document" encoding (server part) + How to get function name from request? ++ support for "encoded"/"literal" encoding +? arrayType and "literal" encoding ? support for "nillable" and "nil" - support for user defined simple types - restiction @@ -112,6 +115,10 @@ WSDL - wsdl caching - wsdl auto generation ? SOAP binding + ? + - "parts" + - + - and - HTTP GET/POST binding - MIME binding diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index d76225c483..09c3700fde 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -773,6 +773,7 @@ static xmlNodePtr to_xml_array(encodeType type, zval *data, int style) if (Z_TYPE_P(data) == IS_ARRAY) { i = zend_hash_num_elements(Z_ARRVAL_P(data)); + /*FIXME: arrayType and "literal" encoding? */ if (i > 0 && style == SOAP_ENCODED) { get_array_type(data, &array_type TSRMLS_CC); smart_str_append(&array_type_and_size, &array_type); @@ -859,7 +860,9 @@ zval *to_zval_array(encodeType type, xmlNodePtr data) int* pos = NULL; xmlAttrPtr arrayTypeAttr; xmlAttrPtr offsetAttr; + xmlAttrPtr *tmp; sdlPtr sdl; + sdlAttributePtr *arrayType; TSRMLS_FETCH(); @@ -888,6 +891,30 @@ zval *to_zval_array(encodeType type, xmlNodePtr data) } efree(type); if (ns) {efree(ns);} + } else if (type.sdl_type != NULL && + type.sdl_type->attributes != NULL && + zend_hash_find(type.sdl_type->attributes, SOAP_ENC_NAMESPACE":arrayType", + sizeof(SOAP_ENC_NAMESPACE":arrayType"), + (void **)&arrayType) == SUCCESS && + zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&tmp) == SUCCESS) { + char *type, *end, *ns; + xmlNsPtr nsptr; + + arrayTypeAttr = *tmp; + parse_namespace(arrayTypeAttr->children->content, &type, &ns); + nsptr = xmlSearchNs(arrayTypeAttr->doc, arrayTypeAttr->parent, ns); + + end = strrchr(type,'['); + if (end) { + *end = '\0'; + } + if (nsptr != NULL) { + enc = get_encoder(SOAP_GLOBAL(sdl), nsptr->href, type); + } + efree(type); + if (ns) {efree(ns);} + dims = emalloc(sizeof(int)); + *dims = 0; } if (dims == NULL) { dims = emalloc(sizeof(int)); @@ -1177,7 +1204,7 @@ static xmlNodePtr to_xml_datetime_ex(encodeType type, zval *data, char *format, } /* Time zone support */ -#if HAVE_TM_GMTOFF +#if HAVE_TM_GMTOFF sprintf(tzbuf, "%c%02d%02d", (ta->tm_gmtoff < 0) ? '-' : '+', abs(ta->tm_gmtoff / 3600), abs( (ta->tm_gmtoff % 3600) / 60 )); #else sprintf(tzbuf, "%c%02d%02d", ((ta->tm_isdst ? tzone - 3600:tzone)>0)?'-':'+', abs((ta->tm_isdst ? tzone - 3600 : tzone) / 3600), abs(((ta->tm_isdst ? tzone - 3600 : tzone) % 3600) / 60)); diff --git a/ext/soap/php_encoding.h b/ext/soap/php_encoding.h index c71c2b2155..4f63d74ca5 100644 --- a/ext/soap/php_encoding.h +++ b/ext/soap/php_encoding.h @@ -121,11 +121,11 @@ #define WSDL_NAMESPACE "http://schemas.xmlsoap.org/wsdl/" #define WSDL_NS_PREFIX "wsdl" -#define WSDL_SOAP_NAMESPACE "http://schemas.xmlsoap.org/wsdl/soap/" +#define WSDL_SOAP11_NAMESPACE "http://schemas.xmlsoap.org/wsdl/soap/" +#define WSDL_SOAP12_NAMESPACE "http://www.w3.org/2003/05/soap-rpc" +#define WSDL_SOAP12OLD_NAMESPACE "http://schemas.xmlsoap.org/wsdl/soap12/" #define WSDL_SOAP_NS_PREFIX "wsdlSoap" -#define WSDL_SOAP12_NAMESPACE "http://schemas.xmlsoap.org/wsdl/soap12/" - #define WSDL_HTTP_NAMESPACE "http://schemas.xmlsoap.org/wsdl/http/" #define WSDL_HTTP_NS_PREFIX "http" diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 361585d477..0716597495 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -129,8 +129,8 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so /* "Connection: close\r\n" "Accept: text/html; text/xml; text/plain\r\n" - "User-Agent: PHP SOAP 0.1\r\n" */ + "User-Agent: PHP SOAP 0.1\r\n" "Content-Type: text/xml; charset=\"utf-8\"\r\n" "Content-Length: "); smart_str_append_long(&soap_headers, buf_size); diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index bd91028231..bb28fd4980 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -107,7 +107,7 @@ encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const char *ns, const enc->details.sdl_type = cur_type; enc->to_xml = sdl_guess_convert_xml; enc->to_zval = sdl_guess_convert_zval; - + if (enc_ptr == NULL) { zend_hash_update(sdl->encoders, nscat.c, nscat.len + 1, &enc, sizeof(encodePtr), NULL); } @@ -213,6 +213,7 @@ static xmlNodePtr sdl_to_xml_array(encodeType enc_type, zval *data, int style) sdlAttributePtr *arrayType; i = zend_hash_num_elements(Z_ARRVAL_P(data)); +/* FIXME: Is arrayType needed? What about enc? */ if (style == SOAP_ENCODED) { xmlAttrPtr *wsdl; if (type->attributes && @@ -609,6 +610,7 @@ static sdlPtr load_wsdl(char *struri) xmlNodePtr address, binding, trav2; char *ns, *ctype; sdlBindingPtr tmpbinding; + char *wsdl_soap_namespace = NULL; tmpbinding = malloc(sizeof(sdlBinding)); memset(tmpbinding, 0, sizeof(sdlBinding)); @@ -636,9 +638,14 @@ static sdlPtr load_wsdl(char *struri) tmpbinding->location = strdup(location->children->content); - if (address->ns && !strcmp(address->ns->href, WSDL_SOAP_NAMESPACE)) { + if (address->ns && !strcmp(address->ns->href, WSDL_SOAP11_NAMESPACE)) { + wsdl_soap_namespace = WSDL_SOAP11_NAMESPACE; + tmpbinding->bindingType = BINDING_SOAP; + } else if (address->ns && !strcmp(address->ns->href, WSDL_SOAP12OLD_NAMESPACE)) { + wsdl_soap_namespace = WSDL_SOAP12OLD_NAMESPACE; tmpbinding->bindingType = BINDING_SOAP; } else if (address->ns && !strcmp(address->ns->href, WSDL_SOAP12_NAMESPACE)) { + wsdl_soap_namespace = WSDL_SOAP12_NAMESPACE; tmpbinding->bindingType = BINDING_SOAP; } else if (address->ns && !strcmp(address->ns->href, WSDL_HTTP_NAMESPACE)) { tmpbinding->bindingType = BINDING_HTTP; @@ -666,13 +673,13 @@ static sdlPtr load_wsdl(char *struri) soapBinding = malloc(sizeof(sdlSoapBinding)); memset(soapBinding, 0, sizeof(sdlSoapBinding)); - soapBinding->style = SOAP_RPC; + soapBinding->style = SOAP_DOCUMENT; - soapBindingNode = get_node_ex(binding->children, "binding", WSDL_SOAP_NAMESPACE); + soapBindingNode = get_node_ex(binding->children, "binding", wsdl_soap_namespace); if (soapBindingNode) { tmp = get_attribute(soapBindingNode->properties, "style"); - if (tmp && !strcmp(tmp->children->content, "document")) { - soapBinding->style = SOAP_DOCUMENT; + if (tmp && !strcmp(tmp->children->content, "rpc")) { + soapBinding->style = SOAP_RPC; } tmp = get_attribute(soapBindingNode->properties, "transport"); @@ -709,7 +716,7 @@ static sdlPtr load_wsdl(char *struri) trav2 = binding->children; FOREACHNODE(trav2, "operation", operation) { sdlFunctionPtr function; - xmlNodePtr input, output, fault, portTypeOperation, portTypeInput, msgInput, msgOutput; + xmlNodePtr input, output, fault, portTypeOperation, portTypeInput, portTypeOutput, msgInput, msgOutput; xmlAttrPtr op_name, paramOrder; op_name = get_attribute(operation->properties, "name"); @@ -741,7 +748,7 @@ static sdlPtr load_wsdl(char *struri) soapBinding = (sdlSoapBindingPtr)tmpbinding->bindingAttributes; soapFunctionBinding->style = soapBinding->style; - soapOperation = get_node_ex(operation->children, "operation", WSDL_SOAP_NAMESPACE); + soapOperation = get_node_ex(operation->children, "operation", wsdl_soap_namespace); if (soapOperation) { tmp = get_attribute(soapOperation->properties, "soapAction"); if (tmp) { @@ -749,10 +756,14 @@ static sdlPtr load_wsdl(char *struri) } tmp = get_attribute(soapOperation->properties, "style"); - if (tmp && !strcmp(tmp->children->content, "rpc")) { - soapFunctionBinding->style = SOAP_RPC; - } else if (!soapBinding->style) { - soapFunctionBinding->style = SOAP_DOCUMENT; + if (tmp) { + if (!strcmp(tmp->children->content, "rpc")) { + soapFunctionBinding->style = SOAP_RPC; + } else { + soapFunctionBinding->style = SOAP_DOCUMENT; + } + } else { + soapFunctionBinding->style = soapBinding->style; } } @@ -776,7 +787,7 @@ static sdlPtr load_wsdl(char *struri) function->requestName = strdup(function->functionName); function->requestParameters = malloc(sizeof(HashTable)); zend_hash_init(function->requestParameters, 0, NULL, delete_paramater, 1); - + parse_namespace(message->children->content, &ctype, &ns); if (zend_hash_find(&ctx.messages, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) { @@ -791,8 +802,8 @@ static sdlPtr load_wsdl(char *struri) sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes; xmlNodePtr body; xmlAttrPtr tmp; - - body = get_node_ex(input->children, "body", WSDL_SOAP_NAMESPACE); + + body = get_node_ex(input->children, "body", wsdl_soap_namespace); if (body) { tmp = get_attribute(body->properties, "use"); if (tmp && !strcmp(tmp->children->content, "literal")) { @@ -800,7 +811,7 @@ static sdlPtr load_wsdl(char *struri) } else { soapFunctionBinding->input.use = SOAP_ENCODED; } - + tmp = get_attribute(body->properties, "namespace"); if (tmp) { soapFunctionBinding->input.ns = strdup(tmp->children->content); @@ -854,91 +865,94 @@ static sdlPtr load_wsdl(char *struri) } } - output = get_node(portTypeOperation->children, "output"); + output = get_node(operation->children, "output"); if (output != NULL) { xmlAttrPtr message; xmlNodePtr part, trav3; char *ns, *ctype; - /* FIXME: may be output message name */ - 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); + 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); + function->responseParameters = malloc(sizeof(HashTable)); + zend_hash_init(function->responseParameters, 0, NULL, delete_paramater, 1); - message = get_attribute(output->properties, "message"); - if (message == NULL) { - php_error(E_ERROR, "Error parsing wsdl (Missing name for \"output\" of \"%s\")", op_name->children->content); - } + message = get_attribute(portTypeOutput->properties, "message"); + if (message == NULL) { + php_error(E_ERROR, "Error parsing wsdl (Missing name for \"output\" of \"%s\")", op_name->children->content); + } - parse_namespace(message->children->content, &ctype, &ns); - if (zend_hash_find(&ctx.messages, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) { - php_error(E_ERROR, "Error parsing wsdl (Missing \"message\" with name \"%s\")", message->children->content); - } - msgOutput = *tmp; + parse_namespace(message->children->content, &ctype, &ns); + if (zend_hash_find(&ctx.messages, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) { + php_error(E_ERROR, "Error parsing wsdl (Missing \"message\" with name \"%s\")", message->children->content); + } + msgOutput = *tmp; - if (ctype) {efree(ctype);} - if (ns) {efree(ns);} + if (ctype) {efree(ctype);} + if (ns) {efree(ns);} - if (tmpbinding->bindingType == BINDING_SOAP) { - sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes; - xmlNodePtr body; - xmlAttrPtr tmp; + if (tmpbinding->bindingType == BINDING_SOAP) { + sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes; + xmlNodePtr body; + xmlAttrPtr tmp; - body = get_node_ex(output->children, "body", WSDL_SOAP_NAMESPACE); - if (body) { - tmp = get_attribute(body->properties, "use"); - if (tmp && !strcmp(tmp->children->content, "literal")) { - soapFunctionBinding->output.use = SOAP_LITERAL; - } else { - soapFunctionBinding->output.use = SOAP_ENCODED; - } + body = get_node_ex(output->children, "body", wsdl_soap_namespace); + if (body) { + tmp = get_attribute(body->properties, "use"); + if (tmp && !strcmp(tmp->children->content, "literal")) { + soapFunctionBinding->output.use = SOAP_LITERAL; + } else { + soapFunctionBinding->output.use = SOAP_ENCODED; + } - tmp = get_attribute(body->properties, "namespace"); - if (tmp) { - soapFunctionBinding->output.ns = strdup(tmp->children->content); - } + tmp = get_attribute(body->properties, "namespace"); + if (tmp) { + soapFunctionBinding->output.ns = strdup(tmp->children->content); + } - tmp = get_attribute(body->properties, "parts"); - if (tmp) { - soapFunctionBinding->output.parts = strdup(tmp->children->content); - } + tmp = get_attribute(body->properties, "parts"); + if (tmp) { + soapFunctionBinding->output.parts = strdup(tmp->children->content); + } - tmp = get_attribute(body->properties, "encodingStyle"); - if (tmp) { - soapFunctionBinding->output.encodingStyle = strdup(tmp->children->content); + tmp = get_attribute(body->properties, "encodingStyle"); + if (tmp) { + soapFunctionBinding->output.encodingStyle = strdup(tmp->children->content); + } } } - } - trav3 = msgOutput->children; - FOREACHNODE(trav3, "part", part) { - sdlParamPtr param; - xmlAttrPtr element, type, name; + trav3 = msgOutput->children; + FOREACHNODE(trav3, "part", part) { + sdlParamPtr param; + xmlAttrPtr element, type, name; - param = malloc(sizeof(sdlParam)); - param->order = 0; + param = malloc(sizeof(sdlParam)); + param->order = 0; - name = get_attribute(part->properties, "name"); - if (name == NULL) { - php_error(E_ERROR, "Error parsing wsdl (No name associated with part \"%s\")", msgOutput->name); - } + name = get_attribute(part->properties, "name"); + if (name == NULL) { + php_error(E_ERROR, "Error parsing wsdl (No name associated with part \"%s\")", msgOutput->name); + } - param->paramName = strdup(name->children->content); + 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); - } + 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); - } + type = get_attribute(part->properties, "type"); + if (type) { + param->encode = get_encoder_from_prefix(ctx.root, part, type->children->content); + } - zend_hash_next_index_insert(function->responseParameters, ¶m, sizeof(sdlParamPtr), NULL); + zend_hash_next_index_insert(function->responseParameters, ¶m, sizeof(sdlParamPtr), NULL); + } + ENDFOREACH(trav3); } - ENDFOREACH(trav3); } fault = get_node(operation->children, "fault"); @@ -1229,4 +1243,3 @@ static void delete_document(void *doc_ptr) xmlDocPtr doc = *((xmlDocPtr*)doc_ptr); xmlFreeDoc(doc); } - diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 224b4e1c98..789b5b068d 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -1042,7 +1042,7 @@ PHP_METHOD(soapserver, handle) && ((*raw_post)->type==IS_STRING)) { int old_error_reporting = EG(error_reporting); EG(error_reporting) &= ~(E_WARNING|E_NOTICE|E_USER_WARNING|E_USER_NOTICE); - + doc_request = xmlParseMemory(Z_STRVAL_PP(raw_post),Z_STRLEN_PP(raw_post)); xmlCleanupParser(); @@ -1086,7 +1086,7 @@ PHP_METHOD(soapserver, handle) MAKE_STD_ZVAL(tmp_soap); object_init_ex(tmp_soap, service->soap_class.ce); - + /* Call constructor */ class_name_len = strlen(service->soap_class.ce->name); class_name = emalloc(class_name_len+1); @@ -1460,13 +1460,16 @@ zend_try { zval** fault; if (zend_hash_find(Z_OBJPROP_P(thisObj), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) { *return_value = **fault; + zval_copy_ctor(return_value); } else { *return_value = *add_soap_fault(thisObj, "SOAP-ENV:Client", "Unknown Error", NULL, NULL TSRMLS_CC); + zval_copy_ctor(return_value); } } else { zval** fault; if (zend_hash_find(Z_OBJPROP_P(thisObj), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) { *return_value = **fault; + zval_copy_ctor(return_value); } } SOAP_GLOBAL(sdl) = NULL; @@ -1847,6 +1850,7 @@ static xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_ sdlParamPtr parameter = NULL; smart_str *gen_ns = NULL; int param_count; + int style, use; encode_reset_ns(); @@ -1856,55 +1860,44 @@ static xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_ doc->children = xmlNewDocNode(doc, NULL, "SOAP-ENV:Envelope", NULL); envelope = doc->children; - /*TODO: if use="literal" SOAP-ENV:encodingStyle is not need */ - if (version == SOAP_1_1) { -/* - if ($style == 'rpc' && $use == 'encoded') { -*/ - xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_1_ENC); -/* - } -*/ - xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_1_ENC); ns = xmlNewNs(envelope, SOAP_1_1_ENV,"SOAP-ENV"); } else if (version == SOAP_1_2) { -/* - if ($style == 'rpc' && $use == 'encoded') { -*/ - xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_2_ENC); -/* - } -*/ - xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_2_ENC); ns = xmlNewNs(envelope, SOAP_1_2_ENV,"SOAP-ENV"); } else { php_error(E_ERROR, "Unknown SOAP version"); } - xmlSetProp(envelope, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); - xmlSetProp(envelope, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); - xmlSetProp(envelope, "xmlns:" APACHE_NS_PREFIX , APACHE_NAMESPACE); body = xmlNewChild(envelope, ns, "Body", NULL); if (Z_TYPE_P(ret) == IS_OBJECT && Z_OBJCE_P(ret) == soap_fault_class_entry) { - param = seralize_zval(ret, NULL, "SOAP-ENV:Fault", SOAP_ENCODED TSRMLS_CC); + use = SOAP_ENCODED; + param = seralize_zval(ret, NULL, "SOAP-ENV:Fault", use TSRMLS_CC); xmlAddChild(body, param); } else { gen_ns = encode_new_ns(); - ns = xmlNewNs(envelope, uri, gen_ns->c); - if (function != NULL) { - method = xmlNewChild(body, ns, function->responseName , NULL); + if (function != NULL && function->binding->bindingType == BINDING_SOAP) { + sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes; + + style = fnb->style; + use = fnb->output.use; + if (style == SOAP_RPC) { + ns = xmlNewNs(body, fnb->output.ns, gen_ns->c); + if (function->responseName) { + method = xmlNewChild(body, ns, function->responseName, NULL); + } else { + method = xmlNewChild(body, ns, function->functionName, NULL); + } + } } else { + style = SOAP_RPC; + use = SOAP_ENCODED; + ns = xmlNewNs(body, uri, gen_ns->c); method = xmlNewChild(body, ns, function_name, NULL); } - if (uri) { - ns = xmlNewNs(method, uri, NULL); - } - if (function != NULL) { param_count = zend_hash_num_elements(function->responseParameters); } else { @@ -1914,8 +1907,21 @@ static xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_ if (param_count == 1) { parameter = get_param(function, NULL, 0, TRUE); - param = seralize_parameter(parameter, ret, 0, "return", SOAP_ENCODED TSRMLS_CC); - xmlAddChild(method,param); + param = seralize_parameter(parameter, ret, 0, "return", use TSRMLS_CC); + if (style == SOAP_RPC) { + xmlAddChild(method,param); + } else { + if (function && function->binding->bindingType == BINDING_SOAP) { + sdlParamPtr *sparam; + + if (zend_hash_index_find(function->responseParameters, 0, (void **)&sparam) == SUCCESS) { + ns = xmlNewNs(param, (*sparam)->encode->details.ns, gen_ns->c); + xmlNodeSetName(param, (*sparam)->encode->details.type_str); + xmlSetNs(param, ns); + } + } + xmlAddChild(body, param); + } } else if (param_count > 1 && Z_TYPE_P(ret) == IS_ARRAY) { HashPosition pos; zval **data; @@ -1930,8 +1936,21 @@ static xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_ zend_hash_get_current_key_ex(Z_ARRVAL_P(ret), ¶m_name, ¶m_name_len, ¶m_index, 0, &pos); parameter = get_param(function, param_name, param_index, TRUE); - param = seralize_parameter(parameter, *data, i, param_name, SOAP_ENCODED TSRMLS_CC); - xmlAddChild(method,param); + param = seralize_parameter(parameter, *data, i, param_name, use TSRMLS_CC); + if (style == SOAP_RPC) { + xmlAddChild(method,param); + } else { + if (function && function->binding->bindingType == BINDING_SOAP) { + sdlParamPtr *sparam; + + if (zend_hash_index_find(function->responseParameters, i, (void **)&sparam) == SUCCESS) { + ns = xmlNewNs(param, (*sparam)->encode->details.ns, gen_ns->c); + xmlNodeSetName(param, (*sparam)->encode->details.type_str); + xmlSetNs(param, ns); + } + } + xmlAddChild(body, param); + } zend_hash_move_forward_ex(Z_ARRVAL_P(ret), &pos); i++; @@ -1939,6 +1958,22 @@ static xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_ } } +/* FIXME: if use="literal" SOAP-ENV:encodingStyle is not need. + What about arrayType? +*/ + if (use == SOAP_ENCODED) { + xmlSetProp(envelope, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); + xmlSetProp(envelope, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); + xmlSetProp(envelope, "xmlns:" APACHE_NS_PREFIX , APACHE_NAMESPACE); + if (version == SOAP_1_1) { + xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_1_ENC); + xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_1_ENC); + } else if (version == SOAP_1_2) { + xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_2_ENC); + xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_2_ENC); + } + } + if (gen_ns) { smart_str_free(gen_ns); efree(gen_ns); @@ -1965,35 +2000,29 @@ static xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function, xmlDocSetRootElement(doc, envelope); if (version == SOAP_1_1) { ns = xmlNewNs(envelope, SOAP_1_1_ENV, "SOAP-ENV"); - xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_1_ENC); - xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_1_ENC); } else if (version == SOAP_1_2) { ns = xmlNewNs(envelope, SOAP_1_2_ENV, "SOAP-ENV"); - xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_2_ENC); - xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_2_ENC); } else { php_error(E_ERROR, "Unknown SOAP version"); } - xmlSetProp(envelope, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); - xmlSetProp(envelope, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); body = xmlNewChild(envelope, ns, "Body", NULL); gen_ns = encode_new_ns(); - if (function) { - if (function->binding->bindingType == BINDING_SOAP) { - sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes; + if (function && function->binding->bindingType == BINDING_SOAP) { + sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes; - style = fnb->style; - use = fnb->input.use; - if (style == SOAP_RPC) { - ns = xmlNewNs(body, fnb->input.ns, gen_ns->c); - if (function->requestName) { - method = xmlNewChild(body, ns, function->requestName, NULL); - } else { - method = xmlNewChild(body, ns, function->functionName, NULL); - } + style = fnb->style; + /*FIXME: how to pass method name if style is SOAP_DOCUMENT */ + /*style = SOAP_RPC;*/ + use = fnb->input.use; + if (style == SOAP_RPC) { + ns = xmlNewNs(body, fnb->input.ns, gen_ns->c); + if (function->requestName) { + method = xmlNewChild(body, ns, function->requestName, NULL); + } else { + method = xmlNewChild(body, ns, function->functionName, NULL); } } } else { @@ -2002,22 +2031,37 @@ static xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function, } else { style = SOAP_RPC; } + /*FIXME: how to pass method name if style is SOAP_DOCUMENT */ + /*style = SOAP_RPC;*/ if (style == SOAP_RPC) { ns = xmlNewNs(body, uri, gen_ns->c); method = xmlNewChild(body, ns, function_name, NULL); } - if (zend_hash_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use"), (void **)&zuse) == SUCCESS) { - if (Z_LVAL_PP(zuse) == SOAP_LITERAL) { - use = SOAP_LITERAL; - } else { - use = SOAP_ENCODED; - } + if (zend_hash_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use"), (void **)&zuse) == SUCCESS && + Z_LVAL_PP(zuse) == SOAP_LITERAL) { + use = SOAP_LITERAL; } else { use = SOAP_ENCODED; } } - + +/* FIXME: if use="literal" SOAP-ENV:encodingStyle is not need. + What about arrayType? +*/ + if (use == SOAP_ENCODED) { + xmlSetProp(envelope, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); + xmlSetProp(envelope, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); + xmlSetProp(envelope, "xmlns:" APACHE_NS_PREFIX , APACHE_NAMESPACE); + if (version == SOAP_1_1) { + xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_1_ENC); + xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_1_ENC); + } else if (version == SOAP_1_2) { + xmlSetProp(envelope, "SOAP-ENV:encodingStyle", SOAP_1_2_ENC); + xmlSetProp(envelope, "xmlns:SOAP-ENC", SOAP_1_2_ENC); + } + } + for (i = 0;i < arg_count;i++) { xmlNodePtr param; sdlParamPtr parameter = get_param(function, NULL, i, FALSE); @@ -2030,7 +2074,7 @@ static xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function, if (function && function->binding->bindingType == BINDING_SOAP) { sdlParamPtr *sparam; - if (zend_hash_index_find(function->requestParameters, 0, (void **)&sparam) == SUCCESS) { + if (zend_hash_index_find(function->requestParameters, i, (void **)&sparam) == SUCCESS) { ns = xmlNewNs(param, (*sparam)->encode->details.ns, gen_ns->c); xmlNodeSetName(param, (*sparam)->encode->details.type_str); xmlSetNs(param, ns); -- cgit v1.2.1