summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2004-02-11 13:53:50 +0000
committerDmitry Stogov <dmitry@php.net>2004-02-11 13:53:50 +0000
commit6096b09159b181e938380cbe18e70b4297942209 (patch)
tree9c5b0f3a86c338fed539c5cfdbe3a9412130002f
parent75390796bed8ffe6e66ebd3e555cd25bdeab6571 (diff)
downloadphp-git-6096b09159b181e938380cbe18e70b4297942209.tar.gz
Now SoapClient uses excptions as default method for error reporting
-rw-r--r--ext/soap/interop/client_round2_interop.php34
-rw-r--r--ext/soap/php_encoding.c39
-rw-r--r--ext/soap/php_sdl.c71
-rw-r--r--ext/soap/php_soap.h2
-rw-r--r--ext/soap/soap.c272
-rw-r--r--ext/soap/tests/schema/test_schema.inc2
-rw-r--r--ext/soap/tests/server018.phpt33
7 files changed, 342 insertions, 111 deletions
diff --git a/ext/soap/interop/client_round2_interop.php b/ext/soap/interop/client_round2_interop.php
index b543d31643..7b19e7f0de 100644
--- a/ext/soap/interop/client_round2_interop.php
+++ b/ext/soap/interop/client_round2_interop.php
@@ -134,20 +134,23 @@ class Interop_Client
*/
function fetchEndpoints($test = NULL) {
// fetch from the interop server
- $soapclient = new SoapClient($this->interopServer);
-
- if ($test) {
- $this->_fetchEndpoints($soapclient, $test);
- } else {
- foreach ($this->tests as $test) {
+ try {
+ $soapclient = new SoapClient($this->interopServer);
+ if ($test) {
$this->_fetchEndpoints($soapclient, $test);
+ } else {
+ foreach ($this->tests as $test) {
+ $this->_fetchEndpoints($soapclient, $test);
+ }
+ $test = 'base';
}
- $test = 'base';
+ } catch (SoapFault $fault) {
+ echo "<pre>$fault</pre>";
+ return NULL;
}
-
// retreive all endpoints now
$this->currentTest = $test;
- $x = $this->_getEndpoints();
+ $x = $this->_getEndpoints($test);
return $x;
}
@@ -358,13 +361,17 @@ class Interop_Client
if ($this->useWSDL) {
if (array_key_exists('wsdlURL',$endpoint_info)) {
if (!array_key_exists('client',$endpoint_info)) {
- $endpoint_info['client'] = new SoapClient($endpoint_info['wsdlURL'], array("trace"=>1));
+ try {
+ $endpoint_info['client'] = new SoapClient($endpoint_info['wsdlURL'], array("trace"=>1));
+ } catch (SoapFault $ex) {
+ $endpoint_info['client']->wsdl->fault = $ex;
+ }
}
$soap =& $endpoint_info['client'];
# XXX how do we determine a failure on retreiving/parsing wsdl?
if ($soap->wsdl->fault) {
- $fault = $soap->wsdl->fault->getFault();
+ $fault = $soap->wsdl->fault;
$soap_test->setResult(0,'WSDL',
$fault->faultstring."\n\n".$fault->detail,
$fault->faultstring,
@@ -407,6 +414,7 @@ class Interop_Client
// XXX no way to set encoding
// this lets us set UTF-8, US-ASCII or other
//$soap->setEncoding($soap_test->encoding);
+try {
if ($this->useWSDL && !$soap_test->headers && !$soap_test->headers_expect) {
$args = '';
foreach ($soap_test->method_params as $pname => $param) {
@@ -421,6 +429,10 @@ class Interop_Client
$return = $soap->__call($soap_test->method_name,$soap_test->method_params,array('soapaction'=>$soapaction,'uri'=>$namespace));
}
}
+} catch (SoapFault $ex) {
+ $return = $ex;
+}
+//var_dump($return);
if(!is_soap_fault($return)){
diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c
index 9686048dbb..08acbfbfd6 100644
--- a/ext/soap/php_encoding.c
+++ b/ext/soap/php_encoding.c
@@ -2363,26 +2363,33 @@ void encode_reset_ns()
encodePtr get_conversion_ex(HashTable *encoding, int encode)
{
- encodePtr *enc;
+ encodePtr *enc = NULL;
TSRMLS_FETCH();
if (zend_hash_index_find(encoding, encode, (void **)&enc) == FAILURE) {
- php_error(E_ERROR, "SOAP-ERROR: Encoding: Cannot find encoding");
- }
-
- if (SOAP_GLOBAL(overrides)) {
- smart_str nscat = {0};
-
- smart_str_appendl(&nscat, (*enc)->details.ns, strlen((*enc)->details.ns));
- smart_str_appendc(&nscat, ':');
- smart_str_appendl(&nscat, (*enc)->details.type_str, strlen((*enc)->details.type_str));
- smart_str_0(&nscat);
-
- zend_hash_find(SOAP_GLOBAL(overrides), nscat.c, nscat.len + 1, (void **)&enc);
- smart_str_free(&nscat);
+ if (SOAP_GLOBAL(overrides)) {
+ smart_str nscat = {0};
+
+ smart_str_appendl(&nscat, (*enc)->details.ns, strlen((*enc)->details.ns));
+ smart_str_appendc(&nscat, ':');
+ smart_str_appendl(&nscat, (*enc)->details.type_str, strlen((*enc)->details.type_str));
+ smart_str_0(&nscat);
+
+ if (zend_hash_find(SOAP_GLOBAL(overrides), nscat.c, nscat.len + 1, (void **)&enc) == FAILURE) {
+ smart_str_free(&nscat);
+ php_error(E_ERROR, "SOAP-ERROR: Encoding: Cannot find encoding");
+ return NULL;
+ } else {
+ smart_str_free(&nscat);
+ return *enc;
+ }
+ } else {
+ php_error(E_ERROR, "SOAP-ERROR: Encoding: Cannot find encoding");
+ return NULL;
+ }
+ } else {
+ return *enc;
}
-
- return *enc;
}
encodePtr get_conversion_from_href_type_ex(HashTable *encoding, const char *type, int len)
diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
index 586389f66e..48641d41eb 100644
--- a/ext/soap/php_sdl.c
+++ b/ext/soap/php_sdl.c
@@ -1814,59 +1814,60 @@ static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr s
sdlPtr get_sdl(char *uri TSRMLS_DC)
{
+ sdlPtr sdl = NULL;
+ char* old_error_code = SOAP_GLOBAL(error_code);
#ifdef SDL_CACHE
- sdlPtr tmp, *hndl;
- TSRMLS_FETCH();
+ sdlPtr *hndl;
- tmp = NULL;
- hndl = NULL;
+ SOAP_GLOBAL(error_code) = "WSDL";
if (zend_hash_find(SOAP_GLOBAL(sdls), uri, strlen(uri), (void **)&hndl) == FAILURE) {
- tmp = load_wsdl(uri);
- zend_hash_add(SOAP_GLOBAL(sdls), uri, strlen(uri), &tmp, sizeof(sdlPtr), NULL);
+ sdl = load_wsdl(uri);
+ zend_hash_add(SOAP_GLOBAL(sdls), uri, strlen(uri), &sdl, sizeof(sdlPtr), NULL);
} else {
- tmp = *hndl;
+ sdl = *hndl;
}
-
- return tmp;
#else
+ SOAP_GLOBAL(error_code) = "WSDL";
if (SOAP_GLOBAL(cache_enabled)) {
char fn[MAXPATHLEN];
- char* key;
- sdlPtr sdl;
- time_t t = time(0);
-
- char md5str[33];
- PHP_MD5_CTX context;
- unsigned char digest[16];
- int len = strlen(SOAP_GLOBAL(cache_dir));
if (strchr(uri,':') != NULL || IS_ABSOLUTE_PATH(uri,strlen(uri))) {
strcpy(fn, uri);
} else if (VCWD_REALPATH(uri, fn) == NULL) {
- return load_wsdl(uri);
+ sdl = load_wsdl(uri);
}
- md5str[0] = '\0';
- PHP_MD5Init(&context);
- PHP_MD5Update(&context, fn, strlen(fn));
- PHP_MD5Final(digest, &context);
- make_digest(md5str, digest);
- key = do_alloca(len+sizeof("/wsdl-")-1+sizeof(md5str));
- memcpy(key,SOAP_GLOBAL(cache_dir),len);
- memcpy(key+len,"/wsdl-",sizeof("/wsdl-")-1);
- memcpy(key+len+sizeof("/wsdl-")-1,md5str,sizeof(md5str));
-
- if ((sdl = get_sdl_from_cache(key, fn, t-SOAP_GLOBAL(cache_ttl))) == NULL) {
- sdl = load_wsdl(fn);
- if (sdl != NULL) {
- add_sdl_to_cache(key, fn, t, sdl);
+ if (sdl == NULL) {
+ char* key;
+ time_t t = time(0);
+ char md5str[33];
+ PHP_MD5_CTX context;
+ unsigned char digest[16];
+ int len = strlen(SOAP_GLOBAL(cache_dir));
+
+ md5str[0] = '\0';
+ PHP_MD5Init(&context);
+ PHP_MD5Update(&context, fn, strlen(fn));
+ PHP_MD5Final(digest, &context);
+ make_digest(md5str, digest);
+ key = do_alloca(len+sizeof("/wsdl-")-1+sizeof(md5str));
+ memcpy(key,SOAP_GLOBAL(cache_dir),len);
+ memcpy(key+len,"/wsdl-",sizeof("/wsdl-")-1);
+ memcpy(key+len+sizeof("/wsdl-")-1,md5str,sizeof(md5str));
+
+ if ((sdl = get_sdl_from_cache(key, fn, t-SOAP_GLOBAL(cache_ttl))) == NULL) {
+ sdl = load_wsdl(fn);
+ if (sdl != NULL) {
+ add_sdl_to_cache(key, fn, t, sdl);
+ }
}
+ free_alloca(key);
}
- free_alloca(key);
- return sdl;
} else {
- return load_wsdl(uri);
+ sdl = load_wsdl(uri);
}
#endif
+ SOAP_GLOBAL(error_code) = old_error_code;
+ return sdl;
}
/* Deletes */
diff --git a/ext/soap/php_soap.h b/ext/soap/php_soap.h
index 192289f377..5b74760820 100644
--- a/ext/soap/php_soap.h
+++ b/ext/soap/php_soap.h
@@ -148,6 +148,8 @@ ZEND_BEGIN_MODULE_GLOBALS(soap)
int soap_version;
sdlPtr sdl;
zend_bool use_soap_error_handler;
+ char* error_code;
+ zval* error_object;
zend_bool cache_enabled;
char* cache_dir;
long cache_ttl;
diff --git a/ext/soap/soap.c b/ext/soap/soap.c
index 5e1e47a10b..84cf34700a 100644
--- a/ext/soap/soap.c
+++ b/ext/soap/soap.c
@@ -24,6 +24,9 @@
#endif
#include "php_soap.h"
#include "ext/session/php_session.h"
+#ifdef ZEND_ENGINE_2
+# include "zend_default_classes.h"
+#endif
static int le_sdl = 0;
static int le_url = 0;
@@ -70,12 +73,62 @@ static void soap_error_handler(int error_num, const char *error_filename, const
#define SOAP_SERVER_BEGIN_CODE() \
zend_bool _old_handler = SOAP_GLOBAL(use_soap_error_handler);\
+ char* _old_error_code = SOAP_GLOBAL(error_code);\
+ zval* _old_error_object = SOAP_GLOBAL(error_object);\
int _old_soap_version = SOAP_GLOBAL(soap_version);\
- SOAP_GLOBAL(use_soap_error_handler) = 1;
+ SOAP_GLOBAL(use_soap_error_handler) = 1;\
+ SOAP_GLOBAL(error_code) = "Server";\
+ SOAP_GLOBAL(error_object) = this_ptr;
#define SOAP_SERVER_END_CODE() \
SOAP_GLOBAL(use_soap_error_handler) = _old_handler;\
+ SOAP_GLOBAL(error_code) = _old_error_code;\
+ SOAP_GLOBAL(error_object) = _old_error_object;\
+ SOAP_GLOBAL(soap_version) = _old_soap_version;
+
+#ifdef ZEND_ENGINE_2
+#define SOAP_CLIENT_BEGIN_CODE() \
+ zend_bool _old_handler = SOAP_GLOBAL(use_soap_error_handler);\
+ char* _old_error_code = SOAP_GLOBAL(error_code);\
+ zval* _old_error_object = SOAP_GLOBAL(error_object);\
+ int _old_soap_version = SOAP_GLOBAL(soap_version);\
+ int _bailout = 0;\
+ SOAP_GLOBAL(use_soap_error_handler) = 1;\
+ SOAP_GLOBAL(error_code) = "Client";\
+ SOAP_GLOBAL(error_object) = this_ptr;\
+ zend_try {
+
+#define SOAP_CLIENT_END_CODE() \
+ } zend_catch {\
+ if (EG(exception) == NULL || \
+ Z_TYPE_P(EG(exception)) != IS_OBJECT || \
+ Z_OBJCE_P(EG(exception)) != soap_fault_class_entry) {\
+ _bailout = 1;\
+ }\
+ } zend_end_try();\
+ SOAP_GLOBAL(use_soap_error_handler) = _old_handler;\
+ SOAP_GLOBAL(error_code) = _old_error_code;\
+ SOAP_GLOBAL(error_object) = _old_error_object;\
+ SOAP_GLOBAL(soap_version) = _old_soap_version;\
+ if (_bailout) {\
+ zend_bailout();\
+ }
+#else
+#define SOAP_CLIENT_BEGIN_CODE() \
+ zend_bool _old_handler = SOAP_GLOBAL(use_soap_error_handler);\
+ char* _old_error_code = SOAP_GLOBAL(error_code);\
+ zval* _old_error_object = SOAP_GLOBAL(error_object);\
+ int _old_soap_version = SOAP_GLOBAL(soap_version);\
+ SOAP_GLOBAL(use_soap_error_handler) = 1;\
+ SOAP_GLOBAL(error_code) = "Client";\
+ SOAP_GLOBAL(error_object) = this_ptr;
+
+#define SOAP_CLIENT_END_CODE() \
+ SOAP_GLOBAL(use_soap_error_handler) = _old_handler;\
+ SOAP_GLOBAL(error_code) = _old_error_code;\
+ SOAP_GLOBAL(error_object) = _old_error_object;\
SOAP_GLOBAL(soap_version) = _old_soap_version;
+#endif
#define HTTP_RAW_POST_DATA "HTTP_RAW_POST_DATA"
@@ -124,6 +177,7 @@ static void (*old_error_handler)(int, const char *, const uint, const char*, va_
#define PHP_SOAP_PARAM_CLASSNAME "soapparam"
#define PHP_SOAP_HEADER_CLASSNAME "soapheader"
+PHP_RINIT_FUNCTION(soap);
PHP_MINIT_FUNCTION(soap);
PHP_MSHUTDOWN_FUNCTION(soap);
PHP_MINFO_FUNCTION(soap);
@@ -184,6 +238,9 @@ PHP_METHOD(soapvar, soapvar);
/* SoapFault Functions */
PHP_METHOD(soapfault, soapfault);
+#ifdef ZEND_ENGINE_2
+PHP_METHOD(soapfault, __toString);
+#endif
/* SoapParam Functions */
PHP_METHOD(soapparam, soapparam);
@@ -203,6 +260,9 @@ static zend_function_entry soap_functions[] = {
static zend_function_entry soap_fault_functions[] = {
PHP_ME(soapfault, soapfault, NULL, 0)
+#ifdef ZEND_ENGINE_2
+ PHP_ME(soapfault, __toString, NULL, 0)
+#endif
{NULL, NULL, NULL}
};
@@ -265,7 +325,7 @@ zend_module_entry soap_module_entry = {
soap_functions,
PHP_MINIT(soap),
PHP_MSHUTDOWN(soap),
- NULL,
+ PHP_RINIT(soap),
NULL,
PHP_MINFO(soap),
#ifdef STANDARD_MODULE_HEADER
@@ -304,8 +364,6 @@ static void php_soap_init_globals(zend_soap_globals *soap_globals)
zend_hash_init(&soap_globals->defEncIndex, 0, NULL, NULL, 1);
zend_hash_init(&soap_globals->defEncNs, 0, NULL, NULL, 1);
- soap_globals->overrides = NULL;
-
i = 0;
do {
enc = (long)&defaultEncoding[i];
@@ -335,7 +393,10 @@ static void php_soap_init_globals(zend_soap_globals *soap_globals)
zend_hash_add(&soap_globals->defEncNs, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE), SOAP_1_1_ENC_NS_PREFIX, sizeof(SOAP_1_1_ENC_NS_PREFIX), NULL);
zend_hash_add(&soap_globals->defEncNs, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE), SOAP_1_2_ENC_NS_PREFIX, sizeof(SOAP_1_2_ENC_NS_PREFIX), NULL);
+ soap_globals->overrides = NULL;
soap_globals->use_soap_error_handler = 0;
+ soap_globals->error_code = NULL;
+ soap_globals->error_object = NULL;
soap_globals->sdl = NULL;
soap_globals->soap_version = SOAP_1_1;
}
@@ -351,6 +412,17 @@ PHP_MSHUTDOWN_FUNCTION(soap)
return SUCCESS;
}
+PHP_RINIT_FUNCTION(soap)
+{
+ SOAP_GLOBAL(overrides) = NULL;
+ SOAP_GLOBAL(use_soap_error_handler) = 0;
+ SOAP_GLOBAL(error_code) = NULL;
+ SOAP_GLOBAL(error_object) = NULL;
+ SOAP_GLOBAL(sdl) = NULL;
+ SOAP_GLOBAL(soap_version) = SOAP_1_1;
+ return SUCCESS;
+}
+
PHP_MINIT_FUNCTION(soap)
{
zend_class_entry ce;
@@ -403,7 +475,11 @@ PHP_MINIT_FUNCTION(soap)
/* Register SoapFault class */
INIT_CLASS_ENTRY(ce, PHP_SOAP_FAULT_CLASSNAME, soap_fault_functions);
+#ifdef ZEND_ENGINE_2
+ soap_fault_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(), NULL TSRMLS_CC);
+#else
soap_fault_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
+#endif
/* Register SoapParam class */
INIT_CLASS_ENTRY(ce, PHP_SOAP_PARAM_CLASSNAME, soap_param_functions);
@@ -611,6 +687,44 @@ PHP_METHOD(soapfault,soapfault)
set_soap_fault(this_ptr, fault_code, fault_string, fault_actor, details TSRMLS_CC);
}
+#ifdef ZEND_ENGINE_2
+PHP_METHOD(soapfault,__toString)
+{
+ zval *faultcode, *faultstring, *file, *line, *trace;
+ char *str;
+ int len;
+ zend_fcall_info fci;
+ zval fname;
+
+ faultcode = zend_read_property(soap_fault_class_entry, this_ptr, "faultcode", sizeof("faultcode")-1, 1 TSRMLS_CC);
+ faultstring = zend_read_property(soap_fault_class_entry, this_ptr, "faultstring", sizeof("faultstring")-1, 1 TSRMLS_CC);
+ file = zend_read_property(soap_fault_class_entry, this_ptr, "file", sizeof("file")-1, 1 TSRMLS_CC);
+ line = zend_read_property(soap_fault_class_entry, this_ptr, "line", sizeof("line")-1, 1 TSRMLS_CC);
+
+ ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1, 0);
+
+ fci.size = sizeof(fci);
+ fci.function_table = &Z_OBJCE_P(getThis())->function_table;
+ fci.function_name = &fname;
+ fci.symbol_table = NULL;
+ fci.object_pp = &getThis();
+ fci.retval_ptr_ptr = &trace;
+ fci.param_count = 0;
+ fci.params = NULL;
+ fci.no_separation = 1;
+
+ zend_call_function(&fci, NULL TSRMLS_CC);
+
+ len = spprintf(&str, 0, "SoapFault exception: [%s] %s in %s:%ld\nStack trace:\n%s",
+ Z_STRVAL_P(faultcode), Z_STRVAL_P(faultstring), Z_STRVAL_P(file), Z_LVAL_P(line),
+ Z_STRLEN_P(trace) ? Z_STRVAL_P(trace) : "#0 {main}\n");
+
+ zval_ptr_dtor(&trace);
+
+ RETURN_STRINGL(str, len, 0);
+}
+#endif
+
/* SoapVar functions */
PHP_METHOD(soapvar,soapvar)
{
@@ -1215,6 +1329,13 @@ PHP_METHOD(soapserver, handle)
if (call_user_function(NULL, &tmp_soap, &constructor, &c_ret, service->soap_class.argc, service->soap_class.argv TSRMLS_CC) == FAILURE) {
php_error(E_ERROR, "Error calling constructor");
}
+#ifdef ZEND_ENGINE_2
+ if (EG(exception) &&
+ Z_TYPE_P(EG(exception)) == IS_OBJECT &&
+ Z_OBJCE_P(EG(exception)) == soap_fault_class_entry) {
+ soap_server_fault_ex(EG(exception) TSRMLS_CC);
+ }
+#endif
zval_dtor(&constructor);
zval_dtor(&c_ret);
}
@@ -1289,6 +1410,13 @@ PHP_METHOD(soapserver, handle)
}
efree(fn_name);
+#ifdef ZEND_ENGINE_2
+ if (EG(exception) &&
+ Z_TYPE_P(EG(exception)) == IS_OBJECT &&
+ Z_OBJCE_P(EG(exception)) == soap_fault_class_entry) {
+ soap_server_fault_ex(EG(exception) TSRMLS_CC);
+ }
+#endif
if (call_status == SUCCESS) {
char *response_name;
@@ -1442,7 +1570,7 @@ static void soap_error_handler(int error_num, const char *error_filename, const
*/
if (error_num == E_USER_ERROR || error_num == E_COMPILE_ERROR || error_num == E_CORE_ERROR ||
error_num == E_ERROR || error_num == E_PARSE) {
-
+ char* code = SOAP_GLOBAL(error_code);
char buffer[1024];
int buffer_len;
zval outbuf, outbuflen;
@@ -1455,14 +1583,44 @@ static void soap_error_handler(int error_num, const char *error_filename, const
if (buffer_len > sizeof(buffer) - 1 || buffer_len < 0) {
buffer_len = sizeof(buffer) - 1;
}
+ if (SOAP_GLOBAL(error_object) &&
+ Z_TYPE_P(SOAP_GLOBAL(error_object)) == IS_OBJECT &&
+ Z_OBJCE_P(SOAP_GLOBAL(error_object)) == soap_class_entry) {
+#ifdef ZEND_ENGINE_2
+ zval **tmp;
- /* Get output buffer and send as fault detials */
- if (php_ob_get_length(&outbuflen TSRMLS_CC) != FAILURE && Z_LVAL(outbuflen) != 0) {
- php_ob_get_buffer(&outbuf TSRMLS_CC);
- }
- php_end_ob_buffer(0, 0 TSRMLS_CC);
+ if (zend_hash_find(Z_OBJPROP_P(SOAP_GLOBAL(error_object)), "_exceptions", sizeof("_exceptions"), (void **) &tmp) != SUCCESS ||
+ Z_TYPE_PP(tmp) != IS_BOOL || Z_LVAL_PP(tmp) != 0) {
+ zval *fault, *exception;
- soap_server_fault("Server", buffer, NULL, &outbuf TSRMLS_CC);
+ if (code == NULL) {
+ code = "Client";
+ }
+ fault = add_soap_fault(SOAP_GLOBAL(error_object), code, buffer, NULL, NULL TSRMLS_CC);
+ MAKE_STD_ZVAL(exception);
+ *exception = *fault;
+ zval_copy_ctor(exception);
+ INIT_PZVAL(exception);
+ EG(exception) = exception;
+ zend_bailout();
+ } else {
+ old_error_handler(error_num, error_filename, error_lineno, format, args);
+ }
+#else
+ old_error_handler(error_num, error_filename, error_lineno, format, args);
+#endif
+ } else {
+ if (code == NULL) {
+ code = "Server";
+ }
+ /* Get output buffer and send as fault detials */
+ if (php_ob_get_length(&outbuflen TSRMLS_CC) != FAILURE && Z_LVAL(outbuflen) != 0) {
+ php_ob_get_buffer(&outbuf TSRMLS_CC);
+ }
+ php_end_ob_buffer(0, 0 TSRMLS_CC);
+
+ soap_server_fault(code, buffer, NULL, &outbuf TSRMLS_CC);
+ }
}
}
@@ -1470,6 +1628,7 @@ PHP_FUNCTION(use_soap_error_handler)
{
zend_bool handler = 1;
+ ZVAL_BOOL(return_value, SOAP_GLOBAL(use_soap_error_handler));
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &handler) == SUCCESS) {
SOAP_GLOBAL(use_soap_error_handler) = handler;
}
@@ -1498,6 +1657,8 @@ PHP_METHOD(soapclient, soapclient)
zval *options = NULL;
int soap_version = SOAP_1_1;
+ SOAP_CLIENT_BEGIN_CODE();
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a", &wsdl, &options) == FAILURE) {
php_error(E_ERROR, "Can't create SoapClient. Invalid parameters.");
return;
@@ -1580,6 +1741,13 @@ PHP_METHOD(soapclient, soapclient)
Z_LVAL_PP(tmp) == 1) {
add_property_long(this_ptr, "trace", 1);
}
+#ifdef ZEND_ENGINE_2
+ if (zend_hash_find(ht, "exceptions", sizeof("exceptions"), (void**)&tmp) == SUCCESS &&
+ (Z_TYPE_PP(tmp) == IS_BOOL || Z_TYPE_PP(tmp) == IS_LONG) &&
+ Z_LVAL_PP(tmp) == 0) {
+ add_property_bool(this_ptr, "_exceptions", 0);
+ }
+#endif
} else if (wsdl == NULL) {
php_error(E_ERROR, "Can't create SoapClient. 'location' and 'uri' options are requred in nonWSDL mode.");
return;
@@ -1603,9 +1771,10 @@ PHP_METHOD(soapclient, soapclient)
SOAP_GLOBAL(soap_version) = old_soap_version;
}
+ SOAP_CLIENT_END_CODE();
}
-static void do_soap_call(zval* thisObj,
+static void do_soap_call(zval* this_ptr,
char* function,
int function_len,
int arg_count,
@@ -1626,29 +1795,28 @@ static void do_soap_call(zval* thisObj,
char *buffer;
int len;
int ret = FALSE;
- int bailout = FALSE;
- int soap_version, old_soap_version;
+ int soap_version;
+
+ SOAP_CLIENT_BEGIN_CODE();
- if (zend_hash_find(Z_OBJPROP_P(thisObj), "trace", sizeof("trace"), (void **) &trace) == SUCCESS
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS
&& Z_LVAL_PP(trace) > 0) {
- zend_hash_del(Z_OBJPROP_P(thisObj), "__last_request", sizeof("__last_request"));
- zend_hash_del(Z_OBJPROP_P(thisObj), "__last_response", sizeof("__last_response"));
+ zend_hash_del(Z_OBJPROP_P(this_ptr), "__last_request", sizeof("__last_request"));
+ zend_hash_del(Z_OBJPROP_P(this_ptr), "__last_response", sizeof("__last_response"));
}
- if (zend_hash_find(Z_OBJPROP_P(thisObj), "_soap_version", sizeof("_soap_version"), (void **) &tmp) == SUCCESS
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_soap_version", sizeof("_soap_version"), (void **) &tmp) == SUCCESS
&& Z_LVAL_PP(tmp) == SOAP_1_2) {
soap_version = SOAP_1_2;
} else {
soap_version = SOAP_1_1;
}
- if (FIND_SDL_PROPERTY(thisObj,tmp) != FAILURE) {
+ if (FIND_SDL_PROPERTY(this_ptr,tmp) != FAILURE) {
FETCH_SDL_RES(sdl,tmp);
}
- clear_soap_fault(thisObj TSRMLS_CC);
+ clear_soap_fault(this_ptr TSRMLS_CC);
- old_soap_version = SOAP_GLOBAL(soap_version);
-zend_try {
SOAP_GLOBAL(soap_version) = soap_version;
old_sdl = SOAP_GLOBAL(sdl);
SOAP_GLOBAL(sdl) = sdl;
@@ -1658,19 +1826,19 @@ zend_try {
sdlBindingPtr binding = fn->binding;
if (binding->bindingType == BINDING_SOAP) {
sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
- request = seralize_function_call(thisObj, fn, NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
- ret = send_http_soap_request(thisObj, request, binding->location, fnb->soapAction, soap_version TSRMLS_CC);
+ request = seralize_function_call(this_ptr, fn, NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
+ ret = send_http_soap_request(this_ptr, request, binding->location, fnb->soapAction, soap_version TSRMLS_CC);
} else {
- request = seralize_function_call(thisObj, fn, NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
- ret = send_http_soap_request(thisObj, request, binding->location, NULL, soap_version TSRMLS_CC);
+ request = seralize_function_call(this_ptr, fn, NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
+ ret = send_http_soap_request(this_ptr, request, binding->location, NULL, soap_version TSRMLS_CC);
}
xmlFreeDoc(request);
if (ret) {
- ret = get_http_soap_response(thisObj, &buffer, &len TSRMLS_CC);
+ ret = get_http_soap_response(this_ptr, &buffer, &len TSRMLS_CC);
if (ret) {
- parse_packet_soap(thisObj, buffer, len, fn, NULL, return_value, output_headers TSRMLS_CC);
+ parse_packet_soap(this_ptr, buffer, len, fn, NULL, return_value, output_headers TSRMLS_CC);
efree(buffer);
}
}
@@ -1680,22 +1848,22 @@ zend_try {
smart_str_appends(&error,function);
smart_str_appends(&error,"\") is not a valid method for this service");
smart_str_0(&error);
- add_soap_fault(thisObj, "Client", error.c, NULL, NULL TSRMLS_CC);
+ add_soap_fault(this_ptr, "Client", error.c, NULL, NULL TSRMLS_CC);
smart_str_free(&error);
}
} else {
zval **uri, **location;
smart_str action = {0};
- if (zend_hash_find(Z_OBJPROP_P(thisObj), "uri", sizeof("uri"), (void *)&uri) == FAILURE) {
- add_soap_fault(thisObj, "Client", "Error finding \"uri\" property", NULL, NULL TSRMLS_CC);
- } else if (zend_hash_find(Z_OBJPROP_P(thisObj), "location", sizeof("location"),(void **) &location) == FAILURE) {
- add_soap_fault(thisObj, "Client", "Error could not find \"location\" property", NULL, NULL TSRMLS_CC);
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "uri", sizeof("uri"), (void *)&uri) == FAILURE) {
+ add_soap_fault(this_ptr, "Client", "Error finding \"uri\" property", NULL, NULL TSRMLS_CC);
+ } else if (zend_hash_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location"),(void **) &location) == FAILURE) {
+ add_soap_fault(this_ptr, "Client", "Error could not find \"location\" property", NULL, NULL TSRMLS_CC);
} else {
if (call_uri == NULL) {
call_uri = Z_STRVAL_PP(uri);
}
- request = seralize_function_call(thisObj, NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
+ request = seralize_function_call(this_ptr, NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
if (soap_action == NULL) {
smart_str_appends(&action, call_uri);
@@ -1706,45 +1874,53 @@ zend_try {
}
smart_str_0(&action);
- ret = send_http_soap_request(thisObj, request, Z_STRVAL_PP(location), action.c, soap_version TSRMLS_CC);
+ ret = send_http_soap_request(this_ptr, request, Z_STRVAL_PP(location), action.c, soap_version TSRMLS_CC);
smart_str_free(&action);
xmlFreeDoc(request);
if (ret) {
- ret = get_http_soap_response(thisObj, &buffer, &len TSRMLS_CC);
+ ret = get_http_soap_response(this_ptr, &buffer, &len TSRMLS_CC);
if (ret) {
- ret = parse_packet_soap(thisObj, buffer, len, NULL, function, return_value, output_headers TSRMLS_CC);
+ ret = parse_packet_soap(this_ptr, buffer, len, NULL, function, return_value, output_headers TSRMLS_CC);
efree(buffer);
}
}
}
}
-} zend_catch {
- ret = FALSE;
- bailout = TRUE;
-} zend_end_try();
- if (bailout) {
- zend_bailout();
- }
+
if (!ret) {
zval** fault;
- if (zend_hash_find(Z_OBJPROP_P(thisObj), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
*return_value = **fault;
zval_copy_ctor(return_value);
} else {
- *return_value = *add_soap_fault(thisObj, "Client", "Unknown Error", NULL, NULL TSRMLS_CC);
+ *return_value = *add_soap_fault(this_ptr, "Client", "Unknown Error", NULL, NULL TSRMLS_CC);
zval_copy_ctor(return_value);
}
} else {
zval** fault;
- if (zend_hash_find(Z_OBJPROP_P(thisObj), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
*return_value = **fault;
zval_copy_ctor(return_value);
}
}
- SOAP_GLOBAL(soap_version) = old_soap_version;
+#ifdef ZEND_ENGINE_2
+ if (Z_TYPE_P(return_value) == IS_OBJECT &&
+ Z_OBJCE_P(return_value) == soap_fault_class_entry &&
+ (zend_hash_find(Z_OBJPROP_P(this_ptr), "_exceptions", sizeof("_exceptions"), (void **) &tmp) != SUCCESS ||
+ Z_TYPE_PP(tmp) != IS_BOOL || Z_LVAL_PP(tmp) != 0)) {
+ zval *exception;
+
+ MAKE_STD_ZVAL(exception);
+ *exception = *return_value;
+ zval_copy_ctor(exception);
+ INIT_PZVAL(exception);
+ EG(exception) = exception;
+ }
+#endif
SOAP_GLOBAL(sdl) = old_sdl;
+ SOAP_CLIENT_END_CODE();
}
PHP_METHOD(soapclient, __call)
diff --git a/ext/soap/tests/schema/test_schema.inc b/ext/soap/tests/schema/test_schema.inc
index 3bdcd95ef7..379e5a158a 100644
--- a/ext/soap/tests/schema/test_schema.inc
+++ b/ext/soap/tests/schema/test_schema.inc
@@ -53,7 +53,7 @@ EOF;
$f = fopen($fname,"w");
fwrite($f,$wsdl);
fclose($f);
- $x = new SoapClient($fname, array("trace"=>1));
+ $x = new SoapClient($fname, array("trace"=>1,"exceptions"=>0));
$y = new SoapServer($fname);
$y->addfunction("test");
unlink($fname);
diff --git a/ext/soap/tests/server018.phpt b/ext/soap/tests/server018.phpt
new file mode 100644
index 0000000000..724f0d8841
--- /dev/null
+++ b/ext/soap/tests/server018.phpt
@@ -0,0 +1,33 @@
+--TEST--
+SOAP Server 18: user fault (through throw)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+function test() {
+ throw new SoapFault("MyFault","My fault string");
+}
+
+$server = new soapserver(null,array('uri'=>"http://testuri.org"));
+$server->addfunction("test");
+
+$HTTP_RAW_POST_DATA = <<<EOF
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<SOAP-ENV:Envelope
+ SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
+ xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:si="http://soapinterop.org/xsd">
+ <SOAP-ENV:Body>
+ <ns1:test xmlns:ns1="http://testuri.org"/>
+ </SOAP-ENV:Body>
+</SOAP-ENV:Envelope>
+EOF;
+
+$server->handle();
+echo "ok\n";
+?>
+--EXPECT--
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>MyFault</faultcode><faultstring>My fault string</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>