Skip to content

Commit 581d510

Browse files
committed
Fix SOAP client failing to follow a scheme-less redirect Location
The HTTP redirect handler inherited scheme, host and port from the newly parsed Location URI itself instead of the previous request URI, so a scheme-less (relative or absolute-path) Location left the host NULL and the retry aborted with "Unable to parse URL". Read the inherited components and the path base from the request URI, restoring the behaviour the URI-parser refactor changed. Closes GH-22341
1 parent 15cbd82 commit 581d510

2 files changed

Lines changed: 54 additions & 5 deletions

File tree

ext/soap/php_http.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,12 +1162,12 @@ int make_http_soap_request(
11621162
zend_string_release_ex(http_headers, 0);
11631163
zend_string_release_ex(http_body, 0);
11641164
if (new_uri->scheme == NULL && new_uri->path != NULL) {
1165-
new_uri->scheme = new_uri->scheme ? zend_string_copy(new_uri->scheme) : NULL;
1166-
new_uri->host = new_uri->host ? zend_string_copy(new_uri->host) : NULL;
1167-
new_uri->port = new_uri->port;
1165+
new_uri->scheme = uri->scheme ? zend_string_copy(uri->scheme) : NULL;
1166+
new_uri->host = uri->host ? zend_string_copy(uri->host) : NULL;
1167+
new_uri->port = uri->port;
11681168
if (new_uri->path && ZSTR_VAL(new_uri->path)[0] != '/') {
1169-
if (new_uri->path) {
1170-
char *t = ZSTR_VAL(new_uri->path);
1169+
if (uri->path) {
1170+
char *t = ZSTR_VAL(uri->path);
11711171
char *p = strrchr(t, '/');
11721172
if (p) {
11731173
zend_string *s = zend_string_alloc((p - t) + ZSTR_LEN(new_uri->path) + 2, 0);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
--TEST--
2+
SOAP client follows a redirect with a scheme-less (relative) Location
3+
--EXTENSIONS--
4+
soap
5+
--SKIPIF--
6+
<?php
7+
if (!file_exists(__DIR__ . "/../../../../sapi/cli/tests/php_cli_server.inc")) {
8+
echo "skip sapi/cli/tests/php_cli_server.inc required but not found";
9+
}
10+
?>
11+
--FILE--
12+
<?php
13+
include __DIR__ . "/../../../../sapi/cli/tests/php_cli_server.inc";
14+
15+
$args = ["-d", "extension_dir=" . ini_get("extension_dir"), "-d", "extension=" . (substr(PHP_OS, 0, 3) == "WIN" ? "php_" : "") . "soap." . PHP_SHLIB_SUFFIX];
16+
if (php_ini_loaded_file()) {
17+
$args[] = "-c";
18+
$args[] = php_ini_loaded_file();
19+
}
20+
21+
$code = <<<'PHP'
22+
if ($_SERVER["REQUEST_URI"] === "/redirected") {
23+
header("Content-Type: text/xml; charset=utf-8");
24+
echo '<?xml version="1.0" encoding="UTF-8"?>',
25+
'<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">',
26+
'<SOAP-ENV:Body><fooResponse><result>ok</result></fooResponse></SOAP-ENV:Body>',
27+
'</SOAP-ENV:Envelope>';
28+
} else {
29+
http_response_code(302);
30+
header("Location: /redirected");
31+
}
32+
PHP;
33+
34+
php_cli_server_start($code, null, $args);
35+
36+
$client = new SoapClient(null, [
37+
'location' => 'http://' . PHP_CLI_SERVER_ADDRESS . '/start',
38+
'uri' => 'test-uri',
39+
]);
40+
41+
try {
42+
$client->__soapCall("foo", []);
43+
echo "redirect followed\n";
44+
} catch (SoapFault $e) {
45+
echo "SoapFault: " . $e->getMessage() . "\n";
46+
}
47+
?>
48+
--EXPECT--
49+
redirect followed

0 commit comments

Comments
 (0)