From a8326d6f62b25336843a750d72f5461979c75426 Mon Sep 17 00:00:00 2001 From: Brad LaFountain Date: Wed, 7 Aug 2002 03:03:09 +0000 Subject: [PATCH] Sync with Sourceforge CVS --- ext/soap/php_encoding.c | 278 ++++++++++--------- ext/soap/php_encoding.h | 60 +++-- ext/soap/php_http.c | 77 +++--- ext/soap/php_packet_soap.c | 8 +- ext/soap/php_schema.c | 58 +++- ext/soap/php_sdl.c | 533 ++++++++++++++++++++++++------------- ext/soap/php_sdl.h | 74 ++++- ext/soap/php_soap.dsp | 16 +- ext/soap/php_soap.h | 57 +++- ext/soap/php_xml.c | 2 +- ext/soap/soap.c | 396 ++++++++++++++++++++------- 11 files changed, 1044 insertions(+), 515 deletions(-) diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 4ce6a18fff..8546289123 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -43,7 +43,7 @@ encode defaultEncoding[] = { //support some of the 1999 data types {{XSD_STRING, XSD_STRING_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_string, to_xml_string}, {{XSD_BOOLEAN, XSD_BOOLEAN_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_bool, to_xml_bool}, - {{XSD_DECIMAL, XSD_DECIMAL_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_double, to_xml_string}, + {{XSD_DECIMAL, XSD_DECIMAL_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_string}, {{XSD_FLOAT, XSD_FLOAT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_double, to_xml_string}, {{XSD_DOUBLE, XSD_DOUBLE_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_double, to_xml_string}, {{XSD_LONG, XSD_LONG_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long}, @@ -109,16 +109,16 @@ encode defaultEncoding[] = { */ }; -xmlNodePtr master_to_xml(encodePtr encode, zval *data) +xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style) { xmlNodePtr node; if(encode->to_xml_before) data = encode->to_xml_before(encode->details, data); if(encode->to_xml) - node = encode->to_xml(encode->details, data); + node = encode->to_xml(encode->details, data, style); if(encode->to_xml_after) - node = encode->to_xml_after(encode->details, node); + node = encode->to_xml_after(encode->details, node, style); return node; } @@ -129,7 +129,7 @@ zval *master_to_zval(encodePtr encode, xmlNodePtr data) data = check_and_resolve_href(data); if(encode->to_zval_before) - data = encode->to_zval_before(encode->details, data); + data = encode->to_zval_before(encode->details, data, 0); if(encode->to_zval) ret = encode->to_zval(encode->details, data); if(encode->to_zval_after) @@ -151,7 +151,7 @@ zval *to_xml_before_user(encodeType type, zval *data) return data; } -xmlNodePtr to_xml_user(encodeType type, zval *data) +xmlNodePtr to_xml_user(encodeType type, zval *data, int style) { zval *ret, **addr; xmlNodePtr node; @@ -177,7 +177,7 @@ xmlNodePtr to_xml_user(encodeType type, zval *data) return node; } -xmlNodePtr to_xml_after_user(encodeType type, xmlNodePtr node) +xmlNodePtr to_xml_after_user(encodeType type, xmlNodePtr node, int style) { zval *ret, *param, **addr; int found; @@ -202,7 +202,7 @@ xmlNodePtr to_xml_after_user(encodeType type, xmlNodePtr node) return node; } -xmlNodePtr to_zval_before_user(encodeType type, xmlNodePtr node) +xmlNodePtr to_zval_before_user(encodeType type, xmlNodePtr node, int style) { zval *ret, *param, **addr; int found; @@ -283,7 +283,7 @@ zval *to_zval_stringl(encodeType type, xmlNodePtr data) return ret; } -xmlNodePtr to_xml_string(encodeType type, zval *data) +xmlNodePtr to_xml_string(encodeType type, zval *data, int style) { xmlNodePtr ret; char *str; @@ -295,11 +295,13 @@ xmlNodePtr to_xml_string(encodeType type, zval *data) convert_to_string(data); str = php_escape_html_entities(Z_STRVAL_P(data), Z_STRLEN_P(data), &new_len, 0, 0, NULL); xmlNodeSetContentLen(ret, str, new_len); - set_ns_and_type(ret, type); + + if(style == SOAP_ENCODED) + set_ns_and_type(ret, type); return ret; } -xmlNodePtr to_xml_stringl(encodeType type, zval *data) +xmlNodePtr to_xml_stringl(encodeType type, zval *data, int style) { xmlNodePtr ret; @@ -308,7 +310,9 @@ xmlNodePtr to_xml_stringl(encodeType type, zval *data) convert_to_string(data); xmlNodeSetContentLen(ret, estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data)), Z_STRLEN_P(data)); - set_ns_and_type(ret, type); + + if(style == SOAP_ENCODED) + set_ns_and_type(ret, type); return ret; } @@ -332,7 +336,7 @@ zval *to_zval_long(encodeType type, xmlNodePtr data) return ret; } -xmlNodePtr to_xml_long(encodeType type, zval *data) +xmlNodePtr to_xml_long(encodeType type, zval *data, int style) { xmlNodePtr ret; @@ -342,7 +346,9 @@ xmlNodePtr to_xml_long(encodeType type, zval *data) convert_to_long(data); convert_to_string(data); xmlNodeSetContentLen(ret, Z_STRVAL_P(data), Z_STRLEN_P(data)); - set_ns_and_type(ret, type); + + if(style == SOAP_ENCODED) + set_ns_and_type(ret, type); return ret; } @@ -365,7 +371,7 @@ zval *to_zval_bool(encodeType type, xmlNodePtr data) return ret; } -xmlNodePtr to_xml_bool(encodeType type, zval *data) +xmlNodePtr to_xml_bool(encodeType type, zval *data, int style) { xmlNodePtr ret; @@ -378,7 +384,8 @@ xmlNodePtr to_xml_bool(encodeType type, zval *data) else xmlNodeSetContent(ret, "0"); - set_ns_and_type(ret, type); + if(style == SOAP_ENCODED) + set_ns_and_type(ret, type); return ret; } @@ -391,14 +398,15 @@ zval *to_zval_null(encodeType type, xmlNodePtr data) return ret; } -xmlNodePtr to_xml_null(encodeType type, zval *data) +xmlNodePtr to_xml_null(encodeType type, zval *data, int style) { xmlNodePtr ret; ret = xmlNewNode(NULL, "BOGUS"); FIND_ZVAL_NULL(data, ret); - xmlSetProp(ret, "xsi:null", "1"); - + + if(style == SOAP_ENCODED) + xmlSetProp(ret, "xsi:null", "1"); return ret; } @@ -432,7 +440,7 @@ zval *to_zval_object(encodeType type, xmlNodePtr data) return ret; } -xmlNodePtr to_xml_object(encodeType type, zval *data) +xmlNodePtr to_xml_object(encodeType type, zval *data, int style) { xmlNodePtr xmlParam; HashTable *prop; @@ -442,7 +450,7 @@ xmlNodePtr to_xml_object(encodeType type, zval *data) //Special handling of class SoapVar if(data && Z_TYPE_P(data) == IS_OBJECT && !strcmp(Z_OBJCE_P(data)->name, soap_var_class_entry.name)) { - zval **ztype, **zdata, **zns, **zstype; + zval **ztype, **zdata, **zns, **zstype, **zname, **znamens; encodePtr enc; if(zend_hash_find(Z_OBJPROP_P(data), "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) @@ -451,7 +459,7 @@ xmlNodePtr to_xml_object(encodeType type, zval *data) php_error(E_ERROR, "error encoding SoapVar"); enc = get_conversion(Z_LVAL_P(*ztype)); - xmlParam = master_to_xml(enc, *zdata); + xmlParam = master_to_xml(enc, *zdata, style); if(zend_hash_find(Z_OBJPROP_P(data), "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) { @@ -460,6 +468,20 @@ xmlNodePtr to_xml_object(encodeType type, zval *data) else set_ns_and_type_ex(xmlParam, NULL, Z_STRVAL_PP(zstype)); } + + if(zend_hash_find(Z_OBJPROP_P(data), "enc_name", sizeof("enc_name"), (void **)&zname) == SUCCESS) + xmlNodeSetName(xmlParam, Z_STRVAL_PP(zname)); + if(zend_hash_find(Z_OBJPROP_P(data), "enc_namens", sizeof("enc_namens"), (void **)&znamens) == SUCCESS) + { + smart_str *ns; + xmlNsPtr nsp; + + ns = encode_new_ns(); + nsp = xmlNewNs(xmlParam, Z_STRVAL_PP(znamens), ns->c); + xmlSetNs(xmlParam, nsp); + smart_str_free(ns); + efree(ns); + } } else { @@ -468,35 +490,37 @@ xmlNodePtr to_xml_object(encodeType type, zval *data) if(Z_TYPE_P(data) == IS_OBJECT) { - prop = Z_OBJPROP_P(data); - i = zend_hash_num_elements(prop); - zend_hash_internal_pointer_reset(prop); + prop = Z_OBJPROP_P(data); + i = zend_hash_num_elements(prop); + zend_hash_internal_pointer_reset(prop); - for(;i > 0;i--) - { - xmlNodePtr property; - encodePtr enc; - zval **zprop; - char *str_key; + for(;i > 0;i--) + { + xmlNodePtr property; + encodePtr enc; + zval **zprop; + char *str_key; - zend_hash_get_current_key(prop, &str_key, NULL, FALSE); - zend_hash_get_current_data(prop, (void **)&zprop); + zend_hash_get_current_key(prop, &str_key, NULL, FALSE); + zend_hash_get_current_data(prop, (void **)&zprop); - enc = get_conversion((*zprop)->type); - property = master_to_xml(enc, (*zprop)); + enc = get_conversion((*zprop)->type); + property = master_to_xml(enc, (*zprop), style); - xmlNodeSetName(property, str_key); - xmlAddChild(xmlParam, property); - zend_hash_move_forward(prop); - } + xmlNodeSetName(property, str_key); + xmlAddChild(xmlParam, property); + zend_hash_move_forward(prop); + } } - set_ns_and_type(xmlParam, type); + + if(style == SOAP_ENCODED) + set_ns_and_type(xmlParam, type); } return xmlParam; } //Array encode/decode -xmlNodePtr guess_array_map(encodeType type, zval *data) +xmlNodePtr guess_array_map(encodeType type, zval *data, int style) { encodePtr enc = NULL; TSRMLS_FETCH(); @@ -514,10 +538,10 @@ xmlNodePtr guess_array_map(encodeType type, zval *data) if(!enc) enc = get_conversion(IS_NULL); - return master_to_xml(enc, data); + return master_to_xml(enc, data, style); } -xmlNodePtr to_xml_array(encodeType type, zval *data) +xmlNodePtr to_xml_array(encodeType type, zval *data, int style) { smart_str array_type_and_size = {0}, array_type = {0}; int i; @@ -531,17 +555,21 @@ xmlNodePtr to_xml_array(encodeType type, zval *data) if(Z_TYPE_P(data) == IS_ARRAY) { i = zend_hash_num_elements(Z_ARRVAL_P(data)); - get_array_type(data, &array_type); - smart_str_append(&array_type_and_size, &array_type); - smart_str_appendc(&array_type_and_size, '['); - smart_str_append_long(&array_type_and_size, i); - smart_str_appendc(&array_type_and_size, ']'); - smart_str_0(&array_type_and_size); - xmlSetProp(xmlParam, "SOAP-ENC:arrayType", array_type_and_size.c); + if(style == SOAP_ENCODED) + { + get_array_type(data, &array_type); + smart_str_append(&array_type_and_size, &array_type); + smart_str_appendc(&array_type_and_size, '['); + smart_str_append_long(&array_type_and_size, i); + smart_str_appendc(&array_type_and_size, ']'); + smart_str_0(&array_type_and_size); + + xmlSetProp(xmlParam, "SOAP-ENC:arrayType", array_type_and_size.c); - smart_str_free(&array_type_and_size); - smart_str_free(&array_type); + smart_str_free(&array_type_and_size); + smart_str_free(&array_type); + } zend_hash_internal_pointer_reset(data->value.ht); for(;i > 0;i--) @@ -552,14 +580,19 @@ xmlNodePtr to_xml_array(encodeType type, zval *data) zend_hash_get_current_data(data->value.ht, (void **)&zdata); enc = get_conversion((*zdata)->type); - xparam = master_to_xml(enc, (*zdata)); + xparam = master_to_xml(enc, (*zdata), style); + + if(style == SOAP_LITERAL) + xmlNodeSetName(xparam, enc->details.type_str); + else + xmlNodeSetName(xparam, "val"); - xmlNodeSetName(xparam, "val"); xmlAddChild(xmlParam, xparam); zend_hash_move_forward(data->value.ht); } } - set_ns_and_type(xmlParam, type); + if(style == SOAP_ENCODED) + set_ns_and_type(xmlParam, type); return xmlParam; } @@ -592,7 +625,7 @@ zval *to_zval_array(encodeType type, xmlNodePtr data) } //Map encode/decode -xmlNodePtr to_xml_map(encodeType type, zval *data) +xmlNodePtr to_xml_map(encodeType type, zval *data, int style) { xmlNodePtr xmlParam; int i; @@ -603,54 +636,57 @@ xmlNodePtr to_xml_map(encodeType type, zval *data) if(Z_TYPE_P(data) == IS_ARRAY) { - i = zend_hash_num_elements(Z_ARRVAL_P(data)); - //TODO: Register namespace...??? - xmlSetProp(xmlParam, "xmlns:apache", "http://xml.apache.org/xml-soap"); - zend_hash_internal_pointer_reset(data->value.ht); - for(;i > 0;i--) - { - xmlNodePtr xparam, item; - xmlNodePtr key; - zval **temp_data; - char *key_val; - int int_val; - encodePtr enc; + i = zend_hash_num_elements(Z_ARRVAL_P(data)); + //TODO: Register namespace...??? + xmlSetProp(xmlParam, "xmlns:apache", "http://xml.apache.org/xml-soap"); + zend_hash_internal_pointer_reset(data->value.ht); + for(;i > 0;i--) + { + xmlNodePtr xparam, item; + xmlNodePtr key; + zval **temp_data; + char *key_val; + int int_val; + encodePtr enc; zend_hash_get_current_data(data->value.ht, (void **)&temp_data); if(Z_TYPE_PP(temp_data) != IS_NULL) { - item = xmlNewNode(NULL, "item"); - key = xmlNewNode(NULL, "key"); - if(zend_hash_get_current_key(data->value.ht, &key_val, (long *)&int_val, FALSE) == HASH_KEY_IS_STRING) - { - xmlSetProp(key, "xsi:type", "xsd:string"); - xmlNodeSetContent(key, key_val); - } - else - { - smart_str tmp = {0}; - smart_str_append_long(&tmp, int_val); - smart_str_0(&tmp); + item = xmlNewNode(NULL, "item"); + key = xmlNewNode(NULL, "key"); + if(zend_hash_get_current_key(data->value.ht, &key_val, (long *)&int_val, FALSE) == HASH_KEY_IS_STRING) + { + if(style == SOAP_ENCODED) + xmlSetProp(key, "xsi:type", "xsd:string"); + xmlNodeSetContent(key, key_val); + } + else + { + smart_str tmp = {0}; + smart_str_append_long(&tmp, int_val); + smart_str_0(&tmp); - xmlSetProp(key, "xsi:type", "xsd:int"); - xmlNodeSetContentLen(key, tmp.c, tmp.len); + if(style == SOAP_ENCODED) + xmlSetProp(key, "xsi:type", "xsd:int"); + xmlNodeSetContentLen(key, tmp.c, tmp.len); - smart_str_free(&tmp); - } + smart_str_free(&tmp); + } - enc = get_conversion((*temp_data)->type); - xparam = master_to_xml(enc, (*temp_data)); + enc = get_conversion((*temp_data)->type); + xparam = master_to_xml(enc, (*temp_data), style); - xmlNodeSetName(xparam, "value"); - xmlAddChild(item, key); - xmlAddChild(item, xparam); - xmlAddChild(xmlParam, item); + xmlNodeSetName(xparam, "value"); + xmlAddChild(item, key); + xmlAddChild(item, xparam); + xmlAddChild(xmlParam, item); } - zend_hash_move_forward(data->value.ht); - } + zend_hash_move_forward(data->value.ht); + } } - set_ns_and_type(xmlParam, type); + if(style == SOAP_ENCODED) + set_ns_and_type(xmlParam, type); return xmlParam; } @@ -696,7 +732,7 @@ zval *to_zval_map(encodeType type, xmlNodePtr data) } //Unknown encode/decode -xmlNodePtr guess_xml_convert(encodeType type, zval *data) +xmlNodePtr guess_xml_convert(encodeType type, zval *data, int style) { encodePtr enc; TSRMLS_FETCH(); @@ -705,7 +741,7 @@ xmlNodePtr guess_xml_convert(encodeType type, zval *data) enc = get_conversion(data->type); else enc = get_conversion(IS_NULL); - return master_to_xml(enc, data); + return master_to_xml(enc, data, style); } zval *guess_zval_convert(encodeType type, xmlNodePtr data) @@ -756,7 +792,7 @@ zval *guess_zval_convert(encodeType type, xmlNodePtr data) } //Time encode/decode -xmlNodePtr to_xml_datetime_ex(encodeType type, zval *data, char *format) +xmlNodePtr to_xml_datetime_ex(encodeType type, zval *data, char *format, int style) { //logic hacked from ext/standard/datetime.c struct tm *ta, tmbuf; @@ -784,48 +820,50 @@ xmlNodePtr to_xml_datetime_ex(encodeType type, zval *data, char *format) xmlNodeSetContent(xmlParam, buf); efree(buf); - set_ns_and_type(xmlParam, type); + + if(style == SOAP_ENCODED) + set_ns_and_type(xmlParam, type); return xmlParam; } -xmlNodePtr to_xml_datetime(encodeType type, zval *data) +xmlNodePtr to_xml_datetime(encodeType type, zval *data, int style) { - return to_xml_datetime_ex(type, data, "%Y-%m-%dT%H:%M:%S"); + return to_xml_datetime_ex(type, data, "%Y-%m-%dT%H:%M:%S", style); } -xmlNodePtr to_xml_time(encodeType type, zval *data) +xmlNodePtr to_xml_time(encodeType type, zval *data, int style) { - return to_xml_datetime_ex(type, data, "%H:%M:%S"); + return to_xml_datetime_ex(type, data, "%H:%M:%S", style); } -xmlNodePtr to_xml_date(encodeType type, zval *data) +xmlNodePtr to_xml_date(encodeType type, zval *data, int style) { - return to_xml_datetime_ex(type, data, "%Y-%m-%d"); + return to_xml_datetime_ex(type, data, "%Y-%m-%d", style); } -xmlNodePtr to_xml_gyearmonth(encodeType type, zval *data) +xmlNodePtr to_xml_gyearmonth(encodeType type, zval *data, int style) { - return to_xml_datetime_ex(type, data, "%Y-%m"); + return to_xml_datetime_ex(type, data, "%Y-%m", style); } -xmlNodePtr to_xml_gyear(encodeType type, zval *data) +xmlNodePtr to_xml_gyear(encodeType type, zval *data, int style) { - return to_xml_datetime_ex(type, data, "%Y"); + return to_xml_datetime_ex(type, data, "%Y", style); } -xmlNodePtr to_xml_gmonthday(encodeType type, zval *data) +xmlNodePtr to_xml_gmonthday(encodeType type, zval *data, int style) { - return to_xml_datetime_ex(type, data, "--%m-%d"); + return to_xml_datetime_ex(type, data, "--%m-%d", style); } -xmlNodePtr to_xml_gday(encodeType type, zval *data) +xmlNodePtr to_xml_gday(encodeType type, zval *data, int style) { - return to_xml_datetime_ex(type, data, "%d"); + return to_xml_datetime_ex(type, data, "%d", style); } -xmlNodePtr to_xml_gmonth(encodeType type, zval *data) +xmlNodePtr to_xml_gmonth(encodeType type, zval *data, int style) { - return to_xml_datetime_ex(type, data, "%m"); + return to_xml_datetime_ex(type, data, "%m", style); } void set_ns_and_type(xmlNodePtr node, encodeType type) @@ -936,7 +974,7 @@ encodePtr get_conversion_from_type_ex(HashTable *encoding, xmlNodePtr node, char encodePtr *enc = NULL; xmlNsPtr nsptr; char *ns, *cptype; - char *nscat; + smart_str nscat = {0}; if(encoding == NULL) return NULL; @@ -945,15 +983,17 @@ encodePtr get_conversion_from_type_ex(HashTable *encoding, xmlNodePtr node, char nsptr = xmlSearchNs(node->doc, node, ns); if(nsptr != NULL) { - nscat = emalloc(strlen(nsptr->href) + strlen(cptype) + 2); - sprintf(nscat, "%s:%s", nsptr->href, cptype); + smart_str_appends(&nscat, nsptr->href); + smart_str_appendc(&nscat, ':'); + smart_str_appends(&nscat, cptype); + smart_str_0(&nscat); - if(zend_hash_find(encoding, nscat, strlen(nscat), (void **)&enc) == FAILURE) + if(zend_hash_find(encoding, nscat.c, nscat.len + 1, (void **)&enc) == FAILURE) { if(zend_hash_find(encoding, type, strlen(type) + 1, (void **)&enc) == FAILURE) enc = NULL; } - efree(nscat); + smart_str_free(&nscat); } else { @@ -1064,7 +1104,7 @@ smart_str *build_soap_action(zval *this_ptr, char *soapaction) php_error(E_ERROR, "Error finding uri"); smart_str_appendl(tmp, Z_STRVAL_PP(uri), Z_STRLEN_PP(uri)); - smart_str_appends(tmp, "/#"); + smart_str_appends(tmp, "#"); smart_str_appendl(tmp, soapaction, strlen(soapaction)); smart_str_0(tmp); diff --git a/ext/soap/php_encoding.h b/ext/soap/php_encoding.h index 7e422dcf9e..a6a9b43270 100644 --- a/ext/soap/php_encoding.h +++ b/ext/soap/php_encoding.h @@ -112,6 +112,14 @@ #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_SOAP_NS_PREFIX "wsdlSoap" + +#define WSDL_HTTP_NAMESPACE "http://schemas.xmlsoap.org/wsdl/http/" +#define WSDL_HTTP_NS_PREFIX "http" + +#define WSDL_HTTP_TRANSPORT "http://schemas.xmlsoap.org/soap/http" + #define UNKNOWN_TYPE 999998 #define END_KNOWN_TYPES 999999 @@ -128,27 +136,27 @@ struct _encode { encodeType details; zval *(*to_zval)(encodeType type, xmlNodePtr data); - xmlNodePtr (*to_xml)(encodeType type, zval *data); + xmlNodePtr (*to_xml)(encodeType type, zval *data, int style); - xmlNodePtr (*to_zval_before)(encodeType type, xmlNodePtr data); + xmlNodePtr (*to_zval_before)(encodeType type, xmlNodePtr data, int style); zval *(*to_zval_after)(encodeType type, zval *data); zval *(*to_xml_before)(encodeType type, zval *data); - xmlNodePtr (*to_xml_after)(encodeType type, xmlNodePtr data); + xmlNodePtr (*to_xml_after)(encodeType type, xmlNodePtr data, int style); }; smart_str *build_soap_action(zval *this_ptr, char *soapaction); // Master functions all encode/decode should be called thur these functions -xmlNodePtr master_to_xml(encodePtr encode, zval *data); +xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style); zval *master_to_zval(encodePtr encode, xmlNodePtr data); #ifdef HAVE_PHP_DOMXML //user defined mapping zval *to_xml_before_user(encodeType type, zval *data); -xmlNodePtr to_xml_user(encodeType type, zval *data); -xmlNodePtr to_xml_after_user(encodeType type, xmlNodePtr node); -xmlNodePtr to_zval_before_user(encodeType type, xmlNodePtr node); +xmlNodePtr to_xml_user(encodeType type, zval *data, int style); +xmlNodePtr to_xml_after_user(encodeType type, xmlNodePtr node, int style); +xmlNodePtr to_zval_before_user(encodeType type, xmlNodePtr node, int style); zval *to_zval_user(encodeType type, xmlNodePtr node); zval *to_zval_after_user(encodeType type, zval *data); #endif @@ -164,37 +172,37 @@ zval *to_zval_map(encodeType type, xmlNodePtr data); zval *to_zval_null(encodeType type, xmlNodePtr data); zval *guess_zval_convert(encodeType type, xmlNodePtr data); -xmlNodePtr to_xml_long(encodeType type, zval *data); -xmlNodePtr to_xml_bool(encodeType type, zval *data); +xmlNodePtr to_xml_long(encodeType type, zval *data, int style); +xmlNodePtr to_xml_bool(encodeType type, zval *data, int style); //String encode -xmlNodePtr to_xml_string(encodeType type, zval *data); -xmlNodePtr to_xml_stringl(encodeType type, zval *data); +xmlNodePtr to_xml_string(encodeType type, zval *data, int style); +xmlNodePtr to_xml_stringl(encodeType type, zval *data, int style); //Null encode -xmlNodePtr to_xml_null(encodeType type, zval *data); +xmlNodePtr to_xml_null(encodeType type, zval *data, int style); //Struct encode -xmlNodePtr to_xml_object(encodeType type, zval *data); +xmlNodePtr to_xml_object(encodeType type, zval *data, int style); //Array encode -xmlNodePtr guess_array_map(encodeType type, zval *data); -xmlNodePtr to_xml_array(encodeType type, zval *data); -xmlNodePtr to_xml_map(encodeType type, zval *data); +xmlNodePtr guess_array_map(encodeType type, zval *data, int style); +xmlNodePtr to_xml_array(encodeType type, zval *data, int style); +xmlNodePtr to_xml_map(encodeType type, zval *data, int style); //Try and guess for non-wsdl clients and servers -xmlNodePtr guess_xml_convert(encodeType type, zval *data); +xmlNodePtr guess_xml_convert(encodeType type, zval *data, int style); //Datetime encode/decode -xmlNodePtr to_xml_datetime_ex(encodeType type, zval *data, char *format); -xmlNodePtr to_xml_datetime(encodeType type, zval *data); -xmlNodePtr to_xml_time(encodeType type, zval *data); -xmlNodePtr to_xml_date(encodeType type, zval *data); -xmlNodePtr to_xml_gyearmonth(encodeType type, zval *data); -xmlNodePtr to_xml_gyear(encodeType type, zval *data); -xmlNodePtr to_xml_gmonthday(encodeType type, zval *data); -xmlNodePtr to_xml_gday(encodeType type, zval *data); -xmlNodePtr to_xml_gmonth(encodeType type, zval *data); +xmlNodePtr to_xml_datetime_ex(encodeType type, zval *data, char *format, int style); +xmlNodePtr to_xml_datetime(encodeType type, zval *data, int style); +xmlNodePtr to_xml_time(encodeType type, zval *data, int style); +xmlNodePtr to_xml_date(encodeType type, zval *data, int style); +xmlNodePtr to_xml_gyearmonth(encodeType type, zval *data, int style); +xmlNodePtr to_xml_gyear(encodeType type, zval *data, int style); +xmlNodePtr to_xml_gmonthday(encodeType type, zval *data, int style); +xmlNodePtr to_xml_gday(encodeType type, zval *data, int style); +xmlNodePtr to_xml_gmonth(encodeType type, zval *data, int style); #define get_conversion(e) get_conversion_ex(SOAP_GLOBAL(defEncIndex), e) #define get_conversion_from_type(n, t) get_conversion_from_type_ex(SOAP_GLOBAL(defEnc), n, t) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 5ec7d0d4fd..38243dbb93 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -8,10 +8,7 @@ void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, ch sdlPtr sdl; php_url *phpurl = NULL; SOAP_STREAM stream; - -#ifdef SOAP_DEBUG - zval *raw_request; -#endif + zval **trace; TSRMLS_FETCH(); @@ -21,17 +18,18 @@ void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, ch xmlDocDumpMemory(doc, &buf, &buf_size); -#ifdef SOAP_DEBUG - MAKE_STD_ZVAL(raw_request); - ZVAL_STRINGL(raw_request, buf, buf_size, 1); - add_property_zval(this_ptr, "__last_request", raw_request); -#endif + if(!buf) + php_error(E_ERROR, "Error build soap request"); + + if(zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS + && Z_LVAL_PP(trace) > 0) + add_property_stringl(this_ptr, "__last_request", buf, buf_size, 1); if(!stream) { char *url; - if(sdl == NULL) + if(!sdl) { zval **location; if(zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &location) == FAILURE) @@ -39,7 +37,11 @@ void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, ch url = Z_STRVAL_PP(location); } else - url = sdl->location; + { + sdlBindingPtr binding; + FETCH_THIS_PORT(binding); + url = binding->location; + } phpurl = php_url_parse(url); @@ -60,19 +62,19 @@ void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, ch } else php_error(E_ERROR,"Could not connect to host"); - /*php_url_free(phpurl);*/ + //php_url_free(phpurl); } if(stream) { zval **cookies; - char *header = "POST %s HTTP/1.0\r\nConnection: close\r\nAccept: text/html; text/xml; text/plain\r\nUser-Agent: PHP SOAP 0.1\r\nHost: %s\r\nContent-Type: text/xml\r\nContent-Length: %d\r\nSOAPAction: \"%s\"\r\n"; + char *header = "POST %s HTTP/1.1\r\nConnection: close\r\nAccept: text/html; text/xml; text/plain\r\nUser-Agent: PHP SOAP 0.1\r\nHost: %s\r\nContent-Type: text/xml\r\nContent-Length: %d\r\nSOAPAction: \"%s\"\r\n"; int size = strlen(header) + strlen(phpurl->host) + strlen(phpurl->path) + 10; - /* TODO: Add authication */ + // TODO: Add authication if(sdl != NULL) { - /* TODO: need to grab soap action from wsdl.... */ + // TODO: need to grab soap action from wsdl.... soap_headers = emalloc(size + strlen(soapaction)); sprintf(soap_headers, header, phpurl->path, phpurl->host, buf_size, soapaction); } @@ -90,7 +92,7 @@ void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, ch if(err != (int)strlen(soap_headers)) php_error(E_ERROR,"Failed Sending HTTP Headers"); - /* Send cookies along with request */ + // Send cookies along with request if(zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == SUCCESS) { smart_str cookie_str = {0}; @@ -149,15 +151,12 @@ void send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *function_name, ch void get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len) { - char *http_headers, *http_body, *content_type, *http_version, http_status[4], *cookie_itt, *connection; + char *http_headers, *http_body, *content_type, *http_version, http_status[4], *cookie_itt; int http_header_size, http_body_size, http_close; sdlPtr sdl; zval **socket_ref; SOAP_STREAM stream; - -#ifdef SOAP_DEBUG - zval *raw_response; -#endif + zval **trace; TSRMLS_FETCH(); @@ -220,17 +219,13 @@ void get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len) if(!get_http_body(stream, http_headers, &http_body, &http_body_size)) php_error(E_ERROR, "Error Fetching http body"); -#ifdef SOAP_DEBUG - MAKE_STD_ZVAL(raw_response); - ZVAL_STRINGL(raw_response, http_body, http_body_size, 1); - add_property_zval(this_ptr, "__last_response", raw_response); -#endif + if(zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS + && Z_LVAL_PP(trace) > 0) + add_property_stringl(this_ptr, "__last_response", http_body, http_body_size, 1); - /* - * Close every time right now till i can spend more time on it - * it works.. it's just slower?? - * See if the server requested a close - */ + // Close every time right now till i can spend more time on it + // it works.. it's just slower?? + //See if the server requested a close http_close = TRUE; /* connection = get_http_header_value(http_headers,"Connection: "); @@ -258,7 +253,7 @@ void get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len) zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", strlen("httpsocket") + 1); } - /* Check and see if the server even sent a xml document */ + //Check and see if the server even sent a xml document content_type = get_http_header_value(http_headers,"Content-Type: "); if(content_type) { @@ -285,12 +280,10 @@ void get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len) efree(content_type); } - /* - Grab and send back every cookie - Not going to worry about Path: because - we shouldn't be changing urls so path dont - matter too much - */ + //Grab and send back every cookie + //Not going to worry about Path: because + //we shouldn't be changing urls so path dont + //matter too much cookie_itt = strstr(http_headers,"Set-Cookie: "); while(cookie_itt) { @@ -363,10 +356,8 @@ int get_http_body(SOAP_STREAM stream, char *headers, char **response, int *out_ trans_enc = get_http_header_value(headers, "Transfer-Encoding: "); content_length = get_http_header_value(headers, "Content-Length: "); - /* - this is temp... - netscape enterprise server sends in lowercase??? - */ + //this is temp... + // netscape enterprise server sends in lowercase??? if(content_length == NULL) content_length = get_http_header_value(headers, "Content-length: "); @@ -402,7 +393,7 @@ int get_http_body(SOAP_STREAM stream, char *headers, char **response, int *out_ #ifdef PHP_STREAMS php_stream_getc(stream);php_stream_getc(stream); #else - /* Eat up '\r' '\n' */ + //Eat up '\r' '\n' php_sock_fgetc(stream);php_sock_fgetc(stream); #endif } diff --git a/ext/soap/php_packet_soap.c b/ext/soap/php_packet_soap.c index 3414f970eb..b2339f08db 100644 --- a/ext/soap/php_packet_soap.c +++ b/ext/soap/php_packet_soap.c @@ -10,6 +10,8 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction response = xmlParseMemory(buffer, buffer_size); xmlCleanupParser(); + (*num_params) = 0; + trav = response->children; FOREACHNODE(trav,"Envelope",env) { @@ -60,11 +62,7 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction xmlNodePtr val; zend_hash_internal_pointer_reset(fn->responseParameters); - if(zend_hash_get_current_data(fn->responseParameters, (void **)&h_param) != SUCCESS) - { - (*num_params) = 0; - } - else + if(zend_hash_get_current_data(fn->responseParameters, (void **)&h_param) == SUCCESS) { param = (*h_param); val = get_node(cur->children, param->paramName); diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index 020b299d47..36cf1ab49a 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -83,7 +83,7 @@ int schema_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpleType, sdlTyp if(name != NULL) { HashTable *ht; - char *key; + smart_str key = {0}; sdlTypePtr newType, *ptr; newType = malloc(sizeof(sdlType)); @@ -94,8 +94,10 @@ int schema_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpleType, sdlTyp if(cur_type == NULL) { ht = (*sdl)->types; - key = emalloc(strlen(newType->namens) + strlen(newType->name) + 2); - sprintf(key, "%s:%s", newType->namens, newType->name); + smart_str_appends(&key, newType->namens); + smart_str_appendc(&key, ':'); + smart_str_appends(&key, newType->name); + smart_str_0(&key); } else { @@ -104,13 +106,13 @@ int schema_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpleType, sdlTyp cur_type->elements = malloc(sizeof(HashTable)); zend_hash_init(cur_type->elements, 0, NULL, delete_type, 1); } - key = strdup(newType->name); ht = cur_type->elements; + smart_str_appends(&key, cur_type->name); } - zend_hash_add(ht, key, strlen(key), &newType, sizeof(sdlTypePtr), (void **)&ptr); + zend_hash_add(ht, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), (void **)&ptr); cur_type = (*ptr); - efree(key); + smart_str_free(&key); } content = get_node(simpleType->children, "restriction"); @@ -749,7 +751,7 @@ int schema_complexType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compType, sdlType { HashTable *ht; sdlTypePtr newType, *ptr; - char *key; + smart_str key = {0}; newType = malloc(sizeof(sdlType)); memset(newType, 0, sizeof(sdlType)); @@ -759,8 +761,10 @@ int schema_complexType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compType, sdlType if(cur_type == NULL) { ht = (*sdl)->types; - key = emalloc(strlen(newType->namens) + strlen(newType->name) + 2); - sprintf(key, "%s:%s", newType->namens, newType->name); + smart_str_appends(&key, newType->namens); + smart_str_appendc(&key, ':'); + smart_str_appends(&key, newType->name); + smart_str_0(&key); } else { @@ -770,13 +774,13 @@ int schema_complexType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compType, sdlType zend_hash_init(cur_type->elements, 0, NULL, delete_type, 1); } ht = cur_type->elements; - key = estrdup(cur_type->name); + smart_str_appends(&key, newType->name); } - zend_hash_add(ht, key, strlen(key), &newType, sizeof(sdlTypePtr), (void **)&ptr); + zend_hash_add(ht, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), (void **)&ptr); cur_type = (*ptr); create_encoder((*sdl), cur_type, ns->children->content, name->children->content); - efree(key); + smart_str_free(&key); } content = get_node(compType->children, "simpleContent"); @@ -859,6 +863,7 @@ int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr c { HashTable *addHash; sdlTypePtr newType, *tmp; + smart_str key = {0}; newType = malloc(sizeof(sdlType)); @@ -870,7 +875,12 @@ int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr c newType->max_occurs = 1; if(cur_type == NULL) + { addHash = (*sdl)->types; + smart_str_appends(&key, newType->namens); + smart_str_appendc(&key, ':'); + smart_str_appends(&key, newType->name); + } else { if(cur_type->elements == NULL) @@ -879,16 +889,33 @@ int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr c zend_hash_init(cur_type->elements, 0, NULL, delete_type, 1); } addHash = cur_type->elements; + smart_str_appends(&key, newType->name); } - zend_hash_add(addHash, newType->name, strlen(newType->name), &newType, sizeof(sdlTypePtr), (void **)&tmp); + smart_str_0(&key); + zend_hash_add(addHash, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), (void **)&tmp); cur_type = (*tmp); + create_encoder((*sdl), cur_type, ns->children->content, name->children->content); + smart_str_free(&key); } + curattr = get_attribute(attrs, "maxOccurs"); + if(curattr) + { + if(!strcmp(curattr->children->content, "unbounded")) + cur_type->max_occurs = -1; + else + cur_type->max_occurs = atoi(curattr->children->content); + } + + curattr = get_attribute(attrs, "minOccurs"); + if(curattr) + cur_type->min_occurs = atoi(curattr->children->content); + //nillable = boolean : false attrs = element->properties; curattr = get_attribute(attrs, "nillable"); - if(curattr != NULL) + if(curattr) { if(!stricmp(curattr->children->content, "true") || !stricmp(curattr->children->content, "1")) @@ -919,6 +946,9 @@ int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr c if(cptype) efree(cptype); } + if(cur_type->max_occurs == -1 || cur_type->max_occurs > 1) + cur_type->encode = get_conversion(SOAP_ENC_ARRAY); + content = get_node(element->children, "simpleType"); if(content) schema_simpleType(sdl, tsn, content, cur_type); diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index 9d73d2fbe8..f0c0c44753 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -63,14 +63,16 @@ encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, char *ns, char *ty encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, char *ns, char *type) { - char *nscat; + smart_str nscat = {0}; encodePtr enc; enc = malloc(sizeof(encode)); memset(enc, 0, sizeof(encode)); - nscat = emalloc(strlen(ns) + strlen(type) + 2); - sprintf(nscat, "%s:%s", ns, type); + smart_str_appends(&nscat, ns); + smart_str_appendc(&nscat, ':'); + smart_str_appends(&nscat, type); + smart_str_0(&nscat); enc->details.ns = strdup(ns); enc->details.type_str = strdup(type); @@ -83,12 +85,12 @@ encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, char *ns, char *type) sdl->encoders = malloc(sizeof(HashTable)); zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 1); } - zend_hash_add(sdl->encoders, nscat, strlen(nscat), &enc, sizeof(encodePtr), NULL); - efree(nscat); + zend_hash_add(sdl->encoders, nscat.c, nscat.len + 1, &enc, sizeof(encodePtr), NULL); + smart_str_free(&nscat); return enc; } -xmlNodePtr sdl_guess_convert_xml(encodeType enc, zval *data) +xmlNodePtr sdl_guess_convert_xml(encodeType enc, zval *data, int style) { sdlTypePtr type; xmlNodePtr ret; @@ -99,26 +101,26 @@ xmlNodePtr sdl_guess_convert_xml(encodeType enc, zval *data) if(type->encode->details.type == IS_ARRAY || type->encode->details.type == SOAP_ENC_ARRAY) { - ret = sdl_to_xml_array(type, data); + ret = sdl_to_xml_array(type, data, style); } else if(type->encode != NULL) { - ret = master_to_xml(type->encode, data); + ret = master_to_xml(type->encode, data, style); } else if(type->elements != NULL) { - ret = sdl_to_xml_object(type, data); + ret = sdl_to_xml_object(type, data, style); } else { - ret = guess_xml_convert(enc, data); + ret = guess_xml_convert(enc, data, style); } //set_ns_and_type(ret, enc); return ret; } -xmlNodePtr sdl_to_xml_object(sdlTypePtr type, zval *data) +xmlNodePtr sdl_to_xml_object(sdlTypePtr type, zval *data, int style) { xmlNodePtr ret; sdlTypePtr *t, tmp; @@ -139,7 +141,7 @@ xmlNodePtr sdl_to_xml_object(sdlTypePtr type, zval *data) { xmlNodePtr newNode; - newNode = master_to_xml(tmp->encode, (*prop)); + newNode = master_to_xml(tmp->encode, (*prop), style); xmlNodeSetName(newNode, tmp->name); xmlAddChild(ret, newNode); } @@ -149,7 +151,7 @@ xmlNodePtr sdl_to_xml_object(sdlTypePtr type, zval *data) return ret; } -xmlNodePtr sdl_to_xml_array(sdlTypePtr type, zval *data) +xmlNodePtr sdl_to_xml_array(sdlTypePtr type, zval *data, int style) { smart_str array_type_and_size = {0}, array_type = {0}; int i; @@ -212,7 +214,7 @@ xmlNodePtr sdl_to_xml_array(sdlTypePtr type, zval *data) zend_hash_get_current_data(data->value.ht, (void **)&zdata); enc = get_conversion((*zdata)->type); - xparam = master_to_xml(enc, (*zdata)); + xparam = master_to_xml(enc, (*zdata), style); xmlNodeSetName(xparam, "val"); xmlAddChild(xmlParam, xparam); @@ -258,7 +260,7 @@ sdlPtr get_sdl(char *uri) hndl = NULL; if(zend_hash_find(SOAP_GLOBAL(sdls), uri, strlen(uri), (void **)&hndl) == FAILURE) { - tmp = load_wsdl(uri); + tmp = load_wsdl(uri, NULL); zend_hash_add(SOAP_GLOBAL(sdls), uri, strlen(uri), &tmp, sizeof(sdlPtr), NULL); } else @@ -267,6 +269,35 @@ sdlPtr get_sdl(char *uri) return tmp; } +sdlBindingPtr get_binding_from_type(sdlPtr sdl, int type) +{ + sdlBindingPtr *binding; + + for(zend_hash_internal_pointer_reset(sdl->bindings); + zend_hash_get_current_data(sdl->bindings, (void **) &binding) == SUCCESS; + zend_hash_move_forward(sdl->bindings)) + { + if((*binding)->bindingType == type) + return *binding; + } + return NULL; +} + +sdlBindingPtr get_binding_from_name(sdlPtr sdl, char *name, char *ns) +{ + sdlBindingPtr binding = NULL; + smart_str key = {0}; + + smart_str_appends(&key, ns); + smart_str_appendc(&key, ':'); + smart_str_appends(&key, name); + + zend_hash_find(sdl->bindings, key.c, key.len, (void **)&binding); + + smart_str_free(&key); + return binding; +} + int load_php_sdl() { /* xmlNodePtr rootElement; @@ -441,37 +472,39 @@ int write_php_sdl() return TRUE; } -sdlPtr load_wsdl(char *struri) +sdlPtr load_wsdl(char *struri, sdlPtr parent) { xmlDocPtr wsdl; - xmlNodePtr root, definitions, types, binding, schema, service; + xmlNodePtr root, definitions, types, binding, schema, service, import; xmlNodePtr trav, trav2, trav3; xmlAttrPtr targetNamespace; sdlPtr tmpsdl; TSRMLS_FETCH(); - tmpsdl = malloc(sizeof(sdl)); - memset(tmpsdl, 0, sizeof(sdl)); - - tmpsdl->source = strdup(struri); + if(!parent) + { + tmpsdl = malloc(sizeof(sdl)); + memset(tmpsdl, 0, sizeof(sdl)); + tmpsdl->source = strdup(struri); + } + else + tmpsdl = parent; wsdl = xmlParseFile(struri); xmlCleanupParser(); if(!wsdl) - php_error(E_ERROR, "Error parsing wsdl file"); + php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Could't load"); tmpsdl->doc = wsdl; root = wsdl->children; definitions = get_node(root, "definitions"); if(!definitions) - php_error(E_ERROR, "Error parsing wsdl file"); + php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Could't find definitions"); targetNamespace = get_attribute(definitions->properties, "targetNamespace"); if(targetNamespace) - { tmpsdl->target_ns = strdup(targetNamespace->children->content); - } types = get_node(definitions->children, "types"); if(types) @@ -483,6 +516,15 @@ sdlPtr load_wsdl(char *struri) } ENDFOREACH(trav); } + + trav = definitions->children; + FOREACHNODE(trav, "import", import) + { + xmlAttrPtr tmp = get_attribute(import->properties, "location"); + if(tmp) + load_wsdl(tmp->children->content, tmpsdl); + } + ENDFOREACH(trav); service = get_node(definitions->children, "service"); if(service != NULL) @@ -491,216 +533,343 @@ sdlPtr load_wsdl(char *struri) xmlNodePtr trav, port; name = get_attribute(service->properties, "name"); - if(name == NULL) - php_error(E_ERROR, "Error parsing wsdl (\"No name associated with service\")"); + if(!name) + php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: No name associated with service"); trav = service->children; FOREACHNODE(trav, "port", port) { - xmlAttrPtr name, binding, location; + xmlAttrPtr type, name, bindingAttr, location; + xmlNodePtr portType, operation; xmlNodePtr address; + char *ns, *ctype; + sdlBindingPtr tmpbinding; + + tmpbinding = malloc(sizeof(sdlBinding)); + memset(tmpbinding, 0, sizeof(sdlBinding)); name = get_attribute(port->properties, "name"); - if(name == NULL) - php_error(E_ERROR, "Error parsing wsdl (\"No name associated with port\")"); + if(!name) + php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: No name associated with port"); - binding = get_attribute(port->properties, "binding"); - if(binding == NULL) - php_error(E_ERROR, "Error parsing wsdl (\"No binding associated with port\")"); + bindingAttr = get_attribute(port->properties, "binding"); + if(bindingAttr == NULL) + php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: No binding associated with port"); - //TODO: validate this is "soap" namespace + //find address and figure out binding type address = get_node(port->children, "address"); - if(address == NULL) - php_error(E_ERROR, "Error parsing wsdl (\"No soap:address associated with port\")"); + if(!address) + php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: No address associated with port"); location = get_attribute(address->properties, "location"); - if(location == NULL) - php_error(E_ERROR, "Error parsing wsdl (\"No location associated with soap:address\")"); + if(!location) + php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: No location associated with port"); - tmpsdl->location = strdup(location->children->content); - } - ENDFOREACH(trav); - - } - else - php_error(E_ERROR, "Error parsing wsdl (\"Couldn't bind to service\")"); + tmpbinding->location = strdup(location->children->content); - trav = definitions->children; - FOREACHNODE(trav, "binding", binding) - { - xmlAttrPtr name, type; - xmlNodePtr portType, operation; - char *ns, *ctype; - - name = get_attribute(binding->properties, "name"); - if(name == NULL) - php_error(E_ERROR, "Error parsing wsdl (Missing \"name\" attribute for \"binding\")"); - - type = get_attribute(binding->properties, "type"); - if(type == NULL) - php_error(E_ERROR, "Error parsing wsdl (Missing \"type\" attribute for \"binding\")"); - - parse_namespace(type->children->content, &ctype, &ns); - portType = get_node_with_attribute(definitions->children, "portType", "name", ctype); - if(portType == NULL) - php_error(E_ERROR, "Error parsing wsdl (Missing \"portType\" with name \"%s\")", name->children->content); - if(ctype) efree(ctype); - if(ns) efree(ns); - - trav2 = binding->children; - FOREACHNODE(trav2, "operation", operation) - { - sdlFunctionPtr function; - xmlNodePtr input, output, fault, portTypeOperation, msgInput, msgOutput, soapOperation; - xmlAttrPtr op_name, paramOrder; + if(address->ns && !strcmp(address->ns->href, WSDL_SOAP_NAMESPACE)) + tmpbinding->bindingType = BINDING_SOAP; + else if(address->ns && !strcmp(address->ns->href, WSDL_HTTP_NAMESPACE)) + tmpbinding->bindingType = BINDING_HTTP; - op_name = get_attribute(operation->properties, "name"); - if(op_name == NULL) - php_error(E_ERROR, "Error parsing wsdl (Missing \"name\" attribute for \"operation\")"); + parse_namespace(bindingAttr->children->content, &ctype, &ns); + binding = get_node_with_attribute(definitions->children, "binding", "name", ctype); + if(ns) efree(ns); if(ctype) efree(ctype); - portTypeOperation = get_node_with_attribute(portType->children, "operation", "name", op_name->children->content); - if(portTypeOperation == NULL) - php_error(E_ERROR, "Error parsing wsdl (Missing \"portType/operation\" with name \"%s\")", op_name->children->content); + if(!binding) + php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: No binding"); - if(tmpsdl->functions == NULL) + if(tmpbinding->bindingType == BINDING_SOAP) { - tmpsdl->functions = malloc(sizeof(HashTable)); - zend_hash_init(tmpsdl->functions, 0, NULL, delete_function, 1); + sdlSoapBindingPtr soapBinding; + xmlNodePtr soapBindingNode; + xmlAttrPtr tmp; + + soapBinding = malloc(sizeof(sdlSoapBinding)); + memset(soapBinding, 0, sizeof(sdlSoapBinding)); + + 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; + else + soapBinding->style = SOAP_RPC; + + tmp = get_attribute(soapBindingNode->properties, "transport"); + if(tmp) + { + if(strcmp(tmp->children->content, WSDL_HTTP_TRANSPORT)) + php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: PHP-SOAP doesn't support transport '%s'", tmp->children->content); + + soapBinding->transport = strdup(tmp->children->content); + } + tmpbinding->bindingAttributes = (void *)soapBinding; + } } - function = malloc(sizeof(sdlFunction)); - function->functionName = strdup(op_name->children->content); - function->requestParameters = NULL; - function->responseParameters = NULL; - function->responseName = NULL; - function->soapAction = NULL; + name = get_attribute(binding->properties, "name"); + if(name == NULL) + php_error(E_ERROR, "Error parsing wsdl (Missing \"name\" attribute for \"binding\")"); - soapOperation = get_node(operation->children, "operation"); - if(soapOperation) - { - xmlAttrPtr action = get_attribute(soapOperation->properties, "soapAction"); - if(action) - function->soapAction = strdup(action->children->content); - } + tmpbinding->name = strdup(name->children->content); + + type = get_attribute(binding->properties, "type"); + if(type == NULL) + php_error(E_ERROR, "Error parsing wsdl (Missing \"type\" attribute for \"binding\")"); - input = get_node(portTypeOperation->children, "input"); - if(input != NULL) + parse_namespace(type->children->content, &ctype, &ns); + portType = get_node_with_attribute(definitions->children, "portType", "name", ctype); + if(portType == NULL) + php_error(E_ERROR, "Error parsing wsdl (Missing \"portType\" with name \"%s\")", name->children->content); + if(ctype) efree(ctype); if(ns) efree(ns); + + trav2 = binding->children; + FOREACHNODE(trav2, "operation", operation) { - xmlAttrPtr message; - xmlNodePtr part; - char *ns, *ctype; - - message = get_attribute(input->properties, "message"); - if(message == NULL) - php_error(E_ERROR, "Error parsing wsdl (Missing name for \"input\" of \"%s\")", op_name->children->content); - - 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); - msgInput = get_node_with_attribute(definitions->children, "message", "name", ctype); - if(msgInput == NULL) - php_error(E_ERROR, "Error parsing wsdl (Missing \"message\" with name \"%s\")", message->children->content); - if(ctype) efree(ctype); - if(ns) efree(ns); - - trav3 = msgInput->children; - FOREACHNODE(trav3, "part", part) + sdlFunctionPtr function; + xmlNodePtr input, output, fault, portTypeOperation, portTypeInput, msgInput, msgOutput; + xmlAttrPtr op_name, paramOrder; + + op_name = get_attribute(operation->properties, "name"); + if(op_name == NULL) + php_error(E_ERROR, "Error parsing wsdl (Missing \"name\" attribute for \"operation\")"); + + portTypeOperation = get_node_with_attribute(portType->children, "operation", "name", op_name->children->content); + if(portTypeOperation == NULL) + php_error(E_ERROR, "Error parsing wsdl (Missing \"portType/operation\" with name \"%s\")", op_name->children->content); + + function = malloc(sizeof(sdlFunction)); + function->functionName = strdup(op_name->children->content); + function->requestParameters = NULL; + function->responseParameters = NULL; + function->responseName = NULL; + function->bindingAttributes = NULL; + function->bindingType = tmpbinding->bindingType; + + if(tmpbinding->bindingType == BINDING_SOAP) { - xmlAttrPtr element, type, name; - sdlParamPtr param; + sdlSoapBindingFunctionPtr soapFunctionBinding; + sdlSoapBindingPtr soapBinding; + xmlNodePtr soapOperation; + xmlAttrPtr tmp; + + soapFunctionBinding = malloc(sizeof(sdlSoapBindingFunction)); + memset(soapFunctionBinding, 0, sizeof(sdlSoapBindingFunction)); + soapBinding = (sdlSoapBindingPtr)tmpbinding->bindingAttributes; + soapFunctionBinding->style = soapBinding->style; + + soapOperation = get_node_ex(operation->children, "operation", WSDL_SOAP_NAMESPACE); + if(soapOperation) + { + tmp = get_attribute(soapOperation->properties, "soapAction"); + if(tmp) + soapFunctionBinding->soapAction = strdup(tmp->children->content); + + 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; + } + + function->bindingAttributes = (void *)soapFunctionBinding; + } + + input = get_node(operation->children, "input"); + if(input != NULL) + { + xmlAttrPtr message; + xmlNodePtr part; + char *ns, *ctype; + + portTypeInput = get_node(portTypeOperation->children, "input"); + 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); + + 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); + msgInput = get_node_with_attribute(definitions->children, "message", "name", ctype); + if(msgInput == NULL) + php_error(E_ERROR, "Error parsing wsdl (Missing \"message\" with name \"%s\")", message->children->content); + if(ctype) efree(ctype); if(ns) efree(ns); + + if(tmpbinding->bindingType == BINDING_SOAP) + { + sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes; + xmlNodePtr body; + xmlAttrPtr tmp; + + 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")) + soapFunctionBinding->input.use = SOAP_LITERAL; + else + soapFunctionBinding->input.use = SOAP_ENCODED; + + tmp = get_attribute(body->properties, "namespace"); + if(tmp) + soapFunctionBinding->input.ns = strdup(tmp->children->content); + + tmp = get_attribute(body->properties, "parts"); + if(tmp) + soapFunctionBinding->input.parts = strdup(tmp->children->content); + + tmp = get_attribute(body->properties, "encodingStyle"); + if(tmp) + soapFunctionBinding->input.encodingStyle = strdup(tmp->children->content); + } + } + + trav3 = msgInput->children; + FOREACHNODE(trav3, "part", part) + { + xmlAttrPtr element, type, name; + sdlParamPtr param; - 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\")", msgInput->name); + name = get_attribute(part->properties, "name"); + if(name == NULL) + php_error(E_ERROR, "Error parsing wsdl (No name associated with part \"%s\")", msgInput->name); - param->paramName = strdup(name->children->content); + param->paramName = strdup(name->children->content); - element = get_attribute(part->properties, "element"); - if(element != NULL) - param->encode = get_encoder_from_prefix(tmpsdl, part, element->children->content); + element = get_attribute(part->properties, "element"); + if(element != NULL) + param->encode = get_encoder_from_prefix(tmpsdl, part, element->children->content); - type = get_attribute(part->properties, "type"); - if(type != NULL) - param->encode = get_encoder_from_prefix(tmpsdl, part, type->children->content); + type = get_attribute(part->properties, "type"); + if(type != NULL) + param->encode = get_encoder_from_prefix(tmpsdl, part, type->children->content); - zend_hash_next_index_insert(function->requestParameters, ¶m, sizeof(sdlParamPtr), NULL); + zend_hash_next_index_insert(function->requestParameters, ¶m, sizeof(sdlParamPtr), NULL); + } + ENDFOREACH(trav3); } - ENDFOREACH(trav3); - } - paramOrder = get_attribute(portTypeOperation->properties, "parameterOrder"); - if(paramOrder) - { + paramOrder = get_attribute(portTypeOperation->properties, "parameterOrder"); + if(paramOrder) + { - } + } - output = get_node(portTypeOperation->children, "output"); - if(output != NULL) - { - xmlAttrPtr message; - xmlNodePtr part; - char *ns, *ctype; + output = get_node(portTypeOperation->children, "output"); + if(output != NULL) + { + xmlAttrPtr message; + xmlNodePtr part; + char *ns, *ctype; - function->responseName = malloc(strlen(function->functionName) + strlen("Response") + 1); - sprintf(function->responseName, "%sResponse\0", function->functionName); - function->responseParameters = malloc(sizeof(HashTable)); - zend_hash_init(function->responseParameters, 0, NULL, delete_paramater, 1); + function->responseName = malloc(strlen(function->functionName) + strlen("Response") + 1); + sprintf(function->responseName, "%sResponse\0", 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(output->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); - msgOutput = get_node_with_attribute(definitions->children, "message", "name", ctype); - if(msgOutput == NULL) - php_error(E_ERROR, "Error parsing wsdl (Missing \"message\" with name \"%s\")", message->children->content); - if(ctype) efree(ctype); - if(ns) efree(ns); + parse_namespace(message->children->content, &ctype, &ns); + msgOutput = get_node_with_attribute(definitions->children, "message", "name", ctype); + if(msgOutput == NULL) + php_error(E_ERROR, "Error parsing wsdl (Missing \"message\" with name \"%s\")", message->children->content); + if(ctype) efree(ctype); if(ns) efree(ns); - trav3 = msgOutput->children; - FOREACHNODE(trav3, "part", part) - { - sdlParamPtr param; - xmlAttrPtr element, type, name; + if(tmpbinding->bindingType == BINDING_SOAP) + { + sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes; + xmlNodePtr body; + xmlAttrPtr tmp; - param = malloc(sizeof(sdlParam)); - param->order = 0; + 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, "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); + } + } - name = get_attribute(part->properties, "name"); - if(name == NULL) - php_error(E_ERROR, "Error parsing wsdl (No name associated with part \"%s\")", msgOutput->name); + trav3 = msgOutput->children; + FOREACHNODE(trav3, "part", part) + { + sdlParamPtr param; + xmlAttrPtr element, type, name; - param->paramName = strdup(name->children->content); + param = malloc(sizeof(sdlParam)); + param->order = 0; - element = get_attribute(part->properties, "element"); - if(element) - param->encode = get_encoder_from_prefix(tmpsdl, part, element->children->content); + 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); + + element = get_attribute(part->properties, "element"); + if(element) + param->encode = get_encoder_from_prefix(tmpsdl, part, element->children->content); + + type = get_attribute(part->properties, "type"); + if(type) + param->encode = get_encoder_from_prefix(tmpsdl, part, type->children->content); + + zend_hash_next_index_insert(function->responseParameters, ¶m, sizeof(sdlParamPtr), NULL); + } + ENDFOREACH(trav3); + } - type = get_attribute(part->properties, "type"); - if(type) - param->encode = get_encoder_from_prefix(tmpsdl, part, type->children->content); + fault = get_node(operation->children, "fault"); + if(!fault) + { + } - zend_hash_next_index_insert(function->responseParameters, ¶m, sizeof(sdlParamPtr), NULL); + if(!tmpbinding->functions) + { + tmpbinding->functions = malloc(sizeof(HashTable)); + zend_hash_init(tmpbinding->functions, 0, NULL, delete_function, 1); } - ENDFOREACH(trav3); + + zend_hash_add(tmpbinding->functions, php_strtolower(function->functionName, strlen(function->functionName)), strlen(function->functionName), &function, sizeof(sdlFunctionPtr), NULL); } + ENDFOREACH(trav2); - fault = get_node(operation->children, "fault"); - if(fault != NULL) + if(!tmpsdl->bindings) { + tmpsdl->bindings = malloc(sizeof(HashTable)); + zend_hash_init(tmpsdl->bindings, 0, NULL, delete_binding, 1); } - zend_hash_add(tmpsdl->functions, php_strtolower(function->functionName, strlen(function->functionName)), strlen(function->functionName), &function, sizeof(sdlFunctionPtr), NULL); + zend_hash_add(tmpsdl->bindings, tmpbinding->name, strlen(tmpbinding->name), &tmpbinding, sizeof(sdlBindingPtr), NULL); } - ENDFOREACH(trav2); + ENDFOREACH(trav); + } - ENDFOREACH(trav); + else + php_error(E_ERROR, "Error parsing wsdl (\"Couldn't bind to service\")"); return tmpsdl; } diff --git a/ext/soap/php_sdl.h b/ext/soap/php_sdl.h index 66a2520bfb..24e2be45a6 100644 --- a/ext/soap/php_sdl.h +++ b/ext/soap/php_sdl.h @@ -5,17 +5,67 @@ #define XSD_WHITESPACE_PRESERVE 1 #define XSD_WHITESPACE_REPLACE 1 +#define BINDING_SOAP 1 +#define BINDING_HTTP 2 + +#define SOAP_RPC 1 +#define SOAP_DOCUMENT 2 + +#define SOAP_ENCODED 1 +#define SOAP_LITERAL 2 + struct _sdl { - xmlDocPtr doc; - HashTable *functions; //array of SoapFunctionsPtr + xmlDocPtr doc; //pointer to the parsed xml file HashTable *types; //array of sdlTypesPtr HashTable *encoders; //array of encodePtr - char *location; + HashTable *bindings; //array of sdlBindings (key'd by name) char *target_ns; char *source; }; +struct _sdlBinding +{ + char *name; + HashTable *functions; + char *location; + int bindingType; + void *bindingAttributes; +}; + +//Soap Binding Specfic stuff +struct _sdlSoapBinding +{ + char *transport; + int style; +}; + +struct _sdlSoapBindingFunctionBody +{ + char *ns; + int use; + char *parts; //not implemented yet + char *encodingStyle; //not implemented yet +}; + +struct _sdlSoapBindingFunction +{ + char *soapAction; + int style; + + sdlSoapBindingFunctionBody input; + sdlSoapBindingFunctionBody output; + sdlSoapBindingFunctionBody falut; +}; + +//HTTP Binding Specfic stuff +/*********** not implemented yet ************ +struct _sdlHttpBinding +{ + int holder; +}; +*********************************************/ + struct _sdlRestrictionInt { int value; @@ -68,13 +118,13 @@ struct _sdlParam struct _sdlFunction { - int enabled; char *functionName; char *requestName; char *responseName; HashTable *requestParameters; //array of sdlParamPtr HashTable *responseParameters; //array of sdlParamPtr (this should only be one) - char *soapAction; + int bindingType; + void *bindingAttributes; }; struct _sdlAttribute @@ -87,11 +137,11 @@ struct _sdlAttribute char *ref; char *type; char *use; - HashTable *extraAttributes; + HashTable *extraAttributes; //array of xmlNodePtr }; sdlPtr get_sdl(char *uri); -sdlPtr load_wsdl(char *struri); +sdlPtr load_wsdl(char *struri, sdlPtr parent); int load_sdl(char *struri, int force_load); int load_ms_sdl(char *struri, int force_load); @@ -101,12 +151,16 @@ encodePtr get_encoder_ex(sdlPtr sdl, char *nscat); encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, char *ns, char *type); encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, char *ns, char *type); -xmlNodePtr sdl_guess_convert_xml(encodeType enc, zval* data); +sdlBindingPtr get_binding_from_type(sdlPtr sdl, int type); +sdlBindingPtr get_binding_from_name(sdlPtr sdl, char *name, char *ns); + +xmlNodePtr sdl_guess_convert_xml(encodeType enc, zval* data, int style); -xmlNodePtr sdl_to_xml_array(sdlTypePtr type, zval *data); -xmlNodePtr sdl_to_xml_object(sdlTypePtr type, zval *data); +xmlNodePtr sdl_to_xml_array(sdlTypePtr type, zval *data, int style); +xmlNodePtr sdl_to_xml_object(sdlTypePtr type, zval *data, int style); void delete_type(void *type); void delete_attribute(void *attribute); #endif + diff --git a/ext/soap/php_soap.dsp b/ext/soap/php_soap.dsp index 7ee12777e1..a80142d6c3 100644 --- a/ext/soap/php_soap.dsp +++ b/ext/soap/php_soap.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PHP_SOAP_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\php4" /I "..\..\..\php4\Zend" /I "..\..\..\php4\TSRM" /I "..\..\..\php4\main" /I "..\..\..\libxml2-2.4.12\include" /I "..\..\bind" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PHP_SOAP_EXPORTSWS" /D "PHP_SOAP_EXPORTS" /D "ZEND_WIN32" /D "PHP_WIN32" /D "ZTS" /D ZEND_DEBUG=0 /D "COMPILE_DL_SOAP" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /I "..\..\..\libxml2-2.4.12\include" /I "..\..\bind" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PHP_SOAP_EXPORTSWS" /D "PHP_SOAP_EXPORTS" /D "ZEND_WIN32" /D "PHP_WIN32" /D "ZTS" /D ZEND_DEBUG=0 /D "COMPILE_DL_SOAP" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" @@ -53,7 +53,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib libxml2.lib wsock32.lib resolv.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS\php_soap.dll" /libpath:"..\..\..\php4\Release_TS" /libpath:"..\..\..\libxml2-2.4.12\lib" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib libxml2.lib wsock32.lib resolv.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS\php_soap.dll" /libpath:"..\..\\" /libpath:"..\..\..\libxml2-2.4.12\lib" /libpath:"..\..\Release_TS" !ELSEIF "$(CFG)" == "php_soap - Win32 Debug" @@ -69,7 +69,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PHP_SOAP_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\php4" /I "..\..\..\php4\Zend" /I "..\..\..\php4\TSRM" /I "..\..\..\php4\main" /I "..\..\..\libxml2-2.4.12\include" /I "..\..\..\bind" /D "WS" /D "_MBCS" /D "_USRDLL" /D "PHP_SOAP_EXPORTS" /D "ZEND_WIN32" /D "PHP_WIN32" /D "ZTS" /D ZEND_DEBUG=1 /D "COMPILE_DL_SOAP" /FR"Release_TS/" /Fp"Release_TS/gd.pch" /YX /Fo"Release_TS/" /Fd"Release_TS/" /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /I "..\..\..\libxml2-2.4.12\include" /I "..\..\bind" /D "WS" /D "_MBCS" /D "_USRDLL" /D "PHP_SOAP_EXPORTS" /D "ZEND_WIN32" /D "PHP_WIN32" /D "ZTS" /D ZEND_DEBUG=1 /D "COMPILE_DL_SOAP" /FR"Release_TS/" /Fp"Release_TS/gd.pch" /YX /Fo"Release_TS/" /Fd"Release_TS/" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" @@ -79,7 +79,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts_debug.lib libxml2.lib wsock32.lib resolv.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS\php_soap.dll" /implib:"Release_TS/php_gd.lib" /pdbtype:sept /libpath:"..\..\..\php4\Debug_TS" /libpath:"..\..\..\libxml2-2.4.12\lib" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts_debug.lib libxml2.lib wsock32.lib resolv.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS\php_soap.dll" /implib:"Release_TS/php_gd.lib" /pdbtype:sept /libpath:"..\..\\" /libpath:"..\..\..\libxml2-2.4.12\lib" /libpath:"..\..\Debug_TS" # SUBTRACT LINK32 /pdb:none /incremental:no !ENDIF @@ -101,10 +101,6 @@ SOURCE=.\php_http.c # End Source File # Begin Source File -SOURCE=.\php_packet_soap.c -# End Source File -# Begin Source File - SOURCE=.\php_schema.c # End Source File # Begin Source File @@ -133,10 +129,6 @@ SOURCE=.\php_http.h # End Source File # Begin Source File -SOURCE=.\php_packet_soap.h -# End Source File -# Begin Source File - SOURCE=.\php_schema.h # End Source File # Begin Source File diff --git a/ext/soap/php_soap.h b/ext/soap/php_soap.h index 681e5b0ca0..301a594a3a 100644 --- a/ext/soap/php_soap.h +++ b/ext/soap/php_soap.h @@ -22,8 +22,6 @@ # define PHP_STREAMS #endif -#define SOAP_DEBUG 1 - #ifdef PHP_WIN32 # ifdef PHP_STREAMS # define SOAP_STREAM php_stream * @@ -53,6 +51,10 @@ typedef struct _sdlType sdlType, *sdlTypePtr; typedef struct _sdlParam sdlParam, *sdlParamPtr; typedef struct _sdlFunction sdlFunction, *sdlFunctionPtr; typedef struct _sdlAttribute sdlAttribute, *sdlAttributePtr; +typedef struct _sdlBinding sdlBinding, *sdlBindingPtr; +typedef struct _sdlSoapBinding sdlSoapBinding, *sdlSoapBindingPtr; +typedef struct _sdlSoapBindingFunction sdlSoapBindingFunction, *sdlSoapBindingFunctionPtr; +typedef struct _sdlSoapBindingFunctionBody sdlSoapBindingFunctionBody, *sdlSoapBindingFunctionBodyPtr; typedef struct _soapMapping soapMapping, *soapMappingPtr; typedef struct _soapService soapService, *soapServicePtr; @@ -69,6 +71,24 @@ extern int le_http_socket; extern int le_url; extern int le_service; + +struct _soapHeaderHandler +{ + char *ns; + int type; + + struct _function_handler + { + char *functionName; + char *type; + } function_handler; + + struct _class_handler + { + zend_class_entry *ce; + } class_handler; +}; + struct _soapMapping { char *ns; @@ -185,16 +205,20 @@ PHP_FUNCTION(map); //Client Functions PHP_FUNCTION(soapobject); +PHP_FUNCTION(__use); +PHP_FUNCTION(__style); PHP_FUNCTION(__isfault); PHP_FUNCTION(__getfault); PHP_FUNCTION(__call); PHP_FUNCTION(__parse); -#ifdef PHP_DEBUG +PHP_FUNCTION(__generate); +PHP_FUNCTION(__trace); PHP_FUNCTION(__getfunctions); PHP_FUNCTION(__gettypes); PHP_FUNCTION(__getlastresponse); PHP_FUNCTION(__getlastrequest); -#endif +PHP_FUNCTION(__headerclass); +PHP_FUNCTION(__headerfunction); //SoapVar Functions PHP_FUNCTION(soapvar); @@ -224,8 +248,11 @@ void set_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault void add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail); sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, int); -sdlFunctionPtr get_function(sdlPtr sdl, char *function_name); +sdlFunctionPtr get_function(sdlBindingPtr sdl, char *function_name); + void delete_sdl(void *handle); +void delete_binding(void *binding); +void delete_sdl_soap_binding_function_body(sdlSoapBindingFunctionBody body); void delete_function(void *function); void delete_paramater(void *paramater); void delete_service(void *service); @@ -240,9 +267,9 @@ void soap_destructor(void *jobject); void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *function_name, int *num_params, zval **parameters[]); xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_name,char *uri,zval *ret); -xmlDocPtr seralize_function_call(sdlFunctionPtr function, char *urn, char *function_name, zval **arguments, int arg_count); -xmlNodePtr seralize_parameter(sdlParamPtr param,zval *param_val,int index,char *name); -xmlNodePtr seralize_zval(zval *val, sdlParamPtr param, char *paramName); +xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function, char *function_name, char *uri, zval **arguments, int arg_count); +xmlNodePtr seralize_parameter(sdlParamPtr param,zval *param_val,int index,char *name, int style); +xmlNodePtr seralize_zval(zval *val, sdlParamPtr param, char *paramName, int style); zval *desearlize_zval(sdlPtr sdl, xmlNodePtr data, sdlParamPtr param); void soap_error_handler(int error_num, const char *error_filename, const uint error_lineno, const char *format, va_list args); @@ -305,6 +332,20 @@ int my_call_user_function(HashTable *function_table, zval **object_pp, zval *fun if(ZEND_NUM_ARGS() != 1 || getParameters(ht, 3, &p, &p1, &p2) == FAILURE) \ WRONG_PARAM_COUNT; +#define FETCH_THIS_PORT(ss) \ + { \ + zval *__thisObj; zval *__port; sdlBindingPtr *__tmp; \ + GET_THIS_OBJECT(__thisObj) \ + if(FIND_PORT_PROPERTY(__thisObj, __port) == FAILURE) { \ + ss = NULL; \ + php_error(E_ERROR, "Error could find current port"); \ + } \ + __tmp = (sdlBindingPtr*)Z_LVAL_P(__port); \ + ss = *__tmp; \ + } + +#define FIND_PORT_PROPERTY(ss,tmp) zend_hash_find(ss->value.obj.properties, "port", sizeof("port"), (void **)&tmp) + #define FETCH_THIS_SDL(ss) \ { \ zval *__thisObj,**__tmp; \ diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c index 707d073984..e3505e2890 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -106,7 +106,7 @@ xmlNodePtr get_node_recurisve_ex(xmlNodePtr node, char *name, char *ns) xmlNodePtr get_node_with_attribute_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns) { - xmlNodePtr trav = node, cur; + xmlNodePtr trav = node, cur = NULL; xmlAttrPtr attr; if(node == NULL) return NULL; diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 074c5846d3..dd0fd6b6ea 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -50,15 +50,18 @@ static zend_function_entry soap_client_functions[] = { PHP_FE(soapobject, NULL) PHP_FE(__isfault, NULL) PHP_FE(__getfault, NULL) + PHP_FE(__use, NULL) + PHP_FE(__style, NULL) PHP_FE(__call, NULL) - PHP_FE(__parse, NULL) -#ifdef SOAP_DEBUG + PHP_FE(__generate, NULL) + PHP_FE(__trace, NULL) + PHP_FE(__headerclass, NULL) + PHP_FE(__headerfunction, NULL) PHP_FE(__getlastrequest, NULL) PHP_FE(__getlastresponse, NULL) PHP_FE(__getfunctions, NULL) PHP_FE(__gettypes, NULL) -#endif {NULL, NULL, NULL} }; @@ -211,6 +214,12 @@ PHP_MINIT_FUNCTION(soap) REGISTER_LONG_CONSTANT("SOAP_PERSISTENCE_REQUEST", SOAP_PERSISTENCE_REQUEST, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOAP_FUNCTIONS_ALL", SOAP_FUNCTIONS_ALL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SOAP_ENCODED", SOAP_ENCODED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SOAP_LITERAL", SOAP_LITERAL, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("SOAP_RPC", SOAP_RPC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SOAP_DOCUMENT", SOAP_DOCUMENT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XSD_1999_TIMEINSTANT", XSD_1999_TIMEINSTANT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("UNKNOWN_TYPE", UNKNOWN_TYPE, CONST_CS | CONST_PERSISTENT); @@ -369,7 +378,7 @@ PHP_FUNCTION(soap_encode_to_xml) php_error(E_ERROR, "wrong number of parameters to soap_encode_to_xml"); enc = get_conversion(Z_TYPE_P(pzval)); - ret = php_domobject_new(seralize_zval(pzval, NULL, name), &found, NULL TSRMLS_CC); + ret = php_domobject_new(seralize_zval(pzval, NULL, name, SOAP_ENCODED), &found, NULL TSRMLS_CC); *return_value = *ret; zval_copy_ctor(return_value); zval_ptr_dtor(&ret); @@ -416,9 +425,8 @@ PHP_FUNCTION(soapfault) int fault_string_len, fault_code_len, fault_actor_len; zval *thisObj, *details = NULL; - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|zs", - &fault_code, &fault_code_len, &fault_string, &fault_string_len, - &details, &fault_actor, &fault_actor_len) == FAILURE) + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|zs", &fault_string, &fault_string_len, + &fault_code, &fault_code_len, &details, &fault_actor, &fault_actor_len) == FAILURE) php_error(E_ERROR, "Invalid arguments to SoapFault constructor"); GET_THIS_OBJECT(thisObj); @@ -432,11 +440,11 @@ PHP_FUNCTION(soapfault) PHP_FUNCTION(soapvar) { zval *data, *thisObj, *type; - char *stype = NULL, *ns = NULL; - int stype_len, ns_len; + char *stype = NULL, *ns = NULL, *name = NULL, *namens = NULL; + int stype_len, ns_len, name_len, namens_len; GET_THIS_OBJECT(thisObj); - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!z|ss", &data, &type, &stype, &stype_len, &ns, &ns_len) == FAILURE) + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!z|ssss", &data, &type, &stype, &stype_len, &ns, &ns_len, &name, &name_len, &namens, &namens_len) == FAILURE) php_error(E_ERROR, "Invalid arguments to SoapVal constructor"); zval_add_ref(&data); @@ -452,10 +460,14 @@ PHP_FUNCTION(soapvar) add_property_zval(thisObj, "enc_value", data); - if(stype) + if(stype && strlen(stype) > 0) add_property_stringl(thisObj, "enc_stype", stype, stype_len, 1); - if(ns) + if(ns && strlen(ns) > 0) add_property_stringl(thisObj, "enc_ns", ns, ns_len, 1); + if(name && strlen(name) > 0) + add_property_stringl(thisObj, "enc_name", name, name_len, 1); + if(namens && strlen(namens) > 0) + add_property_stringl(thisObj, "enc_namens", namens, namens_len, 1); } //SoapServer functions @@ -1005,7 +1017,7 @@ PHP_FUNCTION(handle) if(call_status == SUCCESS) { sdlFunctionPtr function; - function = get_function(service->sdl, Z_STRVAL(function_name)); + function = get_function(get_binding_from_type(service->sdl, BINDING_SOAP), Z_STRVAL(function_name)); SOAP_GLOBAL(overrides) = service->mapping; doc_return = seralize_response_call(function, response_name, service->uri, &retval); SOAP_GLOBAL(overrides) = NULL; @@ -1137,13 +1149,133 @@ PHP_FUNCTION(soapobject) sdl = get_sdl(location); ret = zend_list_insert(sdl, le_sdl); + add_property_resource(thisObj, "sdl", ret); + add_property_resource(thisObj, "port", (long)get_binding_from_type(sdl, BINDING_SOAP)); zend_list_addref(ret); } } } +PHP_FUNCTION(__headerclass) +{ + char *classname, *ns; + int classname_len, ns_len; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &classname, &classname_len, &ns, &ns_len) == FAILURE) + php_error(E_ERROR, "Invalid arguments to SoapObject->__headerclass"); +} + +PHP_FUNCTION(__headerfunction) +{ + char *functionname, *headername, *ns; + int functionname_len, *headername_len, ns_len; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", &functionname, &functionname_len, &headername, + &headername_len, &ns, &ns_len) == FAILURE) + php_error(E_ERROR, "Invalid arguments to SoapObject->__headerfunction"); +} + +PHP_FUNCTION(__use) +{ + int use; + zval *thisObj; + + GET_THIS_OBJECT(thisObj); + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &use) == FAILURE) + php_error(E_ERROR, "Invalid arguments to SoapObject->__use"); + + if(use == SOAP_DOCUMENT || use == SOAP_LITERAL) + { + add_property_long(thisObj, "use", use); + RETURN_TRUE; + } + RETURN_FALSE; +} + +PHP_FUNCTION(__style) +{ + int style; + zval *thisObj; + + GET_THIS_OBJECT(thisObj); + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &style)) + php_error(E_ERROR, "Invalid arguments to SoapObject->__style"); + + if(style == SOAP_RPC || style == SOAP_DOCUMENT) + { + add_property_long(thisObj, "style", style); + RETURN_TRUE; + } + RETURN_FALSE; +} + +PHP_FUNCTION(__trace) +{ + int level; + zval *thisObj; + + GET_THIS_OBJECT(thisObj); + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &level)) + php_error(E_ERROR, "Invalid arguments to SoapObject->__trace"); + + add_property_long(thisObj, "trace", level); + RETURN_TRUE; +} + +PHP_FUNCTION(__generate) +{ + char *function, *soap_action, *uri; + int function_len, soap_action_len, uri_len, i = 0; + zval *args; + zval **real_args; + zval **param; + xmlDocPtr request = NULL; + int arg_count; + xmlChar *buf; + int size; + sdlPtr sdl; + + FETCH_THIS_SDL(sdl); + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|ss", + &function, &function_len, &args, &soap_action, &soap_action_len, &uri, &uri_len) == FAILURE) + php_error(E_ERROR, "Invalid arguments to SoapObject->__call"); + + arg_count = zend_hash_num_elements(Z_ARRVAL_P(args)); + + real_args = emalloc(sizeof(zval *) * arg_count); + for(zend_hash_internal_pointer_reset(Z_ARRVAL_P(args)); + zend_hash_get_current_data(Z_ARRVAL_P(args), (void **) ¶m) == SUCCESS; + zend_hash_move_forward(Z_ARRVAL_P(args))) + { + zval_add_ref(param); + real_args[i++] = *param; + } + + + if(sdl) + { + sdlBindingPtr binding; + sdlFunctionPtr sdlFunction; + FETCH_THIS_PORT(binding); + + php_strtolower(function, function_len); + sdlFunction = get_function(binding, function); + request = seralize_function_call(this_ptr, sdlFunction, NULL, uri, real_args, arg_count); + } + else + { + request = seralize_function_call(this_ptr, NULL, function, uri, real_args, arg_count); + } + + xmlDocDumpMemory(request, &buf, &size); + ZVAL_STRINGL(return_value, buf, size, 1); + xmlFree(buf); +} PHP_FUNCTION(__parse) { @@ -1161,7 +1293,10 @@ PHP_FUNCTION(__parse) if(sdl != NULL) { - fn = get_function(sdl, function); + sdlBindingPtr binding; + + FETCH_THIS_PORT(binding); + fn = get_function(binding, function); if(fn != NULL) parse_packet_soap(getThis(), message, message_len, fn, NULL, &ret_params, &num_params); } @@ -1180,18 +1315,16 @@ PHP_FUNCTION(__parse) PHP_FUNCTION(__call) { - char *function=NULL, *soap_action=NULL, *uri=NULL; - int function_len=0, soap_action_len=0, uri_len=0, i = 0; - zval *args=NULL; - zval **real_args=NULL; - zval **param=NULL; + char *function, *soap_action, *uri; + int function_len, soap_action_len, uri_len, i = 0; + zval *args; + zval **real_args; + zval **param; xmlDocPtr request = NULL; - int num_params=0, arg_count=0; - zval **ret_params=NULL; - - char *buffer=NULL; - - int len=0; + int num_params, arg_count; + zval **ret_params; + char *buffer; + int len; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|ss", &function, &function_len, &args, &soap_action, &soap_action_len, &uri, &uri_len) == FAILURE) @@ -1208,21 +1341,17 @@ PHP_FUNCTION(__call) real_args[i++] = *param; } - request = seralize_function_call(NULL, uri, function, real_args, arg_count); + request = seralize_function_call(this_ptr, NULL, function, uri, real_args, arg_count); send_http_soap_request(getThis(), request, function, soap_action); xmlFreeDoc(request); get_http_soap_response(getThis(), &buffer, &len); - parse_packet_soap(getThis(), buffer, len, NULL, function, &ret_params, &num_params); - efree(buffer); - if(num_params > 0) { *return_value = *ret_params[0]; - zval_add_ref(&return_value); efree(ret_params); } @@ -1258,7 +1387,6 @@ PHP_FUNCTION(__getfault) RETURN_NULL(); } -#ifdef SOAP_DEBUG PHP_FUNCTION(__getfunctions) { sdlPtr sdl; @@ -1272,14 +1400,17 @@ PHP_FUNCTION(__getfunctions) { smart_str buf = {0}; sdlFunctionPtr *function; + sdlBindingPtr binding; + + FETCH_THIS_PORT(binding); array_init(return_value); - zend_hash_internal_pointer_reset(sdl->functions); - while(zend_hash_get_current_data(sdl->functions, (void **)&function) != FAILURE) + zend_hash_internal_pointer_reset(binding->functions); + while(zend_hash_get_current_data(binding->functions, (void **)&function) != FAILURE) { function_to_string((*function), &buf); add_next_index_stringl(return_value, buf.c, buf.len, 1); - zend_hash_move_forward(sdl->functions); + zend_hash_move_forward(binding->functions); smart_str_free(&buf); } } @@ -1345,8 +1476,6 @@ PHP_FUNCTION(__getlastresponse) } RETURN_NULL(); } -#endif - void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference) { @@ -1380,29 +1509,36 @@ void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_refe if(sdl != NULL) { - fn = get_function(sdl, function); + sdlBindingPtr binding; + + FETCH_THIS_PORT(binding); + fn = get_function(binding, function); if(fn != NULL) { int num_params; zval **ret_params; - char *buffer; - + char *ns; int len; - request = seralize_function_call(fn, sdl->target_ns, NULL, arguments, arg_count); - - send_http_soap_request(getThis(), request, fn->soapAction, fn->soapAction); + if(binding->bindingType == BINDING_SOAP) + { + sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes; + request = seralize_function_call(this_ptr, fn, NULL, fnb->input.ns, arguments, arg_count); + send_http_soap_request(getThis(), request, fn->functionName, fnb->soapAction); + } + else + { + request = seralize_function_call(this_ptr, fn, NULL, sdl->target_ns, arguments, arg_count); + send_http_soap_request(getThis(), request, fn->functionName, NULL); + } xmlFreeDoc(request); get_http_soap_response(getThis(), &buffer, &len); - parse_packet_soap(getThis(), buffer, len, fn, NULL, &ret_params, &num_params); - efree(buffer); - if(num_params > 0) { *return_value = *ret_params[0]; @@ -1424,14 +1560,12 @@ void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_refe zval **uri; smart_str *action; char *buffer; - int len; - if(zend_hash_find(Z_OBJPROP_P(thisObj), "uri", sizeof("uri"), (void *)&uri) == FAILURE) php_error(E_ERROR, "Error finding uri in soap_call_function_handler"); - request = seralize_function_call(NULL, Z_STRVAL_PP(uri), function, arguments, arg_count); + request = seralize_function_call(this_ptr, NULL, function, Z_STRVAL_PP(uri), arguments, arg_count); action = build_soap_action(thisObj, function); send_http_soap_request(getThis(), request, function, action->c); @@ -1439,12 +1573,9 @@ void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_refe xmlFreeDoc(request); get_http_soap_response(getThis(), &buffer, &len); - parse_packet_soap(getThis(), buffer, len, NULL, function, &ret_params, &num_params); - efree(buffer); - if(num_params > 0) { *return_value = *ret_params[0]; @@ -1470,7 +1601,7 @@ void add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault { zval *fault; MAKE_STD_ZVAL(fault); - set_soap_fault(fault, fault_code, fault_string, fault_actor, fault_detail); + set_soap_fault(fault, fault_string, fault_code, fault_actor, fault_detail); add_property_zval(obj, "__soap_fault", fault); } @@ -1497,8 +1628,6 @@ void set_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault } } - - void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *function_name, int *num_params, zval ***parameters) { xmlNodePtr trav,trav2,trav3,trav4,env,body; @@ -1519,15 +1648,16 @@ void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *function_name { zval tmp_function_name, **tmp_parameters; sdlFunctionPtr function; + sdlBindingPtr binding = get_binding_from_type(sdl, BINDING_SOAP); INIT_ZVAL(tmp_function_name); ZVAL_STRING(&tmp_function_name, (char *)trav3->name, 1); (*function_name) = tmp_function_name; - function = get_function(sdl, php_strtolower((char *)trav3->name, strlen(trav3->name))); + function = get_function(binding, php_strtolower((char *)trav3->name, strlen(trav3->name))); if(sdl != NULL && function == NULL) - php_error(E_ERROR, "Error function \"%s\" doesn't exists for this service \"%s\"", trav3->name, sdl->location); + php_error(E_ERROR, "Error function \"%s\" doesn't exists for this service \"%s\"", trav3->name, binding->location); if(trav3->children) { @@ -1578,10 +1708,6 @@ void deseralize_function_call(sdlPtr sdl, xmlDocPtr request, zval *function_name ENDFOREACH(trav); } - - - - xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_name, char *uri, zval *ret) { xmlDoc *doc; @@ -1608,9 +1734,9 @@ xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_name, c body = xmlNewChild(envelope, ns, "Body", NULL); if(Z_TYPE_P(ret) == IS_OBJECT && - Z_OBJCE_P(ret)->refcount == soap_var_class_entry.refcount) + Z_OBJCE_P(ret)->refcount == soap_fault_class_entry.refcount) { - param = seralize_zval(ret, NULL, "SOAP-ENV:Fault"); + param = seralize_zval(ret, NULL, "SOAP-ENV:Fault", SOAP_ENCODED); xmlAddChild(body, param); } else @@ -1636,12 +1762,12 @@ xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_name, c if(zend_hash_find(Z_OBJPROP_P(ret), "param_name", sizeof("param_name"), (void **)&ret_name) == SUCCESS && zend_hash_find(Z_OBJPROP_P(ret), "param_data", sizeof("param_data"), (void **)&ret_data) == SUCCESS) - param = seralize_parameter(parameter, *ret_data, 0, Z_STRVAL_PP(ret_name)); + param = seralize_parameter(parameter, *ret_data, 0, Z_STRVAL_PP(ret_name), SOAP_ENCODED); else - param = seralize_parameter(parameter, ret, 0, "return"); + param = seralize_parameter(parameter, ret, 0, "return", SOAP_ENCODED); } else - param = seralize_parameter(parameter, ret, 0, "return"); + param = seralize_parameter(parameter, ret, 0, "return", SOAP_ENCODED); xmlAddChild(method,param); } @@ -1649,12 +1775,13 @@ xmlDocPtr seralize_response_call(sdlFunctionPtr function, char *function_name, c return doc; } -xmlDocPtr seralize_function_call(sdlFunctionPtr function, char *uri, char *function_name, zval **arguments, int arg_count) +xmlDocPtr seralize_function_call(zval *this_ptr, sdlFunctionPtr function, char *function_name, char *uri, zval **arguments, int arg_count) { xmlDoc *doc; - xmlNode *envelope,*body,*method; - xmlNs *ns; - int i; + xmlNode *envelope, *body, *method; + xmlNs *ns, *tmpns; + zval **zstyle, **zuse; + int i, style, use; smart_str *gen_ns; encode_reset_ns(); @@ -1668,18 +1795,43 @@ xmlDocPtr seralize_function_call(sdlFunctionPtr function, char *uri, char *funct xmlSetProp(envelope, "xmlns:SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"); xmlSetProp(envelope, "xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); xmlSetProp(envelope, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); - ns = xmlNewNs(envelope,"http://schemas.xmlsoap.org/soap/envelope/","SOAP-ENV"); + + ns = xmlNewNs(envelope, "http://schemas.xmlsoap.org/soap/envelope/", "SOAP-ENV"); body = xmlNewChild(envelope, ns, "Body", NULL); gen_ns = encode_new_ns(); - ns = xmlNewNs(envelope, uri, gen_ns->c); - if(function != NULL) - method = xmlNewChild(body, ns, function->requestName , NULL); + if(function) + { + if(function->bindingType == BINDING_SOAP) + { + sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes; + + ns = xmlNewNs(body, fnb->input.ns, gen_ns->c); + style = fnb->style; + use = fnb->input.use; + if(style == SOAP_RPC) + method = xmlNewChild(body, ns, function->requestName , NULL); + } + } else - method = xmlNewChild(body, ns, function_name , NULL); + { + if(zend_hash_find(Z_OBJPROP_P(this_ptr), "style", sizeof("style"), (void **)&zstyle) == SUCCESS) + style = Z_LVAL_PP(zstyle); + else + style = SOAP_RPC; + + if(style == SOAP_RPC) + { + ns = xmlNewNs(body, uri, gen_ns->c); + method = xmlNewChild(body, ns, function_name, NULL); + } - ns = xmlNewNs(method, uri, NULL); + if(zend_hash_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use"), (void **)&zuse) == SUCCESS) + use = Z_LVAL_PP(zuse); + else + use = SOAP_ENCODED; + } for(i = 0;i < arg_count;i++) { @@ -1694,28 +1846,44 @@ xmlDocPtr seralize_function_call(sdlFunctionPtr function, char *uri, char *funct if(zend_hash_find(Z_OBJPROP_P(arguments[i]), "param_name", sizeof("param_name"), (void **)&ret_name) == SUCCESS && zend_hash_find(Z_OBJPROP_P(arguments[i]), "param_data", sizeof("param_data"), (void **)&ret_data) == SUCCESS) - param = seralize_parameter(parameter, *ret_data, i, Z_STRVAL_PP(ret_name)); + param = seralize_parameter(parameter, *ret_data, i, Z_STRVAL_PP(ret_name), use); else - param = seralize_parameter(parameter, arguments[i], i, NULL); + param = seralize_parameter(parameter, arguments[i], i, NULL, use); } else - param = seralize_parameter(parameter, arguments[i], i, NULL); - xmlAddChild(method,param); + param = seralize_parameter(parameter, arguments[i], i, NULL, use); + + if(style == SOAP_RPC) + xmlAddChild(method, param); + else if(style == SOAP_DOCUMENT) + { + if(function && function->bindingType == BINDING_SOAP) + { + sdlParamPtr *sparam; + + if(zend_hash_index_find(function->requestParameters, 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); + } } + smart_str_free(gen_ns); return doc; } -xmlNodePtr seralize_parameter(sdlParamPtr param, zval *param_val, int index, char *name) +xmlNodePtr seralize_parameter(sdlParamPtr param, zval *param_val, int index, char *name, int style) { int type = 0; char *paramName; xmlNodePtr xmlParam; if(param != NULL && param->paramName != NULL) - { paramName = estrdup(param->paramName); - } else { if(name == NULL) @@ -1727,7 +1895,7 @@ xmlNodePtr seralize_parameter(sdlParamPtr param, zval *param_val, int index, cha paramName = estrdup(name); } - xmlParam = seralize_zval(param_val, param, paramName); + xmlParam = seralize_zval(param_val, param, paramName, style); efree(paramName); @@ -1747,7 +1915,7 @@ zval *desearlize_zval(sdlPtr sdl, xmlNodePtr data, sdlParamPtr param) return enc->to_zval(enc->details, data); } -xmlNodePtr seralize_zval(zval *val, sdlParamPtr param, char *paramName) +xmlNodePtr seralize_zval(zval *val, sdlParamPtr param, char *paramName, int style) { xmlNodePtr xmlParam; encodePtr enc; @@ -1758,8 +1926,9 @@ xmlNodePtr seralize_zval(zval *val, sdlParamPtr param, char *paramName) else enc = get_conversion(val->type); - xmlParam = master_to_xml(enc, val); - xmlNodeSetName(xmlParam, paramName); + xmlParam = master_to_xml(enc, val, style); + if(!strcmp(xmlParam->name, "BOGUS")) + xmlNodeSetName(xmlParam, paramName); return xmlParam; } @@ -1789,7 +1958,7 @@ sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, int return NULL; } -sdlFunctionPtr get_function(sdlPtr sdl, char *function_name) +sdlFunctionPtr get_function(sdlBindingPtr sdl, char *function_name) { sdlFunctionPtr *tmp; if(sdl != NULL) @@ -1880,14 +2049,11 @@ void delete_sdl(void *handle) { sdlPtr tmp = *((sdlPtr*)handle); - xmlFreeDoc(tmp->doc); if(tmp->source) free(tmp->source); if(tmp->target_ns) free(tmp->target_ns); - if(tmp->location) - free(tmp->location); if(tmp->encoders) { zend_hash_destroy(tmp->encoders); @@ -1898,10 +2064,10 @@ void delete_sdl(void *handle) zend_hash_destroy(tmp->types); free(tmp->types); } - if(tmp->functions) + if(tmp->bindings) { - zend_hash_destroy(tmp->functions); - free(tmp->functions); + zend_hash_destroy(tmp->bindings); + free(tmp->bindings); } free(tmp); } @@ -1950,6 +2116,28 @@ void delete_service(void *data) efree(service); } +void delete_binding(void *data) +{ + sdlBindingPtr binding = *((sdlBindingPtr*)data); + + if(binding->functions) + { + zend_hash_destroy(binding->functions); + free(binding->functions); + } + + if(binding->location) + free(binding->location); + if(binding->name) + free(binding->name); + + if(binding->bindingType == BINDING_SOAP) + { + sdlSoapBindingPtr soapBind = binding->bindingAttributes; + free(soapBind->transport); + } +} + void delete_function(void *data) { sdlFunctionPtr function = *((sdlFunctionPtr*)data); @@ -1960,8 +2148,6 @@ void delete_function(void *data) free(function->requestName); if(function->responseName) free(function->responseName); - if(function->soapAction) - free(function->soapAction); if(function->requestParameters) { @@ -1973,6 +2159,26 @@ void delete_function(void *data) zend_hash_destroy(function->responseParameters); free(function->responseParameters); } + + if(function->bindingType == BINDING_SOAP) + { + sdlSoapBindingFunctionPtr soapFunction = function->bindingAttributes; + if(soapFunction->soapAction) + free(soapFunction->soapAction); + delete_sdl_soap_binding_function_body(soapFunction->input); + delete_sdl_soap_binding_function_body(soapFunction->output); + delete_sdl_soap_binding_function_body(soapFunction->falut); + } +} + +void delete_sdl_soap_binding_function_body(sdlSoapBindingFunctionBody body) +{ + if(body.ns) + free(body.ns); + if(body.parts) + free(body.parts); + if(body.encodingStyle) + free(body.encodingStyle); } void delete_paramater(void *data) -- 2.40.0