From: Dmitry Stogov Date: Fri, 2 Apr 2004 11:12:44 +0000 (+0000) Subject: SoapClint support for multiple hosts (through WSDL) with cookies. X-Git-Tag: php-5.0.0RC2RC1~114 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6f6ef6deed7446a19e6f815f95fdebc24eaca505;p=php SoapClint support for multiple hosts (through WSDL) with cookies. --- diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index a8c07948d6..08068e3814 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -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: "); diff --git a/ext/soap/php_soap.h b/ext/soap/php_soap.h index 1ccbfd5951..2eeba6be9f 100644 --- a/ext/soap/php_soap.h +++ b/ext/soap/php_soap.h @@ -47,6 +47,8 @@ # define stricmp strcasecmp #endif +extern int le_url; + typedef struct _encodeType encodeType, *encodeTypePtr; typedef struct _encode encode, *encodePtr; diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 0a0289709f..9e38e0b205 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -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) {