diff options
author | Dmitry Stogov <dmitry@php.net> | 2004-01-30 15:07:19 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2004-01-30 15:07:19 +0000 |
commit | b81645edd3912d6dca99d56649736a0b23056964 (patch) | |
tree | 3db256bb236511558a7a5e2b01d804bac1cf8c9f /ext | |
parent | 356e8f9b7d9495874244143e0ec490b519c1c3cf (diff) | |
download | php-git-b81645edd3912d6dca99d56649736a0b23056964.tar.gz |
SOAP 1.2 specification conformity was improved
Diffstat (limited to 'ext')
-rw-r--r-- | ext/soap/TODO | 1 | ||||
-rw-r--r-- | ext/soap/php_encoding.c | 25 | ||||
-rw-r--r-- | ext/soap/php_http.c | 18 | ||||
-rw-r--r-- | ext/soap/php_packet_soap.c | 51 | ||||
-rw-r--r-- | ext/soap/php_schema.c | 44 | ||||
-rw-r--r-- | ext/soap/php_sdl.c | 1 | ||||
-rw-r--r-- | ext/soap/php_xml.c | 47 | ||||
-rw-r--r-- | ext/soap/php_xml.h | 2 | ||||
-rw-r--r-- | ext/soap/soap.c | 158 |
9 files changed, 212 insertions, 135 deletions
diff --git a/ext/soap/TODO b/ext/soap/TODO index 3da3773d6b..2bda464236 100644 --- a/ext/soap/TODO +++ b/ext/soap/TODO @@ -9,7 +9,6 @@ General SOAP ---- -- SOAP message MUST NOT contain Processing Instructions <?xml-stylesheet ... ?> (XML_PI_NODE) - support for SOAP headers - actor attribute - mustUnderstend attribute diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index a138eae329..2e9eb23b06 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -2321,19 +2321,20 @@ static xmlNodePtr check_and_resolve_href(xmlNodePtr data) /* SOAP 1.2 enc:id enc:ref */ href = get_attribute_ex(data->properties, "ref", SOAP_1_2_ENC_NAMESPACE); if (href) { - /* Internal href try and find node */ + char* id; + if (href->children->content[0] == '#') { - xmlNodePtr ret = get_node_with_attribute_recursive_ex(data->doc->children, NULL, NULL, "id", &href->children->content[1], SOAP_1_2_ENC_NAMESPACE); - if (!ret) { - php_error(E_ERROR,"SOAP-ERROR: Encoding: Unresolved reference '%s'",href->children->content); - } else if (ret == data) { - php_error(E_ERROR,"SOAP-ERROR: Encoding: Violation of id and ref information items '%s'",href->children->content); - } - return ret; + id = href->children->content+1; } else { - /* TODO: External href....? */ - php_error(E_ERROR,"SOAP-ERROR: Encoding: External reference '%s'",href->children->content); + id = href->children->content; + } + xmlNodePtr ret = get_node_with_attribute_recursive_ex(data->doc->children, NULL, NULL, "id", id, SOAP_1_2_ENC_NAMESPACE); + if (!ret) { + php_error(E_ERROR,"SOAP-ERROR: Encoding: Unresolved reference '%s'",href->children->content); + } else if (ret == data) { + php_error(E_ERROR,"SOAP-ERROR: Encoding: Violation of id and ref information items '%s'",href->children->content); } + return ret; } } return data; @@ -2513,13 +2514,13 @@ static void get_array_type(xmlNodePtr node, zval *array, smart_str *type TSRMLS_ } else { cur_stype = NULL; } - + if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_ns", sizeof("enc_ns"), (void **)&ztype) == SUCCESS) { cur_ns = Z_STRVAL_PP(ztype); } else { cur_ns = NULL; } - + } else if (Z_TYPE_PP(tmp) == IS_ARRAY && is_map(*tmp)) { cur_type = APACHE_MAP; cur_stype = NULL; diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index f2f8da2fbd..e4a6c9e0e7 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -90,7 +90,7 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, in #endif int port; int old_error_reporting; - + if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_host", sizeof("_proxy_host"), (void **) &proxy_host) == SUCCESS && Z_TYPE_PP(proxy_host) == IS_STRING && zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_port", sizeof("_proxy_port"), (void **) &proxy_port) == SUCCESS && @@ -134,14 +134,14 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, in smart_str_append_const(&soap_headers, "\r\n"); if (php_stream_write(stream, soap_headers.c, soap_headers.len) != soap_headers.len) { php_stream_close(stream); - stream = NULL; + stream = NULL; } smart_str_free(&soap_headers); if (stream) { if (!get_http_headers(stream, &http_headers, &http_header_size TSRMLS_CC) || http_headers == NULL) { php_stream_close(stream); - stream = NULL; + stream = NULL; } efree(http_headers); } @@ -222,7 +222,15 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so return FALSE; } - use_ssl = strcmp(phpurl->scheme, "https") == 0; + use_ssl = 0; + if (strcmp(phpurl->scheme, "https") == 0) { + use_ssl = 1; + } else if (strcmp(phpurl->scheme, "http") != 0) { + xmlFree(buf); + php_url_free(phpurl); + add_soap_fault(this_ptr, "HTTP", "Unknown protocol. Only http and https are allowed.", NULL, NULL TSRMLS_CC); + return FALSE; + } #ifdef ZEND_ENGINE_2 if (use_ssl && php_stream_locate_url_wrapper("https://", NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) == NULL) { xmlFree(buf); @@ -257,7 +265,7 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so add_soap_fault(this_ptr, "HTTP", "Could not connect to host", NULL, NULL TSRMLS_CC); return FALSE; } - } + } if (stream) { zval **cookies, **login, **password; diff --git a/ext/soap/php_packet_soap.c b/ext/soap/php_packet_soap.c index 54c38ad27f..03315c586d 100644 --- a/ext/soap/php_packet_soap.c +++ b/ext/soap/php_packet_soap.c @@ -27,6 +27,7 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction char* envelope_ns = NULL; xmlDocPtr response; xmlNodePtr trav, env, head, body, resp, cur, fault; + xmlAttrPtr attr; int param_count = 0; int old_error_reporting; int soap_version; @@ -48,6 +49,7 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction } if (xmlGetIntSubset(response) != NULL) { add_soap_fault(this_ptr, "Client", "DTD are not supported by SOAP", NULL, NULL TSRMLS_CC); + xmlFreeDoc(response); return FALSE; } @@ -65,7 +67,7 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction envelope_ns = SOAP_1_2_ENV_NAMESPACE; soap_version = SOAP_1_2; } else { - add_soap_fault(this_ptr, "Client", "looks like we got bad SOAP response\n", NULL, NULL TSRMLS_CC); + add_soap_fault(this_ptr, "VersionMismatch", "Wrong Version", NULL, NULL TSRMLS_CC); xmlFreeDoc(response); return FALSE; } @@ -73,11 +75,25 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction trav = trav->next; } if (env == NULL) { - add_soap_fault(this_ptr, "Client", "looks like we got XML without \"Envelope\" element\n", NULL, NULL TSRMLS_CC); + add_soap_fault(this_ptr, "Client", "looks like we got XML without \"Envelope\" element", NULL, NULL TSRMLS_CC); xmlFreeDoc(response); return FALSE; } + attr = env->properties; + while (attr != NULL) { + if (attr->ns == NULL) { + add_soap_fault(this_ptr, "Client", "A SOAP Envelope element cannot have non Namespace qualified attributes", NULL, NULL TSRMLS_CC); + xmlFreeDoc(response); + return FALSE; + } else if (soap_version == SOAP_1_2 && attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) { + add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Envelope", NULL, NULL TSRMLS_CC); + xmlFreeDoc(response); + return FALSE; + } + attr = attr->next; + } + /* Get <Header> element */ head = NULL; trav = env->children; @@ -91,20 +107,29 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction /* Get <Body> element */ body = NULL; - while (trav != NULL) { - if (trav->type == XML_ELEMENT_NODE) { - if (body == NULL && node_is_equal_ex(trav,"Body",envelope_ns)) { - body = trav; - } else { - add_soap_fault(this_ptr, "Client", "looks like we got bad SOAP response\n", NULL, NULL TSRMLS_CC); - xmlFreeDoc(response); - return FALSE; - } - } + while (trav != NULL && trav->type != XML_ELEMENT_NODE) { + trav = trav->next; + } + if (trav != NULL && node_is_equal_ex(trav,"Body",envelope_ns)) { + body = trav; + trav = trav->next; + } + while (trav != NULL && trav->type != XML_ELEMENT_NODE) { trav = trav->next; } if (body == NULL) { - add_soap_fault(this_ptr, "Client", "looks like we got \"Envelope\" without \"Body\" element\n", NULL, NULL TSRMLS_CC); + add_soap_fault(this_ptr, "Client", "Body must be present in a SOAP envelope", NULL, NULL TSRMLS_CC); + xmlFreeDoc(response); + return FALSE; + } + attr = get_attribute_ex(body->properties,"encodingStyle",SOAP_1_2_ENV_NAMESPACE); + if (attr && soap_version == SOAP_1_2) { + add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Body", NULL, NULL TSRMLS_CC); + xmlFreeDoc(response); + return FALSE; + } + if (trav != NULL && soap_version == SOAP_1_2) { + add_soap_fault(this_ptr, "Client", "A SOAP 1.2 envelope can contain only Header and Body", NULL, NULL TSRMLS_CC); xmlFreeDoc(response); return FALSE; } diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index cd114ca33b..69372c39ce 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -115,48 +115,6 @@ static encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const char return enc; } -static int is_blank(const char* str) -{ - while (*str != '\0') { - if (*str != ' ' && *str != 0x9 && *str != 0xa && *str != 0xd) { - return 0; - } - str++; - } - return 1; -} - -/* removes all empty text, comments and other insignoficant nodes */ -static void schema_cleanup(xmlNodePtr schema) -{ - xmlNodePtr trav; - xmlNodePtr del = NULL; - - trav = schema->children; - while (trav != NULL) { - if (del != NULL) { - xmlUnlinkNode(del); - xmlFreeNode(del); - del = NULL; - } - if (trav->type == XML_TEXT_NODE) { - if (is_blank(trav->content)) { - del = trav; - } - } else if ((trav->type != XML_ELEMENT_NODE) && - (trav->type != XML_CDATA_SECTION_NODE)) { - del = trav; - } else if (trav->children != NULL) { - schema_cleanup(trav); - } - trav = trav->next; - } - if (del != NULL) { - xmlUnlinkNode(del); - xmlFreeNode(del); - } -} - static void schema_load_file(sdlPtr sdl, xmlAttrPtr ns, xmlChar *location, xmlAttrPtr tns, int import) { if (location != NULL && !zend_hash_exists(&sdl->docs, location, strlen(location)+1)) { @@ -169,6 +127,7 @@ static void schema_load_file(sdlPtr sdl, xmlAttrPtr ns, xmlChar *location, xmlAt if (doc == NULL) { php_error(E_ERROR, "SOAP-ERROR: Parsing Schema: can't import schema from '%s'",location); } + cleanup_xml(doc); schema = get_node(doc->children, "schema"); if (schema == NULL) { xmlFreeDoc(doc); @@ -226,7 +185,6 @@ int load_schema(sdlPtr sdl,xmlNodePtr schema) xmlNodePtr trav; xmlAttrPtr tns; - schema_cleanup(schema); if (!sdl->types) { sdl->types = malloc(sizeof(HashTable)); zend_hash_init(sdl->types, 0, NULL, delete_type, 1); diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index 28edfd08c2..54b82fcd14 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -178,6 +178,7 @@ static void load_wsdl_ex(char *struri, sdlCtx *ctx, int include) if (!wsdl) { php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Couldn't load from '%s'", struri); } + cleanup_xml(wsdl); zend_hash_add(&tmpsdl->docs, struri, strlen(struri)+1, (void**)&wsdl, sizeof(xmlDocPtr), NULL); diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c index f2a50b50f9..65e058c2bf 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -194,3 +194,50 @@ int parse_namespace(const char *inval, char **value, char **namespace) return FALSE; } + +static int is_blank(const char* str) +{ + while (*str != '\0') { + if (*str != ' ' && *str != 0x9 && *str != 0xa && *str != 0xd) { + return 0; + } + str++; + } + return 1; +} + +/* removes all empty text, comments and other insignoficant nodes */ +static void cleanup_xml_node(xmlNodePtr node) +{ + xmlNodePtr trav; + xmlNodePtr del = NULL; + + trav = node->children; + while (trav != NULL) { + if (del != NULL) { + xmlUnlinkNode(del); + xmlFreeNode(del); + del = NULL; + } + if (trav->type == XML_TEXT_NODE) { + if (is_blank(trav->content)) { + del = trav; + } + } else if ((trav->type != XML_ELEMENT_NODE) && + (trav->type != XML_CDATA_SECTION_NODE)) { + del = trav; + } else if (trav->children != NULL) { + cleanup_xml_node(trav); + } + trav = trav->next; + } + if (del != NULL) { + xmlUnlinkNode(del); + xmlFreeNode(del); + } +} + +void cleanup_xml(xmlDocPtr doc) +{ + cleanup_xml_node((xmlNodePtr)doc); +} diff --git a/ext/soap/php_xml.h b/ext/soap/php_xml.h index f223aac6d3..eb34d2db11 100644 --- a/ext/soap/php_xml.h +++ b/ext/soap/php_xml.h @@ -41,6 +41,8 @@ xmlNodePtr get_node_with_attribute_ex(xmlNodePtr node, char *name, char *name_ns xmlNodePtr get_node_with_attribute_recursive_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns); int parse_namespace(const char *inval,char **value,char **namespace); +void cleanup_xml(xmlDocPtr doc); + int php_stream_xmlIO_match_wrapper(const char *filename); void *php_stream_xmlIO_open_wrapper(const char *filename); int php_stream_xmlIO_read(void *context, char *buffer, int len); diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 4e1f3e923c..cfae730052 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -1205,23 +1205,52 @@ PHP_METHOD(soapserver, handle) SOAP_SERVER_END_CODE(); } -static void soap_error_handler(int error_num, const char *error_filename, const uint error_lineno, const char *format, va_list args) +static void soap_server_fault(char* code, char* string, char *actor, zval* details) { - char buffer[1024]; - int buffer_len; int soap_version; + xmlChar *buf, cont_len[30]; + int size; + zval ret; + xmlDocPtr doc_return; + TSRMLS_FETCH(); + + soap_version = SOAP_GLOBAL(soap_version); + + INIT_ZVAL(ret); + + set_soap_fault(&ret, code, string, actor, details TSRMLS_CC); + + doc_return = seralize_response_call(NULL, NULL, NULL, &ret, soap_version TSRMLS_CC); + + xmlDocDumpMemory(doc_return, &buf, &size); + + /* + Want to return HTTP 500 but apache wants to over write + our fault code with their own handling... Figure this out later + */ + sapi_add_header("HTTP/1.1 500 Internal Service Error", sizeof("HTTP/1.1 500 Internal Service Error"), 1); + sprintf(cont_len,"Content-Length: %d", size); + sapi_add_header(cont_len, strlen(cont_len) + 1, 1); + if (soap_version == SOAP_1_2) { + sapi_add_header("Content-Type: application/soap+xml; charset=\"utf-8\"", sizeof("Content-Type: application/soap+xml; charset=\"utf-8\""), 1); + } else { + sapi_add_header("Content-Type: text/xml; charset=\"utf-8\"", sizeof("Content-Type: text/xml; charset=\"utf-8\""), 1); + } + php_write(buf, size TSRMLS_CC); + + xmlFreeDoc(doc_return); + xmlFree(buf); + zend_bailout(); +} + +static void soap_error_handler(int error_num, const char *error_filename, const uint error_lineno, const char *format, va_list args) +{ TSRMLS_FETCH(); if (!SOAP_GLOBAL(use_soap_error_handler)) { old_error_handler(error_num, error_filename, error_lineno, format, args); return; } - soap_version = SOAP_GLOBAL(soap_version); - buffer_len = vsnprintf(buffer, sizeof(buffer)-1, format, args); - buffer[sizeof(buffer)-1]=0; - if (buffer_len > sizeof(buffer) - 1 || buffer_len < 0) { - buffer_len = sizeof(buffer) - 1; - } /* Trap all errors @@ -1230,14 +1259,19 @@ static void soap_error_handler(int error_num, const char *error_filename, const */ if (error_num == E_USER_ERROR || error_num == E_COMPILE_ERROR || error_num == E_CORE_ERROR || error_num == E_ERROR || error_num == E_PARSE) { - zval outbuf, outbuflen, ret; - xmlChar *buf, cont_len[30]; - int size; - xmlDocPtr doc_return; + + char buffer[1024]; + int buffer_len; + zval outbuf, outbuflen; INIT_ZVAL(outbuf); INIT_ZVAL(outbuflen); - INIT_ZVAL(ret); + + buffer_len = vsnprintf(buffer, sizeof(buffer)-1, format, args); + buffer[sizeof(buffer)-1]=0; + if (buffer_len > sizeof(buffer) - 1 || buffer_len < 0) { + buffer_len = sizeof(buffer) - 1; + } /* Get output buffer and send as fault detials */ if (php_ob_get_length(&outbuflen TSRMLS_CC) != FAILURE && Z_LVAL(outbuflen) != 0) { @@ -1245,37 +1279,7 @@ static void soap_error_handler(int error_num, const char *error_filename, const } php_end_ob_buffer(0, 0 TSRMLS_CC); - set_soap_fault(&ret, "Server", buffer, NULL, &outbuf TSRMLS_CC); - doc_return = seralize_response_call(NULL, NULL, NULL, &ret, soap_version TSRMLS_CC); - - /* - xmlDocDumpMemoryEnc(doc_return, &buf, &size, XML_CHAR_ENCODING_UTF8); - */ - xmlDocDumpMemory(doc_return, &buf, &size); - - /* - Want to return HTTP 500 but apache wants to over write - our fault code with their own handling... Figure this out later - */ - sapi_add_header("HTTP/1.1 500 Internal Service Error", sizeof("HTTP/1.1 500 Internal Service Error"), 1); - sprintf(cont_len,"Content-Length: %d", size); - sapi_add_header(cont_len, strlen(cont_len) + 1, 1); - if (soap_version == SOAP_1_2) { - sapi_add_header("Content-Type: application/soap+xml; charset=\"utf-8\"", sizeof("Content-Type: application/soap+xml; charset=\"utf-8\""), 1); - } else { - sapi_add_header("Content-Type: text/xml; charset=\"utf-8\"", sizeof("Content-Type: text/xml; charset=\"utf-8\""), 1); - } - php_write(buf, size TSRMLS_CC); - - xmlFreeDoc(doc_return); - xmlFree(buf); - - zval_dtor(&outbuf); - zval_dtor(&outbuflen); -/* ??? - zval_dtor(&ret); -*/ - zend_bailout(); + soap_server_fault("Server", buffer, NULL, &outbuf TSRMLS_CC); } } @@ -1727,6 +1731,9 @@ static void set_soap_fault(zval *obj, char *fault_code, char *fault_string, char } else if (strcmp(fault_code,"Server") == 0) { smart_str_appendl(&code, SOAP_1_1_ENV_NS_PREFIX, sizeof(SOAP_1_1_ENV_NS_PREFIX)-1); smart_str_appendc(&code, ':'); + } else if (strcmp(fault_code,"VersionMismatch") == 0) { + smart_str_appendl(&code, SOAP_1_1_ENV_NS_PREFIX, sizeof(SOAP_1_1_ENV_NS_PREFIX)-1); + smart_str_appendc(&code, ':'); } smart_str_appends(&code,fault_code); } else if (soap_version == SOAP_1_2) { @@ -1738,6 +1745,9 @@ static void set_soap_fault(zval *obj, char *fault_code, char *fault_string, char smart_str_appendl(&code, SOAP_1_2_ENV_NS_PREFIX, sizeof(SOAP_1_2_ENV_NS_PREFIX)-1); smart_str_appendc(&code, ':'); smart_str_appendl(&code,"Receiver",sizeof("Receiver")-1); + } else if (strcmp(fault_code,"VersionMismatch") == 0) { + smart_str_appendl(&code, SOAP_1_2_ENV_NS_PREFIX, sizeof(SOAP_1_2_ENV_NS_PREFIX)-1); + smart_str_appendc(&code, ':'); } else { smart_str_appends(&code,fault_code); } @@ -1758,6 +1768,7 @@ static void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *functi { char* envelope_ns = NULL; xmlNodePtr trav,env,head,body,func; + xmlAttrPtr attr; int cur_param = 0,num_of_params = 0; zval tmp_function_name, **tmp_parameters = NULL; sdlFunctionPtr function; @@ -1780,13 +1791,23 @@ static void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *functi envelope_ns = SOAP_1_2_ENV_NAMESPACE; SOAP_GLOBAL(soap_version) = SOAP_1_2; } else { - php_error(E_ERROR,"looks like we got bad SOAP request\n"); + soap_server_fault("VersionMismatch","Wrong Version", NULL, NULL); } } trav = trav->next; } if (env == NULL) { - php_error(E_ERROR,"looks like we got XML without \"Envelope\" element\n"); + php_error(E_ERROR,"looks like we got XML without \"Envelope\" element"); + } + + attr = env->properties; + while (attr != NULL) { + if (attr->ns == NULL) { + php_error(E_ERROR,"A SOAP Envelope element cannot have non Namespace qualified attributes"); + } else if (*version == SOAP_1_2 && attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) { + php_error(E_ERROR,"encodingStyle cannot be specified on the Envelope"); + } + attr = attr->next; } /* Get <Header> element */ @@ -1802,18 +1823,26 @@ static void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *functi /* Get <Body> element */ body = NULL; - while (trav != NULL) { - if (trav->type == XML_ELEMENT_NODE) { - if (body == NULL && node_is_equal_ex(trav,"Body",envelope_ns)) { - body = trav; - } else { - php_error(E_ERROR,"looks like we got bad SOAP request\n"); - } - } + while (trav != NULL && trav->type != XML_ELEMENT_NODE) { + trav = trav->next; + } + if (trav != NULL && node_is_equal_ex(trav,"Body",envelope_ns)) { + body = trav; + trav = trav->next; + } + while (trav != NULL && trav->type != XML_ELEMENT_NODE) { trav = trav->next; } if (body == NULL) { - php_error(E_ERROR,"looks like we got \"Envelope\" without \"Body\" element\n"); + php_error(E_ERROR,"Body must be present in a SOAP envelope"); + } + attr = get_attribute_ex(body->properties,"encodingStyle",SOAP_1_2_ENV_NAMESPACE); + if (attr && *version == SOAP_1_2) { + php_error(E_ERROR,"encodingStyle cannot be specified on the Body"); + } + + if (trav != NULL && *version == SOAP_1_2) { + php_error(E_ERROR,"A SOAP 1.2 envelope can contain only Header and Body"); } func = NULL; @@ -1821,19 +1850,23 @@ static void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *functi while (trav != NULL) { if (trav->type == XML_ELEMENT_NODE) { if (func != NULL) { - php_error(E_ERROR,"looks like we got \"Body\" with several functions call\n"); + php_error(E_ERROR,"looks like we got \"Body\" with several functions call"); } func = trav; } trav = trav->next; } if (func == NULL) { - php_error(E_ERROR,"looks like we got \"Body\" without function call\n"); + php_error(E_ERROR,"looks like we got \"Body\" without function call"); } 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); + if (*version == SOAP_1_2) { + soap_server_fault("rpc:ProcedureNotPresent","Procedure not present", NULL, NULL); + } else { + php_error(E_ERROR, "Procedure '%s' not present", func->name); + } } INIT_ZVAL(tmp_function_name); @@ -2047,10 +2080,13 @@ static xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_ parameter = get_param(function, NULL, 0, TRUE); if (style == SOAP_RPC) { - param = seralize_parameter(parameter, ret, 0, "return", use, method TSRMLS_CC); + xmlNode *rpc_result; if (version == SOAP_1_2) { xmlNs *rpc_ns = xmlNewNs(body, RPC_SOAP12_NAMESPACE, RPC_SOAP12_NS_PREFIX); - xmlNode *rpc_result = xmlNewChild(method, rpc_ns, "result", NULL); + rpc_result = xmlNewChild(method, rpc_ns, "result", NULL); + } + param = seralize_parameter(parameter, ret, 0, "return", use, method TSRMLS_CC); + if (version == SOAP_1_2) { xmlNodeSetContent(rpc_result,param->name); } } else { |