Skip to content

Commit c525e29

Browse files
committed
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.
1 parent f27090c commit c525e29

File tree

3 files changed

+130
-10
lines changed

3 files changed

+130
-10
lines changed

ext/soap/php_http.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,8 @@ int make_http_soap_request(zval *this_ptr,
532532
}
533533
PG(allow_url_fopen) = old_allow_url_fopen;
534534

535+
bool client_trace = Z_TYPE_P(Z_CLIENT_TRACE_P(this_ptr)) == IS_TRUE;
536+
535537
if (stream) {
536538
zval *cookies, *login, *password;
537539
zend_resource *ret = zend_register_resource(phpurl, le_url);
@@ -863,7 +865,7 @@ int make_http_soap_request(zval *this_ptr,
863865

864866
smart_str_append_const(&soap_headers, "\r\n");
865867
smart_str_0(&soap_headers);
866-
if (Z_TYPE_P(Z_CLIENT_TRACE_P(this_ptr)) == IS_TRUE) {
868+
if (client_trace) {
867869
zval_ptr_dtor(Z_CLIENT_LAST_REQUEST_HEADERS_P(this_ptr));
868870
/* Need to copy the string here, as we continue appending to soap_headers below. */
869871
ZVAL_STRINGL(Z_CLIENT_LAST_REQUEST_HEADERS_P(this_ptr),
@@ -892,14 +894,8 @@ int make_http_soap_request(zval *this_ptr,
892894
return FALSE;
893895
}
894896

895-
if (!return_value) {
896-
php_stream_close(stream);
897-
convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr));
898-
convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr));
899-
smart_str_free(&soap_headers_z);
900-
return TRUE;
901-
}
902-
897+
http_headers = NULL;
898+
if (return_value || client_trace) {
903899
do {
904900
http_headers = get_http_headers(stream);
905901
if (!http_headers) {
@@ -914,7 +910,7 @@ int make_http_soap_request(zval *this_ptr,
914910
return FALSE;
915911
}
916912

917-
if (Z_TYPE_P(Z_CLIENT_TRACE_P(this_ptr)) == IS_TRUE) {
913+
if (client_trace) {
918914
zval_ptr_dtor(Z_CLIENT_LAST_RESPONSE_HEADERS_P(this_ptr));
919915
ZVAL_STR_COPY(Z_CLIENT_LAST_RESPONSE_HEADERS_P(this_ptr), http_headers);
920916
}
@@ -951,6 +947,25 @@ int make_http_soap_request(zval *this_ptr,
951947
}
952948
}
953949
} while (http_status == 100);
950+
}
951+
952+
if (!return_value) {
953+
/* In this case, the headers were only fetched because client_trace was true. */
954+
if (request != buf) {
955+
zend_string_release_ex(request, 0);
956+
}
957+
php_stream_close(stream);
958+
if (http_headers) {
959+
zend_string_release_ex(http_headers, 0);
960+
}
961+
convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr));
962+
convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr));
963+
if (http_msg) {
964+
efree(http_msg);
965+
}
966+
smart_str_free(&soap_headers_z);
967+
return true;
968+
}
954969

955970
/* Grab and send back every cookie */
956971

ext/soap/tests/bugs/bug49278.phpt

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
--TEST--
2+
Bug #49278 (SoapClient::__getLastResponseHeaders returns NULL if wsdl operation !has output)
3+
--EXTENSIONS--
4+
soap
5+
--INI--
6+
soap.wsdl_cache_enabled=0
7+
--SKIPIF--
8+
<?php
9+
if (!file_exists(__DIR__ . "/../../../../sapi/cli/tests/php_cli_server.inc")) {
10+
echo "skip sapi/cli/tests/php_cli_server.inc required but not found";
11+
}
12+
?>
13+
--FILE--
14+
<?php
15+
16+
include __DIR__ . "/../../../../sapi/cli/tests/php_cli_server.inc";
17+
18+
$args = ["-d", "extension_dir=" . ini_get("extension_dir"), "-d", "extension=" . (substr(PHP_OS, 0, 3) == "WIN" ? "php_" : "") . "soap." . PHP_SHLIB_SUFFIX];
19+
if (php_ini_loaded_file()) {
20+
// Necessary such that it works from a development directory in which case extension_dir might not be the real extension dir
21+
$args[] = "-c";
22+
$args[] = php_ini_loaded_file();
23+
}
24+
$code = '$server = new SoapServer("' . __DIR__ . '"/bug49278.wsdl", ["trace"=>1]);' .
25+
<<<'PHP'
26+
function Add() {}
27+
$server->addFunction('Add');
28+
$server->handle();
29+
PHP;
30+
31+
php_cli_server_start($code, null, $args);
32+
33+
$client = new SoapClient(__DIR__ . '/bug49278.wsdl', array('location' => "http://".PHP_CLI_SERVER_ADDRESS, 'trace' => 1));
34+
$client->Add();
35+
var_dump($client->__getLastResponse());
36+
var_dump($client->__getLastResponse());
37+
var_dump($client->__getLastRequestHeaders());
38+
var_dump($client->__getLastResponseHeaders());
39+
40+
?>
41+
--EXPECTF--
42+
string(0) ""
43+
string(0) ""
44+
string(177) "POST / HTTP/1.1
45+
Host: %s
46+
Connection: Keep-Alive
47+
User-Agent: PHP-SOAP/8.4.0-dev
48+
Content-Type: text/xml; charset=utf-8
49+
SOAPAction: "Add"
50+
Content-Length: %d
51+
52+
"
53+
string(165) "HTTP/1.1 200 OK
54+
Host: %s
55+
Date: %s
56+
Connection: close
57+
X-Powered-By: PHP/8.4.0-dev
58+
Content-type: text/html; charset=UTF-8
59+
"

ext/soap/tests/bugs/bug49278.wsdl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0" ?>
2+
<definitions
3+
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
4+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
5+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6+
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
7+
xmlns:si="http://soapinterop.org/xsd"
8+
xmlns:tns="http://linuxsrv.home/~dmitry/soap/test.wsdl"
9+
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
10+
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
11+
xmlns="http://schemas.xmlsoap.org/wsdl/"
12+
targetNamespace="http://linuxsrv.home/~dmitry/soap/test.wsdl">
13+
14+
<types>
15+
<xsd:schema targetNamespace="http://linuxsrv.home/~dmitry/soap/test.wsdl">
16+
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
17+
<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
18+
</xsd:schema>
19+
</types>
20+
21+
<message name="AddRequest"/>
22+
<message name="AddResponse"/>
23+
24+
<portType name="TestServicePortType">
25+
<operation name="Add">
26+
<input message="tns:AddRequest" />
27+
</operation>
28+
</portType>
29+
30+
<binding name="TestServiceBinding" type="tns:TestServicePortType">
31+
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
32+
<operation name="Add">
33+
<soap:operation soapAction="Add" style="rpc" />
34+
<input>
35+
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
36+
</input>
37+
</operation>
38+
</binding>
39+
40+
<service name="TestService">
41+
<port name="TestServicePort" binding="tns:TestServiceBinding">
42+
<soap:address location="http://linuxsrv.home/~dmitry/soap/soap_server.php" />
43+
</port>
44+
</service>
45+
46+
</definitions>

0 commit comments

Comments
 (0)