mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix #49278: SoapClient::__getLastResponseHeaders returns NULL if wsdl operation !has output
Instead of early exiting, process the headers if tracing is enabled, and exit after that. Closes GH-12609.
This commit is contained in:
2
NEWS
2
NEWS
@@ -46,6 +46,8 @@ SOAP:
|
||||
. Add support for clark notation for namespaces in class map. (lxShaDoWxl)
|
||||
. Mitigate #51561 (SoapServer with a extented class and using sessions,
|
||||
lost the setPersistence()). (nielsdos)
|
||||
. Fixed bug #49278 (SoapClient::__getLastResponseHeaders returns NULL if
|
||||
wsdl operation !has output). (nielsdos)
|
||||
|
||||
Sockets:
|
||||
. Removed the deprecated inet_ntoa call support. (David Carlier)
|
||||
|
||||
@@ -532,6 +532,8 @@ try_again:
|
||||
}
|
||||
PG(allow_url_fopen) = old_allow_url_fopen;
|
||||
|
||||
bool client_trace = Z_TYPE_P(Z_CLIENT_TRACE_P(this_ptr)) == IS_TRUE;
|
||||
|
||||
if (stream) {
|
||||
zval *cookies, *login, *password;
|
||||
zend_resource *ret = zend_register_resource(phpurl, le_url);
|
||||
@@ -863,7 +865,7 @@ try_again:
|
||||
|
||||
smart_str_append_const(&soap_headers, "\r\n");
|
||||
smart_str_0(&soap_headers);
|
||||
if (Z_TYPE_P(Z_CLIENT_TRACE_P(this_ptr)) == IS_TRUE) {
|
||||
if (client_trace) {
|
||||
zval_ptr_dtor(Z_CLIENT_LAST_REQUEST_HEADERS_P(this_ptr));
|
||||
/* Need to copy the string here, as we continue appending to soap_headers below. */
|
||||
ZVAL_STRINGL(Z_CLIENT_LAST_REQUEST_HEADERS_P(this_ptr),
|
||||
@@ -892,65 +894,78 @@ try_again:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!return_value) {
|
||||
php_stream_close(stream);
|
||||
convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr));
|
||||
convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr));
|
||||
smart_str_free(&soap_headers_z);
|
||||
return TRUE;
|
||||
http_headers = NULL;
|
||||
if (return_value || client_trace) {
|
||||
do {
|
||||
http_headers = get_http_headers(stream);
|
||||
if (!http_headers) {
|
||||
if (request != buf) {
|
||||
zend_string_release_ex(request, 0);
|
||||
}
|
||||
php_stream_close(stream);
|
||||
convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr));
|
||||
convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr));
|
||||
add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL);
|
||||
smart_str_free(&soap_headers_z);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (client_trace) {
|
||||
zval_ptr_dtor(Z_CLIENT_LAST_RESPONSE_HEADERS_P(this_ptr));
|
||||
ZVAL_STR_COPY(Z_CLIENT_LAST_RESPONSE_HEADERS_P(this_ptr), http_headers);
|
||||
}
|
||||
|
||||
/* Check to see what HTTP status was sent */
|
||||
http_1_1 = 0;
|
||||
http_status = 0;
|
||||
http_version = get_http_header_value(ZSTR_VAL(http_headers), "HTTP/");
|
||||
if (http_version) {
|
||||
char *tmp;
|
||||
|
||||
if (!strncmp(http_version,"1.1", 3)) {
|
||||
http_1_1 = 1;
|
||||
}
|
||||
|
||||
tmp = strstr(http_version," ");
|
||||
if (tmp != NULL) {
|
||||
tmp++;
|
||||
http_status = atoi(tmp);
|
||||
}
|
||||
tmp = strstr(tmp," ");
|
||||
if (tmp != NULL) {
|
||||
tmp++;
|
||||
if (http_msg) {
|
||||
efree(http_msg);
|
||||
}
|
||||
http_msg = estrdup(tmp);
|
||||
}
|
||||
efree(http_version);
|
||||
|
||||
/* Try and get headers again */
|
||||
if (http_status == 100) {
|
||||
zend_string_release_ex(http_headers, 0);
|
||||
}
|
||||
}
|
||||
} while (http_status == 100);
|
||||
}
|
||||
|
||||
do {
|
||||
http_headers = get_http_headers(stream);
|
||||
if (!http_headers) {
|
||||
if (request != buf) {
|
||||
zend_string_release_ex(request, 0);
|
||||
}
|
||||
php_stream_close(stream);
|
||||
convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr));
|
||||
convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr));
|
||||
add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL);
|
||||
smart_str_free(&soap_headers_z);
|
||||
return FALSE;
|
||||
if (!return_value) {
|
||||
/* In this case, the headers were only fetched because client_trace was true. */
|
||||
if (request != buf) {
|
||||
zend_string_release_ex(request, 0);
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(Z_CLIENT_TRACE_P(this_ptr)) == IS_TRUE) {
|
||||
zval_ptr_dtor(Z_CLIENT_LAST_RESPONSE_HEADERS_P(this_ptr));
|
||||
ZVAL_STR_COPY(Z_CLIENT_LAST_RESPONSE_HEADERS_P(this_ptr), http_headers);
|
||||
php_stream_close(stream);
|
||||
if (http_headers) {
|
||||
zend_string_release_ex(http_headers, 0);
|
||||
}
|
||||
|
||||
/* Check to see what HTTP status was sent */
|
||||
http_1_1 = 0;
|
||||
http_status = 0;
|
||||
http_version = get_http_header_value(ZSTR_VAL(http_headers), "HTTP/");
|
||||
if (http_version) {
|
||||
char *tmp;
|
||||
|
||||
if (!strncmp(http_version,"1.1", 3)) {
|
||||
http_1_1 = 1;
|
||||
}
|
||||
|
||||
tmp = strstr(http_version," ");
|
||||
if (tmp != NULL) {
|
||||
tmp++;
|
||||
http_status = atoi(tmp);
|
||||
}
|
||||
tmp = strstr(tmp," ");
|
||||
if (tmp != NULL) {
|
||||
tmp++;
|
||||
if (http_msg) {
|
||||
efree(http_msg);
|
||||
}
|
||||
http_msg = estrdup(tmp);
|
||||
}
|
||||
efree(http_version);
|
||||
|
||||
/* Try and get headers again */
|
||||
if (http_status == 100) {
|
||||
zend_string_release_ex(http_headers, 0);
|
||||
}
|
||||
convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr));
|
||||
convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr));
|
||||
if (http_msg) {
|
||||
efree(http_msg);
|
||||
}
|
||||
} while (http_status == 100);
|
||||
smart_str_free(&soap_headers_z);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Grab and send back every cookie */
|
||||
|
||||
|
||||
59
ext/soap/tests/bugs/bug49278.phpt
Normal file
59
ext/soap/tests/bugs/bug49278.phpt
Normal file
@@ -0,0 +1,59 @@
|
||||
--TEST--
|
||||
Bug #49278 (SoapClient::__getLastResponseHeaders returns NULL if wsdl operation !has output)
|
||||
--EXTENSIONS--
|
||||
soap
|
||||
--INI--
|
||||
soap.wsdl_cache_enabled=0
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!file_exists(__DIR__ . "/../../../../sapi/cli/tests/php_cli_server.inc")) {
|
||||
echo "skip sapi/cli/tests/php_cli_server.inc required but not found";
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include __DIR__ . "/../../../../sapi/cli/tests/php_cli_server.inc";
|
||||
|
||||
$args = ["-d", "extension_dir=" . ini_get("extension_dir"), "-d", "extension=" . (substr(PHP_OS, 0, 3) == "WIN" ? "php_" : "") . "soap." . PHP_SHLIB_SUFFIX];
|
||||
if (php_ini_loaded_file()) {
|
||||
// Necessary such that it works from a development directory in which case extension_dir might not be the real extension dir
|
||||
$args[] = "-c";
|
||||
$args[] = php_ini_loaded_file();
|
||||
}
|
||||
$code = '$server = new SoapServer("' . __DIR__ . '"/bug49278.wsdl", ["trace"=>1]);' .
|
||||
<<<'PHP'
|
||||
function Add() {}
|
||||
$server->addFunction('Add');
|
||||
$server->handle();
|
||||
PHP;
|
||||
|
||||
php_cli_server_start($code, null, $args);
|
||||
|
||||
$client = new SoapClient(__DIR__ . '/bug49278.wsdl', array('location' => "http://".PHP_CLI_SERVER_ADDRESS, 'trace' => 1));
|
||||
$client->Add();
|
||||
var_dump($client->__getLastResponse());
|
||||
var_dump($client->__getLastResponse());
|
||||
var_dump($client->__getLastRequestHeaders());
|
||||
var_dump($client->__getLastResponseHeaders());
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(0) ""
|
||||
string(0) ""
|
||||
string(177) "POST / HTTP/1.1
|
||||
Host: %s
|
||||
Connection: Keep-Alive
|
||||
User-Agent: PHP-SOAP/8.4.0-dev
|
||||
Content-Type: text/xml; charset=utf-8
|
||||
SOAPAction: "Add"
|
||||
Content-Length: %d
|
||||
|
||||
"
|
||||
string(165) "HTTP/1.1 200 OK
|
||||
Host: %s
|
||||
Date: %s
|
||||
Connection: close
|
||||
X-Powered-By: PHP/8.4.0-dev
|
||||
Content-type: text/html; charset=UTF-8
|
||||
"
|
||||
46
ext/soap/tests/bugs/bug49278.wsdl
Normal file
46
ext/soap/tests/bugs/bug49278.wsdl
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" ?>
|
||||
<definitions
|
||||
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:si="http://soapinterop.org/xsd"
|
||||
xmlns:tns="http://linuxsrv.home/~dmitry/soap/test.wsdl"
|
||||
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
xmlns="http://schemas.xmlsoap.org/wsdl/"
|
||||
targetNamespace="http://linuxsrv.home/~dmitry/soap/test.wsdl">
|
||||
|
||||
<types>
|
||||
<xsd:schema targetNamespace="http://linuxsrv.home/~dmitry/soap/test.wsdl">
|
||||
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
|
||||
<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
|
||||
</xsd:schema>
|
||||
</types>
|
||||
|
||||
<message name="AddRequest"/>
|
||||
<message name="AddResponse"/>
|
||||
|
||||
<portType name="TestServicePortType">
|
||||
<operation name="Add">
|
||||
<input message="tns:AddRequest" />
|
||||
</operation>
|
||||
</portType>
|
||||
|
||||
<binding name="TestServiceBinding" type="tns:TestServicePortType">
|
||||
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
|
||||
<operation name="Add">
|
||||
<soap:operation soapAction="Add" style="rpc" />
|
||||
<input>
|
||||
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
|
||||
</input>
|
||||
</operation>
|
||||
</binding>
|
||||
|
||||
<service name="TestService">
|
||||
<port name="TestServicePort" binding="tns:TestServiceBinding">
|
||||
<soap:address location="http://linuxsrv.home/~dmitry/soap/soap_server.php" />
|
||||
</port>
|
||||
</service>
|
||||
|
||||
</definitions>
|
||||
Reference in New Issue
Block a user