]> granicus.if.org Git - php/commitdiff
Support for HTTP proxies was implemented
authorDmitry Stogov <dmitry@php.net>
Thu, 29 Jan 2004 11:26:52 +0000 (11:26 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 29 Jan 2004 11:26:52 +0000 (11:26 +0000)
ext/soap/TODO
ext/soap/php_http.c
ext/soap/soap.c

index c0f3e8e951799d801fb2741e642a106379dd4f1e..3f011b06f3b8d573887c8da2af66b3d01a14cecf 100644 (file)
@@ -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
index b61b99424232aa092a5fa587c5669816775766d7..0f85b13adf5d066c9f60d963d762633f063b092e 100644 (file)
@@ -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 */
index 60264239789217b5a61c271605d0129a35da270e..535c37d5901634e2a77c45063f4782aa3fb3337d 100644 (file)
@@ -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)
 {