123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- #include "php_soap.h"
- int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctionPtr fn, char *fn_name, zval *return_value, zval *soap_headers)
- {
- char* envelope_ns = NULL;
- xmlDocPtr response;
- xmlNodePtr trav, env, head, body, resp, cur, fault;
- xmlAttrPtr attr;
- int param_count = 0;
- int soap_version = SOAP_1_1;
- HashTable *hdrs = NULL;
- ZVAL_NULL(return_value);
-
- if (buffer_size == 0) {
- return TRUE;
- }
-
- response = soap_xmlParseMemory(buffer, buffer_size);
- if (!response) {
- add_soap_fault(this_ptr, "Client", "looks like we got no XML document", NULL, NULL);
- return FALSE;
- }
- if (xmlGetIntSubset(response) != NULL) {
- add_soap_fault(this_ptr, "Client", "DTD are not supported by SOAP", NULL, NULL);
- xmlFreeDoc(response);
- return FALSE;
- }
-
- env = NULL;
- trav = response->children;
- while (trav != NULL) {
- if (trav->type == XML_ELEMENT_NODE) {
- if (env == NULL && node_is_equal_ex(trav,"Envelope",SOAP_1_1_ENV_NAMESPACE)) {
- env = trav;
- envelope_ns = SOAP_1_1_ENV_NAMESPACE;
- soap_version = SOAP_1_1;
- } else if (env == NULL && node_is_equal_ex(trav,"Envelope",SOAP_1_2_ENV_NAMESPACE)) {
- env = trav;
- envelope_ns = SOAP_1_2_ENV_NAMESPACE;
- soap_version = SOAP_1_2;
- } else {
- add_soap_fault(this_ptr, "VersionMismatch", "Wrong Version", NULL, NULL);
- xmlFreeDoc(response);
- return FALSE;
- }
- }
- trav = trav->next;
- }
- if (env == NULL) {
- add_soap_fault(this_ptr, "Client", "looks like we got XML without \"Envelope\" element", NULL, NULL);
- 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);
- xmlFreeDoc(response);
- return FALSE;
- } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
- if (soap_version == SOAP_1_2) {
- add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Envelope", NULL, NULL);
- xmlFreeDoc(response);
- return FALSE;
- } else if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE) != 0) {
- add_soap_fault(this_ptr, "Client", "Unknown data encoding style", NULL, NULL);
- xmlFreeDoc(response);
- return FALSE;
- }
- }
- attr = attr->next;
- }
-
- head = NULL;
- trav = env->children;
- while (trav != NULL && trav->type != XML_ELEMENT_NODE) {
- trav = trav->next;
- }
- if (trav != NULL && node_is_equal_ex(trav,"Header",envelope_ns)) {
- head = trav;
- trav = trav->next;
- }
-
- body = NULL;
- 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", "Body must be present in a SOAP envelope", NULL, NULL);
- xmlFreeDoc(response);
- return FALSE;
- }
- attr = body->properties;
- while (attr != NULL) {
- if (attr->ns == NULL) {
- if (soap_version == SOAP_1_2) {
- add_soap_fault(this_ptr, "Client", "A SOAP Body element cannot have non Namespace qualified attributes", NULL, NULL);
- xmlFreeDoc(response);
- return FALSE;
- }
- } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
- if (soap_version == SOAP_1_2) {
- add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Body", NULL, NULL);
- xmlFreeDoc(response);
- return FALSE;
- } else if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE) != 0) {
- add_soap_fault(this_ptr, "Client", "Unknown data encoding style", NULL, NULL);
- xmlFreeDoc(response);
- return FALSE;
- }
- }
- attr = attr->next;
- }
- 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);
- xmlFreeDoc(response);
- return FALSE;
- }
- if (head != NULL) {
- attr = head->properties;
- while (attr != NULL) {
- if (attr->ns == NULL) {
- add_soap_fault(this_ptr, "Client", "A SOAP Header element cannot have non Namespace qualified attributes", NULL, NULL);
- xmlFreeDoc(response);
- return FALSE;
- } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
- if (soap_version == SOAP_1_2) {
- add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Header", NULL, NULL);
- xmlFreeDoc(response);
- return FALSE;
- } else if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE) != 0) {
- add_soap_fault(this_ptr, "Client", "Unknown data encoding style", NULL, NULL);
- xmlFreeDoc(response);
- return FALSE;
- }
- }
- attr = attr->next;
- }
- }
-
- fault = get_node_ex(body->children,"Fault",envelope_ns);
- if (fault != NULL) {
- char *faultcode = NULL;
- zend_string *faultstring = NULL, *faultactor = NULL;
- zval details;
- xmlNodePtr tmp;
- ZVAL_UNDEF(&details);
- if (soap_version == SOAP_1_1) {
- tmp = get_node(fault->children, "faultcode");
- if (tmp != NULL && tmp->children != NULL) {
- faultcode = (char*)tmp->children->content;
- }
- tmp = get_node(fault->children, "faultstring");
- if (tmp != NULL && tmp->children != NULL) {
- zval zv;
- master_to_zval(&zv, get_conversion(IS_STRING), tmp);
- faultstring = Z_STR(zv);
- }
- tmp = get_node(fault->children, "faultactor");
- if (tmp != NULL && tmp->children != NULL) {
- zval zv;
- master_to_zval(&zv, get_conversion(IS_STRING), tmp);
- faultactor = Z_STR(zv);
- }
- tmp = get_node(fault->children, "detail");
- if (tmp != NULL) {
- master_to_zval(&details, NULL, tmp);
- }
- } else {
- tmp = get_node(fault->children, "Code");
- if (tmp != NULL && tmp->children != NULL) {
- tmp = get_node(tmp->children, "Value");
- if (tmp != NULL && tmp->children != NULL) {
- faultcode = (char*)tmp->children->content;
- }
- }
- tmp = get_node(fault->children,"Reason");
- if (tmp != NULL && tmp->children != NULL) {
-
- tmp = get_node(tmp->children,"Text");
- if (tmp != NULL && tmp->children != NULL) {
- zval zv;
- master_to_zval(&zv, get_conversion(IS_STRING), tmp);
- faultstring = Z_STR(zv);
- }
- }
- tmp = get_node(fault->children,"Detail");
- if (tmp != NULL) {
- master_to_zval(&details, NULL, tmp);
- }
- }
- add_soap_fault(this_ptr, faultcode, faultstring ? ZSTR_VAL(faultstring) : NULL, faultactor ? ZSTR_VAL(faultactor) : NULL, &details);
- if (faultstring) {
- zend_string_release_ex(faultstring, 0);
- }
- if (faultactor) {
- zend_string_release_ex(faultactor, 0);
- }
- if (Z_REFCOUNTED(details)) {
- Z_DELREF(details);
- }
- xmlFreeDoc(response);
- return FALSE;
- }
-
- array_init(return_value);
- resp = body->children;
- while (resp != NULL && resp->type != XML_ELEMENT_NODE) {
- resp = resp->next;
- }
- if (resp != NULL) {
- if (fn != NULL && fn->binding && fn->binding->bindingType == BINDING_SOAP) {
-
- sdlParamPtr param = NULL;
- xmlNodePtr val = NULL;
- char *name, *ns = NULL;
- zval tmp;
- sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
- int res_count;
- hdrs = fnb->output.headers;
- if (fn->responseParameters) {
- res_count = zend_hash_num_elements(fn->responseParameters);
- ZEND_HASH_FOREACH_PTR(fn->responseParameters, param) {
- if (fnb->style == SOAP_DOCUMENT) {
- if (param->element) {
- name = param->element->name;
- ns = param->element->namens;
- } else {
- name = param->paramName;
- }
- } else {
- name = fn->responseName;
-
- }
-
- cur = get_node_ex(resp, name, ns);
- if (!cur) {
- cur = get_node(resp, name);
-
- }
- if (!cur && fnb->style == SOAP_RPC) {
- cur = resp;
- }
- if (cur) {
- if (fnb->style == SOAP_DOCUMENT) {
- val = cur;
- } else {
- val = get_node(cur->children, param->paramName);
- if (res_count == 1) {
- if (val == NULL) {
- val = get_node(cur->children, "return");
- }
- if (val == NULL) {
- val = get_node(cur->children, "result");
- }
- if (val == NULL && cur->children && cur->children->next == NULL) {
- val = cur->children;
- }
- }
- }
- }
- if (!val) {
-
- ZVAL_NULL(&tmp);
- } else {
-
- if (param != NULL) {
- master_to_zval(&tmp, param->encode, val);
- } else {
- master_to_zval(&tmp, NULL, val);
- }
- }
- add_assoc_zval(return_value, param->paramName, &tmp);
- param_count++;
- } ZEND_HASH_FOREACH_END();
- }
- } else {
-
- xmlNodePtr val;
- val = resp->children;
- while (val != NULL) {
- while (val && val->type != XML_ELEMENT_NODE) {
- val = val->next;
- }
- if (val != NULL) {
- if (!node_is_equal_ex(val,"result",RPC_SOAP12_NAMESPACE)) {
- zval tmp;
- zval *arr;
- master_to_zval(&tmp, NULL, val);
- if (val->name) {
- if ((arr = zend_hash_str_find(Z_ARRVAL_P(return_value), (char*)val->name, strlen((char*)val->name))) != NULL) {
- add_next_index_zval(arr, &tmp);
- } else if (val->next && get_node(val->next, (char*)val->name)) {
- zval arr;
- array_init(&arr);
- add_next_index_zval(&arr, &tmp);
- add_assoc_zval(return_value, (char*)val->name, &arr);
- } else {
- add_assoc_zval(return_value, (char*)val->name, &tmp);
- }
- } else {
- add_next_index_zval(return_value, &tmp);
- }
- ++param_count;
- }
- val = val->next;
- }
- }
- }
- }
- if (Z_TYPE_P(return_value) == IS_ARRAY) {
- if (param_count == 0) {
- zend_array_destroy(Z_ARR_P(return_value));
- ZVAL_NULL(return_value);
- } else if (param_count == 1) {
- zval *tmp;
- zend_hash_internal_pointer_reset(Z_ARRVAL_P(return_value));
- tmp = zend_hash_get_current_data(Z_ARRVAL_P(return_value));
- if (!Z_REFCOUNTED_P(return_value)) {
- ZVAL_COPY(return_value, tmp);
- } else {
- zend_refcounted *garbage = Z_COUNTED_P(return_value);
- ZVAL_COPY(return_value, tmp);
- rc_dtor_func(garbage);
- }
- }
- }
- if (soap_headers && head) {
- trav = head->children;
- while (trav != NULL) {
- if (trav->type == XML_ELEMENT_NODE) {
- encodePtr enc = NULL;
- zval val;
- if (hdrs) {
- smart_str key = {0};
- sdlSoapBindingFunctionHeaderPtr hdr;
- if (trav->ns) {
- smart_str_appends(&key, (char*)trav->ns->href);
- smart_str_appendc(&key,':');
- }
- smart_str_appends(&key, (char*)trav->name);
- smart_str_0(&key);
- if ((hdr = zend_hash_find_ptr(hdrs, key.s)) != NULL) {
- enc = hdr->encode;
- }
- smart_str_free(&key);
- }
- master_to_zval(&val, enc, trav);
- add_assoc_zval(soap_headers, (char*)trav->name, &val);
- }
- trav = trav->next;
- }
- }
- xmlFreeDoc(response);
- return TRUE;
- }
|