]> granicus.if.org Git - php/commitdiff
SoapClint support for multiple hosts (through WSDL) with cookies.
authorDmitry Stogov <dmitry@php.net>
Fri, 2 Apr 2004 11:12:44 +0000 (11:12 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 2 Apr 2004 11:12:44 +0000 (11:12 +0000)
ext/soap/php_http.c
ext/soap/php_soap.h
ext/soap/soap.c

index a8c07948d6c96bf9c72814259ffbba61e7d0e56b..08068e3814145ec8c3e754f9dad302c844ca7ef5 100644 (file)
@@ -205,19 +205,13 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
                add_property_stringl(this_ptr, "__last_request", buf, buf_size, 1);
        }
 
-       /* 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), "httpsocket", sizeof("httpsocket"));
-               zend_hash_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy"));
-               stream = NULL;
-               use_proxy = 0;
-       }
-
        if (location != NULL && location[0] != '\000') {
                phpurl = php_url_parse(location);
        }
-       if (phpurl == NULL) {
+       if (phpurl == NULL || phpurl->host == NULL) {
+         if (phpurl != NULL) {
+               php_url_free(phpurl);
+         }
                xmlFree(buf);
                add_soap_fault(this_ptr, "HTTP", "Unable to parse URL", NULL, NULL TSRMLS_CC);
                return FALSE;
@@ -254,6 +248,37 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
                phpurl->port = use_ssl ? 443 : 80;
        }
 
+       /* 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 &&
+                   ((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))) {
+    } 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"));
+                       stream = NULL;
+                       use_proxy = 0;
+    }
+       }
+
+       /* 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"));
+               stream = NULL;
+               use_proxy = 0;
+       }
+
        if (!stream) {
                stream = http_connect(this_ptr, phpurl, use_ssl, &use_proxy TSRMLS_CC);
                if (stream) {
@@ -270,6 +295,10 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
 
        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);*/
 
                smart_str_append_const(&soap_headers, "POST ");
                if (use_proxy && !use_ssl) {
@@ -347,15 +376,15 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
                                        request = Z_STRVAL(retval);
                                        request_size = Z_STRLEN(retval);
                                } else {
-                       php_url_free(phpurl);
-                       if (request != buf) {efree(request);}
-                       xmlFree(buf);
-                       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", "Compression Failed", NULL, NULL TSRMLS_CC);
-                       return FALSE;
+                                       if (request != buf) {efree(request);}
+                                       xmlFree(buf);
+                                       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"));
+                                       add_soap_fault(this_ptr, "HTTP", "Compression Failed", NULL, NULL TSRMLS_CC);
+                                       return FALSE;
                                }
                  }
                }
@@ -402,26 +431,45 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
                                        zend_hash_get_current_data(Z_ARRVAL_PP(cookies), (void **)&data);
                                        zend_hash_get_current_key(Z_ARRVAL_PP(cookies), &key, NULL, FALSE);
 
-                                       smart_str_appendl(&soap_headers, key, strlen(key));
-                                       smart_str_appendc(&soap_headers, '=');
-                                       smart_str_appendl(&soap_headers, Z_STRVAL_PP(data), Z_STRLEN_PP(data));
-                                       smart_str_append_const(&soap_headers, ";");
+                                       if (Z_TYPE_PP(data) == IS_ARRAY) {
+                                         zval** value;
+
+                                               if (zend_hash_index_find(Z_ARRVAL_PP(data), 0, (void**)&value) == SUCCESS &&
+                                                   Z_TYPE_PP(value) == IS_STRING) {
+                                                 zval **tmp;
+                                                 if (zend_hash_index_find(Z_ARRVAL_PP(data), 1, (void**)&tmp) == SUCCESS &&
+                                                     strncmp(phpurl->path,Z_STRVAL_PP(tmp),Z_STRLEN_PP(tmp)) == 0 &&
+                                                     zend_hash_index_find(Z_ARRVAL_PP(data), 2, (void**)&tmp) == SUCCESS &&
+                                                     strcmp(phpurl->host,Z_STRVAL_PP(tmp)) == 0 &&
+                                                     (use_ssl || zend_hash_index_find(Z_ARRVAL_PP(data), 3, (void**)&tmp) == FAILURE)) {
+                                                               smart_str_appendl(&soap_headers, key, strlen(key));
+                                                               smart_str_appendc(&soap_headers, '=');
+                                                               smart_str_appendl(&soap_headers, Z_STRVAL_PP(value), Z_STRLEN_PP(value));
+                                                               smart_str_appendc(&soap_headers, ';');
+                                                       }
+                                               }
+                                       }
                                        zend_hash_move_forward(Z_ARRVAL_PP(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);
+               }
                smart_str_appendl(&soap_headers, request, request_size);
                smart_str_0(&soap_headers);
 
                err = php_stream_write(stream, soap_headers.c, soap_headers.len);
                if (err != soap_headers.len) {
-                       php_url_free(phpurl);
                        if (request != buf) {efree(request);}
                        xmlFree(buf);
                        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"));
                        add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL TSRMLS_CC);
@@ -430,7 +478,6 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
                smart_str_free(&soap_headers);
 
        }
-       php_url_free(phpurl);
        if (request != buf) {efree(request);}
        xmlFree(buf);
        return TRUE;
@@ -464,6 +511,11 @@ int get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS
                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);
+       }
+
        /* Check to see what HTTP status was sent */
        http_version = get_http_header_value(http_headers,"HTTP/");
        if (http_version) {
@@ -597,50 +649,86 @@ int get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS
           matter too much
        */
        cookie_itt = strstr(http_headers,"Set-Cookie: ");
-       while (cookie_itt) {
-               char *end_pos, *cookie;
-               char *eqpos, *sempos;
-               smart_str name = {0}, value = {0};
-               zval **cookies, *z_cookie;
-
-               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 (cookie_itt &&
+                 zend_hash_find(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl"), (void **)&tmp) == SUCCESS) {
+
+         php_url *phpurl = (php_url*)zend_fetch_resource(tmp TSRMLS_CC, -1, "httpurl", NULL, 1, le_url);
+
+         if (phpurl) {
+                       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);
+                               }
 
-               end_pos = strstr(cookie_itt,"\r\n");
-               cookie = get_http_header_value(cookie_itt,"Set-Cookie: ");
+                               end_pos = strstr(cookie_itt,"\r\n");
+                               cookie = get_http_header_value(cookie_itt,"Set-Cookie: ");
+
+                               eqpos = strstr(cookie, "=");
+                               sempos = strstr(cookie, ";");
+                               if (eqpos != NULL && (sempos == NULL || sempos > eqpos)) {
+                                       smart_str name = {0};
+                                       int cookie_len;
+                                       zval *zcookie;
+
+                                       if (sempos != NULL) {
+                                               cookie_len = sempos-(eqpos+1);
+                                       } else {
+                                               cookie_len = strlen(cookie)-(eqpos-cookie)-1;
+                                       }
+
+                                       smart_str_appendl(&name, cookie, eqpos - cookie);
+                                       smart_str_0(&name);
+
+                                       ALLOC_INIT_ZVAL(zcookie);
+                                       array_init(zcookie);
+                                       add_index_stringl(zcookie, 0, eqpos + 1, cookie_len, 1);
+
+                                       if (sempos != NULL) {
+                                               char *options = cookie + cookie_len+1;
+                                               while (*options) {
+                                                       while (*options == ' ') {options++;}
+                                                       sempos = strstr(options, ";");
+                                                       if (strstr(options,"path=") == options) {
+                                                               eqpos = options + sizeof("path=")-1;
+                                                               add_index_stringl(zcookie, 1, eqpos, sempos?(sempos-eqpos):strlen(eqpos), 1);
+                                                       } else if (strstr(options,"domain=") == options) {
+                                                               eqpos = options + sizeof("domain=")-1;
+                                                               add_index_stringl(zcookie, 2, eqpos, sempos?(sempos-eqpos):strlen(eqpos), 1);
+                                                       } else if (strstr(options,"secure") == options) {
+                                                               add_index_bool(zcookie, 3, 1);
+                                                       }
+                                                       if (sempos != NULL) {
+                                                               options = sempos+1;
+                                                       } else {
+                                                         break;
+                                                       }
+                                               }
+                                       }
+               if (!zend_hash_index_exists(Z_ARRVAL_P(zcookie), 1)) {
+                 char *c = strrchr(phpurl->path, '/');
+                 if (c) {
+                                                       add_index_stringl(zcookie, 1, phpurl->path, c-phpurl->path, 1);
+                                               }
+               }
+               if (!zend_hash_index_exists(Z_ARRVAL_P(zcookie), 2)) {
+                                               add_index_string(zcookie, 2, phpurl->host, 1);
+               }
 
-               eqpos = strstr(cookie, "=");
-               sempos = strstr(cookie, ";");
-               if (eqpos != NULL && (sempos == NULL || sempos > eqpos)) {
-                       int cookie_len;
+                                       add_assoc_zval_ex(*cookies, name.c, name.len+1, zcookie);
+                                       smart_str_free(&name);
+                               }
 
-                       if (sempos != NULL) {
-                               cookie_len = sempos-(eqpos+1);
-                       } else {
-                               cookie_len = strlen(cookie)-(eqpos-cookie)-1;
+                               cookie_itt = strstr(cookie_itt + sizeof("Set-Cookie: "), "Set-Cookie: ");
+                               efree(cookie);
                        }
-
-                       smart_str_appendl(&name, cookie, eqpos - cookie);
-                       smart_str_0(&name);
-
-                       smart_str_appendl(&value, eqpos + 1, cookie_len);
-                       smart_str_0(&value);
-
-                       MAKE_STD_ZVAL(z_cookie);
-                       ZVAL_STRINGL(z_cookie, value.c, value.len, 1);
-
-                       zend_hash_update(Z_ARRVAL_PP(cookies), name.c, name.len + 1, &z_cookie, sizeof(zval *), NULL);
                }
-
-               cookie_itt = strstr(cookie_itt + sizeof("Set-Cookie: "), "Set-Cookie: ");
-
-               smart_str_free(&value);
-               smart_str_free(&name);
-               efree(cookie);
        }
 
        content_encoding = get_http_header_value(http_headers,"Content-Encoding: ");
index 1ccbfd59514ec592a73062ecccf6215569a6dfd7..2eeba6be9f59fcf421506a4fa59cc28b649e27e0 100644 (file)
@@ -47,6 +47,8 @@
 # define stricmp strcasecmp
 #endif
 
+extern int le_url;
+
 typedef struct _encodeType encodeType, *encodeTypePtr;
 typedef struct _encode encode, *encodePtr;
 
index 0a0289709fa1daffdfd56e0a57dfa68eeaee9e39..9e38e0b2052da8bbb79ae3876beff023cc23de2d 100644 (file)
@@ -29,7 +29,7 @@
 #endif
 
 static int le_sdl = 0;
-static int le_url = 0;
+int le_url = 0;
 static int le_service = 0;
 
 typedef struct _soapHeader {
@@ -230,6 +230,8 @@ PHP_METHOD(SoapClient, SoapClient);
 PHP_METHOD(SoapClient, __call);
 PHP_METHOD(SoapClient, __getLastRequest);
 PHP_METHOD(SoapClient, __getLastResponse);
+PHP_METHOD(SoapClient, __getLastRequestHeaders);
+PHP_METHOD(SoapClient, __getLastResponseHeaders);
 PHP_METHOD(SoapClient, __getFunctions);
 PHP_METHOD(SoapClient, __getTypes);
 
@@ -297,6 +299,8 @@ static zend_function_entry soap_client_functions[] = {
        PHP_ME(SoapClient, __call, __call_args, 0)
        PHP_ME(SoapClient, __getLastRequest, NULL, 0)
        PHP_ME(SoapClient, __getLastResponse, NULL, 0)
+       PHP_ME(SoapClient, __getLastRequestHeaders, NULL, 0)
+       PHP_ME(SoapClient, __getLastResponseHeaders, NULL, 0)
        PHP_ME(SoapClient, __getFunctions, NULL, 0)
        PHP_ME(SoapClient, __getTypes, NULL, 0)
        {NULL, NULL, NULL}
@@ -1345,7 +1349,7 @@ PHP_METHOD(SoapServer, handle)
                        /* Find the soap object and assign */
                        if (zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), "_bogus_session_name", sizeof("_bogus_session_name"), (void **) &tmp_soap) == SUCCESS &&
                            Z_TYPE_PP(tmp_soap) == IS_OBJECT &&
-                           Z_OBJCE_PP(tmp_soap) == service->soap_class.ce) {                           
+                           Z_OBJCE_PP(tmp_soap) == service->soap_class.ce) {
                                soap_obj = *tmp_soap;
                        }
                }
@@ -1382,7 +1386,7 @@ PHP_METHOD(SoapServer, handle)
                        } else {
 #else
       {
-#endif 
+#endif
                                int class_name_len = strlen(service->soap_class.ce->name);
                                char *class_name = emalloc(class_name_len+1);
 
@@ -2190,6 +2194,26 @@ PHP_METHOD(SoapClient, __getLastResponse)
        RETURN_NULL();
 }
 
+PHP_METHOD(SoapClient, __getLastRequestHeaders)
+{
+       zval **tmp;
+
+       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__last_request_headers", sizeof("__last_request_headers"), (void **)&tmp) == SUCCESS) {
+               RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+       }
+       RETURN_NULL();
+}
+
+PHP_METHOD(SoapClient, __getLastResponseHeaders)
+{
+       zval **tmp;
+
+       if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__last_response_headers", sizeof("__last_response_headers"), (void **)&tmp) == SUCCESS) {
+               RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
+       }
+       RETURN_NULL();
+}
+
 #ifndef ZEND_ENGINE_2
 static void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
 {