Reimplemented SoapServer and SoapClient classes using ZE2 object API.

All internal properties are hidden now.
This commit is contained in:
Dmitry Stogov 2006-07-31 16:02:04 +00:00
parent 304816bf78
commit ac7333ce60
7 changed files with 740 additions and 602 deletions

View File

@ -57,17 +57,18 @@ static int stream_alive(php_stream *stream TSRMLS_DC)
/* Proxy HTTP Authentication */
void proxy_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
{
zval **login, **password;
soap_client_object *client;
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_login", sizeof("_proxy_login"), (void **)&login) == SUCCESS) {
client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
if (client->proxy_login) {
unsigned char* buf;
int len;
smart_str auth = {0};
smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
smart_str_appends(&auth, client->proxy_login);
smart_str_appendc(&auth, ':');
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_password", sizeof("_proxy_password"), (void **)&password) == SUCCESS) {
smart_str_appendl(&auth, Z_STRVAL_PP(password), Z_STRLEN_PP(password));
if (client->proxy_password) {
smart_str_appends(&auth, client->proxy_login);
}
smart_str_0(&auth);
buf = php_base64_encode((unsigned char*)auth.c, auth.len, &len);
@ -82,18 +83,18 @@ void proxy_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
/* HTTP Authentication */
void basic_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
{
zval **login, **password;
soap_client_object *client;
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_login", sizeof("_login"), (void **)&login) == SUCCESS &&
!zend_hash_exists(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest"))) {
client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
if (client->login && !client->digest) {
unsigned char* buf;
int len;
smart_str auth = {0};
smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
smart_str_appends(&auth, client->login);
smart_str_appendc(&auth, ':');
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS) {
smart_str_appendl(&auth, Z_STRVAL_PP(password), Z_STRLEN_PP(password));
if (client->password) {
smart_str_appends(&auth, client->password);
}
smart_str_0(&auth);
buf = php_base64_encode((unsigned char*)auth.c, auth.len, &len);
@ -108,7 +109,6 @@ void basic_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, int *use_proxy TSRMLS_DC)
{
php_stream *stream;
zval **proxy_host, **proxy_port, **tmp;
char *host;
php_stream_context *context = NULL;
char *name;
@ -117,21 +117,19 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, in
int old_error_reporting;
struct timeval tv;
struct timeval *timeout = NULL;
soap_client_object *client;
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_host", sizeof("_proxy_host"), (void **) &proxy_host) == SUCCESS &&
Z_TYPE_PP(proxy_host) == IS_STRING &&
zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_port", sizeof("_proxy_port"), (void **) &proxy_port) == SUCCESS &&
Z_TYPE_PP(proxy_port) == IS_LONG) {
host = Z_STRVAL_PP(proxy_host);
port = Z_LVAL_PP(proxy_port);
client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
if (client->proxy_host) {
host = client->proxy_host;
port = client->proxy_port;
*use_proxy = 1;
} else {
host = phpurl->host;
port = phpurl->port;
}
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_connection_timeout", sizeof("_connection_timeout"), (void **) &tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_LONG && Z_LVAL_PP(tmp) > 0) {
tv.tv_sec = Z_LVAL_PP(tmp);
if (client->connection_timeout) {
tv.tv_sec = client->connection_timeout;
tv.tv_usec = 0;
timeout = &tv;
}
@ -139,10 +137,7 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, in
old_error_reporting = EG(error_reporting);
EG(error_reporting) &= ~(E_WARNING|E_NOTICE|E_USER_WARNING|E_USER_NOTICE);
if (SUCCESS == zend_hash_find(Z_OBJPROP_P(this_ptr),
"_stream_context", sizeof("_stream_context"), (void**)&tmp)) {
context = php_stream_context_from_zval(*tmp, 0);
}
context = client->stream_context;
namelen = spprintf(&name, 0, "%s://%s:%d", (use_ssl && !*use_proxy)? "ssl" : "tcp", host, port);
@ -227,7 +222,6 @@ int make_http_soap_request(zval *this_ptr,
int request_size, err;
php_url *phpurl = NULL;
php_stream *stream;
zval **trace, **tmp;
int use_proxy = 0;
int use_ssl;
char *http_headers, *http_body, *content_type, *http_version, *cookie_itt;
@ -239,21 +233,23 @@ int make_http_soap_request(zval *this_ptr,
char *content_encoding;
char *http_msg = NULL;
zend_bool old_allow_url_fopen;
soap_client_object *client;
if (this_ptr == NULL || Z_TYPE_P(this_ptr) != IS_OBJECT) {
return FALSE;
}
client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
request = buf;
request_size = buf_size;
/* Compress request */
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "compression", sizeof("compression"), (void **)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_LONG) {
int level = Z_LVAL_PP(tmp) & 0x0f;
int kind = Z_LVAL_PP(tmp) & SOAP_COMPRESSION_DEFLATE;
if (client->compression) {
int level = client->compression & 0x0f;
int kind = client->compression & SOAP_COMPRESSION_DEFLATE;
if (level > 9) {level = 9;}
if ((Z_LVAL_PP(tmp) & SOAP_COMPRESSION_ACCEPT) != 0) {
if ((client->compression & SOAP_COMPRESSION_ACCEPT) != 0) {
smart_str_append_const(&soap_headers_z,"Accept-Encoding: gzip, deflate\r\n");
}
if (level > 0) {
@ -292,11 +288,9 @@ int make_http_soap_request(zval *this_ptr,
}
}
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"), (void **)&tmp) == SUCCESS) {
php_stream_from_zval_no_verify(stream,tmp);
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"), (void **)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_LONG) {
use_proxy = Z_LVAL_PP(tmp);
}
if (client->stream) {
stream = client->stream;
use_proxy = client->use_proxy;
} else {
stream = NULL;
}
@ -339,20 +333,21 @@ try_again:
/* Check if request to the same host */
if (stream != NULL) {
php_url *orig;
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl"), (void **)&tmp) == SUCCESS &&
(orig = (php_url *) zend_fetch_resource(tmp TSRMLS_CC, -1, "httpurl", NULL, 1, le_url)) != NULL &&
if (client->url &&
((use_proxy && !use_ssl) ||
(((use_ssl && orig->scheme != NULL && strcmp(orig->scheme, "https") == 0) ||
(!use_ssl && orig->scheme == NULL) ||
(!use_ssl && strcmp(orig->scheme, "https") != 0)) &&
strcmp(orig->host, phpurl->host) == 0 &&
orig->port == phpurl->port))) {
(((use_ssl && client->url->scheme != NULL && strcmp(client->url->scheme, "https") == 0) ||
(!use_ssl && client->url->scheme == NULL) ||
(!use_ssl && strcmp(client->url->scheme, "https") != 0)) &&
strcmp(client->url->host, phpurl->host) == 0 &&
client->url->port == phpurl->port))) {
} else {
php_stream_close(stream);
zend_hash_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl"));
zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
if (client->url) {
php_url_free(client->url);
client->url = NULL;
}
client->stream = NULL;
client->use_proxy = 0;
stream = NULL;
use_proxy = 0;
}
@ -361,9 +356,12 @@ try_again:
/* Check if keep-alive connection is still opened */
if (stream != NULL && !stream_alive(stream TSRMLS_CC)) {
php_stream_close(stream);
zend_hash_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl"));
zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
if (client->url) {
php_url_free(client->url);
client->url = NULL;
}
client->stream = NULL;
client->use_proxy = 0;
stream = NULL;
use_proxy = 0;
}
@ -372,8 +370,8 @@ try_again:
stream = http_connect(this_ptr, phpurl, use_ssl, &use_proxy TSRMLS_CC);
if (stream) {
php_stream_auto_cleanup(stream);
add_property_resource(this_ptr, "httpsocket", php_stream_get_resource_id(stream));
add_property_long(this_ptr, "_use_proxy", use_proxy);
client->stream = stream;
client->use_proxy = use_proxy;
} else {
php_url_free(phpurl);
if (request != buf) {efree(request);}
@ -385,12 +383,11 @@ try_again:
PG(allow_url_fopen) = old_allow_url_fopen;
if (stream) {
zval **cookies, **login, **password;
int ret = zend_list_insert(phpurl, le_url);
add_property_resource(this_ptr, "httpurl", ret);
/*zend_list_addref(ret);*/
if (client->url) {
php_url_free(client->url);
client->url = NULL;
}
client->url = phpurl;
smart_str_append_const(&soap_headers, "POST ");
if (use_proxy && !use_ssl) {
smart_str_appends(&soap_headers, phpurl->scheme);
@ -423,11 +420,10 @@ try_again:
"Connection: close\r\n"
"Accept: text/html; text/xml; text/plain\r\n"
*/
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_user_agent", sizeof("_user_agent"), (void **)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING) {
if (Z_STRLEN_PP(tmp) > 0) {
if (client->user_agent) {
if (client->user_agent[0] != 0) {
smart_str_append_const(&soap_headers, "User-Agent: ");
smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
smart_str_appends(&soap_headers, client->user_agent);
smart_str_append_const(&soap_headers, "\r\n");
}
} else{
@ -458,12 +454,9 @@ try_again:
smart_str_append_const(&soap_headers, "\r\n");
/* HTTP Authentication */
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_login", sizeof("_login"), (void **)&login) == SUCCESS &&
Z_TYPE_PP(login) == IS_STRING) {
zval **digest;
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest"), (void **)&digest) == SUCCESS) {
if (Z_TYPE_PP(digest) == IS_ARRAY) {
if (client->login) {
if (client->digest) {
if (client->digest == 2) {
char HA1[33], HA2[33], response[33], cnonce[33], nc[9];
PHP_MD5_CTX md5ctx;
unsigned char hash[16];
@ -474,39 +467,27 @@ try_again:
PHP_MD5Final(hash, &md5ctx);
make_digest(cnonce, hash);
if (zend_hash_find(Z_ARRVAL_PP(digest), "nc", sizeof("nc"), (void **)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_LONG) {
Z_LVAL_PP(tmp)++;
sprintf(nc, "%08ld", Z_LVAL_PP(tmp));
} else {
add_assoc_long(*digest, "nc", 1);
strcpy(nc, "00000001");
}
client->digest_nc++;
sprintf(nc, "%08ld", client->digest_nc);
PHP_MD5Init(&md5ctx);
PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(login), Z_STRLEN_PP(login));
PHP_MD5Update(&md5ctx, (unsigned char*)client->login, strlen(client->login));
PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
if (zend_hash_find(Z_ARRVAL_PP(digest), "realm", sizeof("realm"), (void **)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING) {
PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
if (client->digest_realm) {
PHP_MD5Update(&md5ctx, (unsigned char*)client->digest_realm, strlen(client->digest_realm));
}
PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS &&
Z_TYPE_PP(password) == IS_STRING) {
PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(password), Z_STRLEN_PP(password));
if (client->password) {
PHP_MD5Update(&md5ctx, (unsigned char*)client->password, strlen(client->password));
}
PHP_MD5Final(hash, &md5ctx);
make_digest(HA1, hash);
if (zend_hash_find(Z_ARRVAL_PP(digest), "algorithm", sizeof("algorithm"), (void **)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING &&
Z_STRLEN_PP(tmp) == sizeof("md5-sess")-1 &&
stricmp(Z_STRVAL_PP(tmp), "md5-sess") == 0) {
if (client->digest_algorithm && stricmp(client->digest_algorithm, "md5-sess") == 0) {
PHP_MD5Init(&md5ctx);
PHP_MD5Update(&md5ctx, (unsigned char*)HA1, 32);
PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
if (zend_hash_find(Z_ARRVAL_PP(digest), "nonce", sizeof("nonce"), (void **)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING) {
PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
if (client->digest_nonce) {
PHP_MD5Update(&md5ctx, (unsigned char*)client->digest_nonce, strlen(client->digest_nonce));
}
PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, 8);
@ -526,10 +507,7 @@ try_again:
/* TODO: Support for qop="auth-int" */
/*
if (zend_hash_find(Z_ARRVAL_PP(digest), "qop", sizeof("qop"), (void **)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING &&
Z_STRLEN_PP(tmp) == sizeof("auth-int")-1 &&
stricmp(Z_STRVAL_PP(tmp), "auth-int") == 0) {
if (client->digest_qop && stricmp(client->digest_qop, "auth-int") == 0) {
PHP_MD5Update(&md5ctx, ":", 1);
PHP_MD5Update(&md5ctx, HEntity, HASHHEXLEN);
}
@ -540,13 +518,11 @@ try_again:
PHP_MD5Init(&md5ctx);
PHP_MD5Update(&md5ctx, (unsigned char*)HA1, 32);
PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
if (zend_hash_find(Z_ARRVAL_PP(digest), "nonce", sizeof("nonce"), (void **)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING) {
PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
if (client->digest_nonce) {
PHP_MD5Update(&md5ctx, (unsigned char*)client->digest_nonce, strlen(client->digest_nonce));
}
PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
if (zend_hash_find(Z_ARRVAL_PP(digest), "qop", sizeof("qop"), (void **)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING) {
if (client->digest_qop) {
PHP_MD5Update(&md5ctx, (unsigned char*)nc, 8);
PHP_MD5Update(&md5ctx, (unsigned char*)":", 1);
PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, 8);
@ -560,16 +536,14 @@ try_again:
make_digest(response, hash);
smart_str_append_const(&soap_headers, "Authorization: Digest username=\"");
smart_str_appendl(&soap_headers, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
if (zend_hash_find(Z_ARRVAL_PP(digest), "realm", sizeof("realm"), (void **)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING) {
smart_str_appends(&soap_headers, client->login);
if (client->digest_realm) {
smart_str_append_const(&soap_headers, "\", realm=\"");
smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
smart_str_appends(&soap_headers, client->digest_realm);
}
if (zend_hash_find(Z_ARRVAL_PP(digest), "nonce", sizeof("nonce"), (void **)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING) {
if (client->digest_nonce) {
smart_str_append_const(&soap_headers, "\", nonce=\"");
smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
smart_str_appends(&soap_headers, client->digest_nonce);
}
smart_str_append_const(&soap_headers, "\", uri=\"");
if (phpurl->path) {
@ -583,8 +557,7 @@ try_again:
smart_str_appendc(&soap_headers, '#');
smart_str_appends(&soap_headers, phpurl->fragment);
}
if (zend_hash_find(Z_ARRVAL_PP(digest), "qop", sizeof("qop"), (void **)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING) {
if (client->digest_qop) {
/* TODO: Support for qop="auth-int" */
smart_str_append_const(&soap_headers, "\", qop=\"auth");
smart_str_append_const(&soap_headers, "\", nc=\"");
@ -594,10 +567,9 @@ try_again:
}
smart_str_append_const(&soap_headers, "\", response=\"");
smart_str_appendl(&soap_headers, response, 32);
if (zend_hash_find(Z_ARRVAL_PP(digest), "opaque", sizeof("opaque"), (void **)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING) {
if (client->digest_opaque) {
smart_str_append_const(&soap_headers, "\", opaque=\"");
smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
smart_str_appends(&soap_headers, client->digest_opaque);
}
smart_str_append_const(&soap_headers, "\"\r\n");
}
@ -606,11 +578,10 @@ try_again:
int len;
smart_str auth = {0};
smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
smart_str_appends(&auth, client->login);
smart_str_appendc(&auth, ':');
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS &&
Z_TYPE_PP(password) == IS_STRING) {
smart_str_appendl(&auth, Z_STRVAL_PP(password), Z_STRLEN_PP(password));
if (client->password) {
smart_str_appends(&auth, client->password);
}
smart_str_0(&auth);
buf = php_base64_encode((unsigned char*)auth.c, auth.len, &len);
@ -628,19 +599,19 @@ try_again:
}
/* Send cookies along with request */
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == SUCCESS) {
if (client->cookies) {
zval **data;
zstr key;
int i, n;
n = zend_hash_num_elements(Z_ARRVAL_PP(cookies));
n = zend_hash_num_elements(Z_ARRVAL_P(client->cookies));
if (n > 0) {
zend_hash_internal_pointer_reset(Z_ARRVAL_PP(cookies));
zend_hash_internal_pointer_reset(Z_ARRVAL_P(client->cookies));
smart_str_append_const(&soap_headers, "Cookie: ");
for (i = 0; i < n; i++) {
zend_hash_get_current_data(Z_ARRVAL_PP(cookies), (void **)&data);
zend_hash_get_current_data(Z_ARRVAL_P(client->cookies), (void **)&data);
/* TODO: unicode support */
zend_hash_get_current_key(Z_ARRVAL_PP(cookies), &key, NULL, FALSE);
zend_hash_get_current_key(Z_ARRVAL_P(client->cookies), &key, NULL, FALSE);
if (Z_TYPE_PP(data) == IS_ARRAY) {
zval** value;
@ -660,16 +631,18 @@ try_again:
}
}
}
zend_hash_move_forward(Z_ARRVAL_PP(cookies));
zend_hash_move_forward(Z_ARRVAL_P(client->cookies));
}
smart_str_append_const(&soap_headers, "\r\n");
}
}
smart_str_append_const(&soap_headers, "\r\n");
smart_str_0(&soap_headers);
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_headers", soap_headers.c, soap_headers.len, 1);
if (client->trace) {
if (client->last_request_headers) {
efree(client->last_request_headers);
}
client->last_request_headers = estrndup(soap_headers.c, soap_headers.len);
}
smart_str_appendl(&soap_headers, request, request_size);
smart_str_0(&soap_headers);
@ -679,9 +652,12 @@ try_again:
if (request != buf) {efree(request);}
smart_str_free(&soap_headers);
php_stream_close(stream);
zend_hash_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl"));
zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
if (client->url) {
php_url_free(client->url);
client->url = NULL;
}
client->stream = NULL;
client->use_proxy = 0;
add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL TSRMLS_CC);
return FALSE;
}
@ -694,8 +670,8 @@ try_again:
if (!buffer) {
php_stream_close(stream);
zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
client->stream = NULL;
client->use_proxy = 0;
return TRUE;
}
@ -704,15 +680,17 @@ try_again:
if (http_headers) {efree(http_headers);}
if (request != buf) {efree(request);}
php_stream_close(stream);
zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
client->stream = NULL;
client->use_proxy = 0;
add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL TSRMLS_CC);
return FALSE;
}
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_headers", http_headers, http_header_size, 1);
if (client->trace) {
if (client->last_response_headers) {
efree(client->last_response_headers);
}
client->last_response_headers = estrndup(http_headers, http_header_size);
}
/* Check to see what HTTP status was sent */
@ -758,13 +736,10 @@ try_again:
while (cookie_itt) {
char *end_pos, *cookie;
char *eqpos, *sempos;
zval **cookies;
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == FAILURE) {
zval *tmp_cookies;
MAKE_STD_ZVAL(tmp_cookies);
array_init(tmp_cookies);
zend_hash_update(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), &tmp_cookies, sizeof(zval *), (void **)&cookies);
if (!client->cookies) {
MAKE_STD_ZVAL(client->cookies);
array_init(client->cookies);
}
end_pos = strstr(cookie_itt,"\r\n");
@ -822,7 +797,7 @@ try_again:
add_index_string(zcookie, 2, phpurl->host, 1);
}
add_assoc_zval_ex(*cookies, name.c, name.len+1, zcookie);
add_assoc_zval_ex(client->cookies, name.c, name.len+1, zcookie);
smart_str_free(&name);
}
@ -849,8 +824,8 @@ try_again:
if (request != buf) {efree(request);}
php_stream_close(stream);
efree(http_headers);
zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
client->stream = NULL;
client->use_proxy = 0;
add_soap_fault(this_ptr, "HTTP", "Error Fetching http body, No Content-Length, connection closed or chunked data", NULL, NULL TSRMLS_CC);
if (http_msg) {
efree(http_msg);
@ -887,8 +862,8 @@ try_again:
if (http_close) {
php_stream_close(stream);
zend_hash_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket"));
zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
client->stream = NULL;
client->use_proxy = 0;
stream = NULL;
}
@ -926,20 +901,15 @@ try_again:
}
} else if (http_status == 401) {
/* Digest authentication */
zval **digest, **login, **password;
char *auth = get_http_header_value(http_headers, "WWW-Authenticate: ");
if (auth &&
strstr(auth, "Digest") == auth &&
(zend_hash_find(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest"), (void **)&digest) == FAILURE ||
Z_TYPE_PP(digest) != IS_ARRAY) &&
zend_hash_find(Z_OBJPROP_P(this_ptr), "_login", sizeof("_login"), (void **)&login) == SUCCESS &&
Z_TYPE_PP(login) == IS_STRING &&
zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS &&
Z_TYPE_PP(password) == IS_STRING) {
if (auth && strstr(auth, "Digest") == auth &&
(client->digest < 2) &&
client->login && client->password) {
char *s;
zval *digest = NULL;
php_url *new_url;
client->digest = 2;
s = auth + sizeof("Digest")-1;
while (*s != '\0') {
char *name, *val;
@ -968,20 +938,21 @@ try_again:
++s;
}
}
if (digest == NULL) {
ALLOC_INIT_ZVAL(digest);
array_init(digest);
if (strcmp(name, "realm") == 0) {
client->digest_realm = estrdup(val);
} else if (strcmp(name, "algorithm") == 0) {
client->digest_algorithm = estrdup(val);
} else if (strcmp(name, "nonce") == 0) {
client->digest_nonce = estrdup(val);
} else if (strcmp(name, "qop") == 0) {
client->digest_qop = estrdup(val);
} else if (strcmp(name, "opaque") == 0) {
client->digest_opaque = estrdup(val);
}
add_assoc_string(digest, name, val ,1);
}
}
if (digest != NULL) {
php_url *new_url = emalloc(sizeof(php_url));
digest->refcount--;
add_property_zval_ex(this_ptr, "_digest", sizeof("_digest"), digest TSRMLS_CC);
new_url = emalloc(sizeof(php_url));
*new_url = *phpurl;
if (phpurl->scheme) phpurl->scheme = estrdup(phpurl->scheme);
if (phpurl->user) phpurl->user = estrdup(phpurl->user);
@ -998,7 +969,6 @@ try_again:
goto try_again;
}
}
if (auth) efree(auth);
}

View File

@ -226,7 +226,7 @@ static int is_wsdl_element(xmlNodePtr node)
return 1;
}
static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include TSRMLS_DC)
static void load_wsdl_ex(char *struri, sdlCtx *ctx, int include TSRMLS_DC)
{
sdlPtr tmpsdl = ctx->sdl;
xmlDocPtr wsdl;
@ -296,7 +296,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include
uri = xmlBuildURI(tmp->children->content, base);
xmlFree(base);
}
load_wsdl_ex(this_ptr, (char*)uri, ctx, 1 TSRMLS_CC);
load_wsdl_ex((char*)uri, ctx, 1 TSRMLS_CC);
xmlFree(uri);
}
@ -628,7 +628,7 @@ static HashTable* wsdl_message(sdlCtx *ctx, xmlChar* message_name)
return parameters;
}
static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
static sdlPtr load_wsdl(char *struri TSRMLS_DC)
{
sdlCtx ctx;
int i,n;
@ -645,7 +645,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
zend_hash_init(&ctx.portTypes, 0, NULL, NULL, 0);
zend_hash_init(&ctx.services, 0, NULL, NULL, 0);
load_wsdl_ex(this_ptr, struri,&ctx, 0 TSRMLS_CC);
load_wsdl_ex(struri,&ctx, 0 TSRMLS_CC);
schema_pass2(&ctx);
n = zend_hash_num_elements(&ctx.services);
@ -3079,7 +3079,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
char* old_error_code = SOAP_GLOBAL(error_code);
int uri_len = 0;
php_stream_context *context=NULL;
zval **tmp, **proxy_host, **proxy_port, *orig_context = NULL, *new_context = NULL;
zval *orig_context = NULL, *new_context = NULL;
smart_str headers = {0};
char* key = NULL;
time_t t = time(0);
@ -3131,26 +3131,24 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
}
}
if (SUCCESS == zend_hash_find(Z_OBJPROP_P(this_ptr),
"_stream_context", sizeof("_stream_context"), (void**)&tmp)) {
context = php_stream_context_from_zval(*tmp, 0);
if (this_ptr) {
soap_client_object *client;
client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC);
if (client->stream_context) {
context = client->stream_context;
}
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_host", sizeof("_proxy_host"), (void **) &proxy_host) == SUCCESS &&
Z_TYPE_PP(proxy_host) == IS_STRING &&
zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_port", sizeof("_proxy_port"), (void **) &proxy_port) == SUCCESS &&
Z_TYPE_PP(proxy_port) == IS_LONG) {
zval str_port, *str_proxy;
if (client->proxy_host) {
zval *str_proxy;
smart_str proxy = {0};
str_port = **proxy_port;
zval_copy_ctor(&str_port);
convert_to_string(&str_port);
smart_str_appends(&proxy,"tcp://");
smart_str_appends(&proxy,Z_STRVAL_PP(proxy_host));
smart_str_appends(&proxy, client->proxy_host);
smart_str_appends(&proxy,":");
smart_str_appends(&proxy,Z_STRVAL(str_port));
smart_str_append_unsigned(&proxy, client->proxy_port);
smart_str_0(&proxy);
zval_dtor(&str_port);
MAKE_STD_ZVAL(str_proxy);
ZVAL_STRING(str_proxy, proxy.c, 1);
smart_str_free(&proxy);
@ -3170,6 +3168,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
}
basic_authentication(this_ptr, &headers TSRMLS_CC);
}
if (headers.len > 0) {
zval *str_headers;
@ -3194,7 +3193,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
SOAP_GLOBAL(error_code) = "WSDL";
sdl = load_wsdl(this_ptr, uri TSRMLS_CC);
sdl = load_wsdl(uri TSRMLS_CC);
if (sdl) {
sdl->is_persistent = 0;
}

View File

@ -49,8 +49,6 @@
# define stricmp strcasecmp
#endif
extern int le_url;
typedef struct _encodeType encodeType, *encodeTypePtr;
typedef struct _encode encode, *encodePtr;
@ -68,7 +66,6 @@ typedef struct _sdlSoapBindingFunction sdlSoapBindingFunction, *sdlSoapBindingFu
typedef struct _sdlSoapBindingFunctionBody sdlSoapBindingFunctionBody, *sdlSoapBindingFunctionBodyPtr;
typedef struct _soapMapping soapMapping, *soapMappingPtr;
typedef struct _soapService soapService, *soapServicePtr;
#include "php_xml.h"
#include "php_encoding.h"
@ -99,8 +96,16 @@ struct _soapMapping {
struct _soapHeader;
struct _soapService {
typedef struct _soap_server_object {
zend_object zo;
sdlPtr sdl;
char *uri;
HashTable *mapping;
int version;
HashTable *class_map;
int features;
xmlCharEncodingHandlerPtr encoding;
struct _soap_functions {
HashTable *ft;
@ -114,16 +119,63 @@ struct _soapService {
int persistance;
} soap_class;
HashTable *mapping;
int version;
int type;
char *actor;
struct _soapHeader **soap_headers_ptr;
} soap_server_object;
typedef struct _soap_client_object {
zend_object zo;
sdlPtr sdl;
char *uri;
xmlCharEncodingHandlerPtr encoding;
HashTable *mapping;
int version;
HashTable *class_map;
int features;
struct _soapHeader **soap_headers_ptr;
};
xmlCharEncodingHandlerPtr encoding;
int style;
int use;
char *location;
char *login;
char *password;
long digest;
long digest_nc;
char *digest_realm;
char *digest_algorithm;
char *digest_nonce;
char *digest_qop;
char *digest_opaque;
char *proxy_host;
long proxy_port;
char *proxy_login;
char *proxy_password;
char *user_agent;
long connection_timeout;
long compression;
php_stream_context *stream_context;
php_stream *stream;
php_url *url;
zend_bool use_proxy;
zend_bool exceptions;
zend_bool trace;
char *last_request_headers;
char *last_request;
char *last_response_headers;
char *last_response;
zval *default_headers;
zval *cookies;
zval *fault;
} soap_client_object;
#define SOAP_CLASS 1
#define SOAP_FUNCTIONS 2

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,8 @@ function test() {
$server = new soapserver(null,array('uri'=>"http://testuri.org"));
$server->addfunction("test");
$HTTP_RAW_POST_DATA = gzencode(<<<EOF
<?xml version="1.0" encoding="ISO-8859-1"?>
$HTTP_RAW_POST_DATA = gzencode(
b'<?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/"
@ -25,8 +25,7 @@ $HTTP_RAW_POST_DATA = gzencode(<<<EOF
<ns1:test xmlns:ns1="http://testuri.org" />
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
EOF
, 9, FORCE_GZIP);
', 9, FORCE_GZIP);
$_SERVER['HTTP_CONTENT_ENCODING'] = "gzip";
$server->handle();
echo "ok\n";

View File

@ -13,8 +13,8 @@ function test() {
$server = new soapserver(null,array('uri'=>"http://testuri.org"));
$server->addfunction("test");
$HTTP_RAW_POST_DATA = gzcompress(<<<EOF
<?xml version="1.0" encoding="ISO-8859-1"?>
$HTTP_RAW_POST_DATA = gzcompress(
b'<?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/"
@ -25,8 +25,7 @@ $HTTP_RAW_POST_DATA = gzcompress(<<<EOF
<ns1:test xmlns:ns1="http://testuri.org" />
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
EOF
, 9);
', 9);
$_SERVER['HTTP_CONTENT_ENCODING'] = "deflate";
$server->handle();
echo "ok\n";

38
ext/soap/tests/setheaders.phpt Executable file
View File

@ -0,0 +1,38 @@
--TEST--
SOAP: SoapClient::__setHeaders
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
$client = new SoapClient(NULL, array("location"=>"test://","uri"=>"test://",
"exceptions"=>0,"trace"=>1));
$client->test();
echo $client->__getLastRequest();
$client->__setSoapHeaders(new SoapHeader("test://","HDR1"));
$client->test();
echo $client->__getLastRequest();
$client->test();
echo $client->__getLastRequest();
$client->__setSoapHeaders();
$client->test();
echo $client->__getLastRequest();
$client->__setSoapHeaders(array(new SoapHeader("test://","HDR1"),new SoapHeader("test://","HDR2")));
$client->test();
echo $client->__getLastRequest();
$h = array(new SoapHeader("test://","HDR0"));
$client->__soapCall("test", array(), null, $h);
echo $client->__getLastRequest();
?>
--EXPECT--
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test://" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:test/></SOAP-ENV:Body></SOAP-ENV:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test://" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Header><ns1:HDR1/></SOAP-ENV:Header><SOAP-ENV:Body><ns1:test/></SOAP-ENV:Body></SOAP-ENV:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test://" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Header><ns1:HDR1/></SOAP-ENV:Header><SOAP-ENV:Body><ns1:test/></SOAP-ENV:Body></SOAP-ENV:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test://" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:test/></SOAP-ENV:Body></SOAP-ENV:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test://" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Header><ns1:HDR1/><ns1:HDR2/></SOAP-ENV:Header><SOAP-ENV:Body><ns1:test/></SOAP-ENV:Body></SOAP-ENV:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test://" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Header><ns1:HDR0/><ns1:HDR1/><ns1:HDR2/></SOAP-ENV:Header><SOAP-ENV:Body><ns1:test/></SOAP-ENV:Body></SOAP-ENV:Envelope>