summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2004-01-30 15:07:19 +0000
committerDmitry Stogov <dmitry@php.net>2004-01-30 15:07:19 +0000
commitb81645edd3912d6dca99d56649736a0b23056964 (patch)
tree3db256bb236511558a7a5e2b01d804bac1cf8c9f
parent356e8f9b7d9495874244143e0ec490b519c1c3cf (diff)
downloadphp-git-b81645edd3912d6dca99d56649736a0b23056964.tar.gz
SOAP 1.2 specification conformity was improved
-rw-r--r--ext/soap/TODO1
-rw-r--r--ext/soap/php_encoding.c25
-rw-r--r--ext/soap/php_http.c18
-rw-r--r--ext/soap/php_packet_soap.c51
-rw-r--r--ext/soap/php_schema.c44
-rw-r--r--ext/soap/php_sdl.c1
-rw-r--r--ext/soap/php_xml.c47
-rw-r--r--ext/soap/php_xml.h2
-rw-r--r--ext/soap/soap.c158
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 {