summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2004-01-29 11:26:52 +0000
committerDmitry Stogov <dmitry@php.net>2004-01-29 11:26:52 +0000
commit5ab77a92680c52d1d4a36126dc5b71b547079975 (patch)
tree2ea954f2c7f9391a604872147be1c1d9bbfc9f39
parent9d2f84e41135f66214c8f786d16a298909eb8f63 (diff)
downloadphp-git-5ab77a92680c52d1d4a36126dc5b71b547079975.tar.gz
Support for HTTP proxies was implemented
-rw-r--r--ext/soap/TODO1
-rw-r--r--ext/soap/php_http.c87
-rw-r--r--ext/soap/soap.c28
3 files changed, 100 insertions, 16 deletions
diff --git a/ext/soap/TODO b/ext/soap/TODO
index c0f3e8e951..3f011b06f3 100644
--- a/ext/soap/TODO
+++ b/ext/soap/TODO
@@ -99,7 +99,6 @@ Transport
? HTTP status codes
? HTTP chunked Transfer-Encoding
- support for HTTP compression (gzip,x-gzip,defalte)
-- support for HTTP proxies
- transport abstraction layer???
UDDI
diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c
index b61b994242..0f85b13adf 100644
--- a/ext/soap/php_http.c
+++ b/ext/soap/php_http.c
@@ -36,6 +36,8 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
php_stream *stream;
zval **trace, **tmp;
int old_error_reporting;
+ int use_proxy = 0;
+ int use_ssl;
if (this_ptr == NULL || Z_TYPE_P(this_ptr) != IS_OBJECT) {
return FALSE;
@@ -43,6 +45,9 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
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);
+ }
} else {
stream = NULL;
}
@@ -66,7 +71,9 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
if (php_stream_set_option(stream, PHP_STREAM_OPTION_CHECK_LIVENESS, 0, NULL) != PHP_STREAM_OPTION_RETURN_OK) {
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"));
stream = NULL;
+ use_proxy = 0;
} else {
tv.tv_sec = FG(default_socket_timeout);;
tv.tv_usec = 0;
@@ -83,26 +90,34 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
return FALSE;
}
- if (!stream) {
- int use_ssl;
- use_ssl = strcmp(phpurl->scheme, "https") == 0;
- if (use_ssl && php_stream_locate_url_wrapper("https://", NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) == NULL) {
- xmlFree(buf);
- php_url_free(phpurl);
- add_soap_fault(this_ptr, "HTTP", "SSL support not available in this build", NULL, NULL TSRMLS_CC);
- return FALSE;
- }
+ use_ssl = strcmp(phpurl->scheme, "https") == 0;
+ if (use_ssl && php_stream_locate_url_wrapper("https://", NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) == NULL) {
+ xmlFree(buf);
+ php_url_free(phpurl);
+ add_soap_fault(this_ptr, "HTTP", "SSL support not available in this build", NULL, NULL TSRMLS_CC);
+ return FALSE;
+ }
- if (phpurl->port == 0) {
- phpurl->port = use_ssl ? 443 : 80;
- }
+ if (phpurl->port == 0) {
+ phpurl->port = use_ssl ? 443 : 80;
+ }
+ if (!stream) {
#ifdef ZEND_ENGINE_2
{
char *res;
long reslen;
-
- reslen = spprintf(&res, 0, "%s://%s:%d", use_ssl ? "ssl" : "tcp", phpurl->host, phpurl->port);
+ zval **proxy_host, **proxy_port;
+
+ 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) {
+ use_proxy = 1;
+ reslen = spprintf(&res, 0, "tcp://%s:%ld", Z_STRVAL_PP(proxy_host), Z_LVAL_PP(proxy_port));
+ } else {
+ reslen = spprintf(&res, 0, "%s://%s:%d", use_ssl ? "ssl" : "tcp", phpurl->host, phpurl->port);
+ }
old_error_reporting = EG(error_reporting);
EG(error_reporting) &= ~(E_WARNING|E_NOTICE|E_USER_WARNING|E_USER_NOTICE);
@@ -134,6 +149,7 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
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);
} else {
xmlFree(buf);
php_url_free(phpurl);
@@ -146,6 +162,13 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
zval **cookies, **login, **password;
smart_str_append_const(&soap_headers, "POST ");
+ if (use_proxy) {
+ smart_str_appends(&soap_headers, phpurl->scheme);
+ smart_str_append_const(&soap_headers, "://");
+ smart_str_appends(&soap_headers, phpurl->host);
+ smart_str_appendc(&soap_headers, ':');
+ smart_str_append_unsigned(&soap_headers, phpurl->port);
+ }
smart_str_appends(&soap_headers, phpurl->path);
smart_str_append_const(&soap_headers, " HTTP/1.1\r\n"
"Host: ");
@@ -194,6 +217,26 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
smart_str_free(&auth);
}
+ /* Proxy HTTP Authentication */
+ if (use_proxy && zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_login", sizeof("_proxy_login"), (void **)&login) == SUCCESS) {
+ char* buf;
+ int len;
+
+ smart_str auth = {0};
+ smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(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));
+ }
+ smart_str_0(&auth);
+ buf = php_base64_encode(auth.c, auth.len, &len);
+ smart_str_append_const(&soap_headers, "Proxy-Authorization: Basic ");
+ smart_str_appendl(&soap_headers, buf, len);
+ smart_str_append_const(&soap_headers, "\r\n");
+ efree(buf);
+ smart_str_free(&auth);
+ }
+
/* Send cookies along with request */
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == SUCCESS) {
zval **data;
@@ -228,6 +271,7 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
smart_str_free(&soap_headers);
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"));
add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL TSRMLS_CC);
return FALSE;
}
@@ -261,6 +305,7 @@ int get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS
if (!get_http_headers(stream, &http_headers, &http_header_size TSRMLS_CC)) {
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"));
add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL TSRMLS_CC);
return FALSE;
}
@@ -311,6 +356,7 @@ int get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS
if (!get_http_headers(stream, &http_headers, &http_header_size TSRMLS_CC)) {
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"));
add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL TSRMLS_CC);
return FALSE;
}
@@ -325,6 +371,7 @@ int get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS
if (!get_http_body(stream, http_headers, &http_body, &http_body_size TSRMLS_CC)) {
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"));
add_soap_fault(this_ptr, "HTTP", "Error Fetching http body, No Content-Length or chunked data", NULL, NULL TSRMLS_CC);
return FALSE;
}
@@ -336,6 +383,17 @@ int get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS
/* See if the server requested a close */
http_close = TRUE;
+ connection = get_http_header_value(http_headers,"Proxy-Connection: ");
+ if (connection) {
+ if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) {
+ http_close = FALSE;
+ }
+ efree(connection);
+/*
+ } else if (http_1_1) {
+ http_close = FALSE;
+*/
+ }
connection = get_http_header_value(http_headers,"Connection: ");
if (connection) {
if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) {
@@ -351,6 +409,7 @@ int get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS
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"));
}
/* Check and see if the server even sent a xml document */
diff --git a/ext/soap/soap.c b/ext/soap/soap.c
index 6026423978..535c37d590 100644
--- a/ext/soap/soap.c
+++ b/ext/soap/soap.c
@@ -153,6 +153,7 @@ PHP_METHOD(soapserver,map);
/* Client Functions */
PHP_METHOD(soapobject, soapobject);
PHP_METHOD(soapobject, __login);
+PHP_METHOD(soapobject, __useproxy);
PHP_METHOD(soapobject, __isfault);
PHP_METHOD(soapobject, __getfault);
PHP_METHOD(soapobject, __call);
@@ -202,6 +203,7 @@ static zend_function_entry soap_server_functions[] = {
static zend_function_entry soap_client_functions[] = {
PHP_ME(soapobject, soapobject, NULL, 0)
PHP_ME(soapobject, __login, NULL, 0)
+ PHP_ME(soapobject, __useproxy, NULL, 0)
PHP_ME(soapobject, __isfault, NULL, 0)
PHP_ME(soapobject, __getfault, NULL, 0)
PHP_ME(soapobject, __call, NULL, 0)
@@ -1160,6 +1162,7 @@ PHP_METHOD(soapserver, handle)
php_end_ob_buffer(0, 0 TSRMLS_CC);
/* xmlDocDumpMemoryEnc(doc_return, &buf, &size, XML_CHAR_ENCODING_UTF8); */
+ xmlSetDocCompressMode(doc_return, 1);
xmlDocDumpMemory(doc_return, &buf, &size);
if (size == 0) {
@@ -1452,7 +1455,7 @@ zend_try {
request = seralize_function_call(thisObj, NULL, function, call_uri, real_args, arg_count, soap_version TSRMLS_CC);
if (soap_action == NULL) {
- smart_str_appendl(&action, Z_STRVAL_PP(uri), Z_STRLEN_PP(uri));
+ smart_str_appends(&action, call_uri);
smart_str_appendc(&action, '#');
smart_str_appends(&action, function);
} else {
@@ -1516,6 +1519,29 @@ PHP_METHOD(soapobject, __login)
add_property_stringl(this_ptr,"_password",login_pass,login_pass_len, 1);
}
+PHP_METHOD(soapobject, __useproxy)
+{
+ char *proxy_host;
+ char *proxy_name = NULL;
+ char *proxy_pass = NULL;
+ int proxy_host_len;
+ int proxy_name_len;
+ int proxy_pass_len;
+ long proxy_port;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|ss",
+ &proxy_host, &proxy_host_len, &proxy_port, &proxy_name, &proxy_name_len, &proxy_pass, &proxy_pass_len) == FAILURE) {
+ return;
+ }
+ add_property_stringl(this_ptr,"_proxy_host",proxy_host,proxy_host_len, 1);
+ add_property_long(this_ptr,"_proxy_port",proxy_port);
+ if (proxy_name) {
+ add_property_stringl(this_ptr,"_proxy_login",proxy_name,proxy_name_len, 1);
+ }
+ if (proxy_pass) {
+ add_property_stringl(this_ptr,"_proxy_password",proxy_pass,proxy_pass_len, 1);
+ }
+}
PHP_METHOD(soapobject, __call)
{