diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c
index 944b033363c6..c7f3732f2987 100644
--- a/ext/soap/php_http.c
+++ b/ext/soap/php_http.c
@@ -1162,12 +1162,12 @@ int make_http_soap_request(
zend_string_release_ex(http_headers, 0);
zend_string_release_ex(http_body, 0);
if (new_uri->scheme == NULL && new_uri->path != NULL) {
- new_uri->scheme = new_uri->scheme ? zend_string_copy(new_uri->scheme) : NULL;
- new_uri->host = new_uri->host ? zend_string_copy(new_uri->host) : NULL;
- new_uri->port = new_uri->port;
+ new_uri->scheme = uri->scheme ? zend_string_copy(uri->scheme) : NULL;
+ new_uri->host = uri->host ? zend_string_copy(uri->host) : NULL;
+ new_uri->port = uri->port;
if (new_uri->path && ZSTR_VAL(new_uri->path)[0] != '/') {
- if (new_uri->path) {
- char *t = ZSTR_VAL(new_uri->path);
+ if (uri->path) {
+ char *t = ZSTR_VAL(uri->path);
char *p = strrchr(t, '/');
if (p) {
zend_string *s = zend_string_alloc((p - t) + ZSTR_LEN(new_uri->path) + 2, 0);
diff --git a/ext/soap/tests/bugs/relative_redirect.phpt b/ext/soap/tests/bugs/relative_redirect.phpt
new file mode 100644
index 000000000000..774e7cbd98d7
--- /dev/null
+++ b/ext/soap/tests/bugs/relative_redirect.phpt
@@ -0,0 +1,49 @@
+--TEST--
+SOAP client follows a redirect with a scheme-less (relative) Location
+--EXTENSIONS--
+soap
+--SKIPIF--
+
+--FILE--
+',
+ '',
+ 'ok',
+ '';
+} else {
+ http_response_code(302);
+ header("Location: /redirected");
+}
+PHP;
+
+php_cli_server_start($code, null, $args);
+
+$client = new SoapClient(null, [
+ 'location' => 'http://' . PHP_CLI_SERVER_ADDRESS . '/start',
+ 'uri' => 'test-uri',
+]);
+
+try {
+ $client->__soapCall("foo", []);
+ echo "redirect followed\n";
+} catch (SoapFault $e) {
+ echo "SoapFault: " . $e->getMessage() . "\n";
+}
+?>
+--EXPECT--
+redirect followed
diff --git a/ext/soap/tests/bugs/relative_redirect_path.phpt b/ext/soap/tests/bugs/relative_redirect_path.phpt
new file mode 100644
index 000000000000..09d4c857cc92
--- /dev/null
+++ b/ext/soap/tests/bugs/relative_redirect_path.phpt
@@ -0,0 +1,49 @@
+--TEST--
+SOAP client follows a redirect with a relative Location resolved against the request path
+--EXTENSIONS--
+soap
+--SKIPIF--
+
+--FILE--
+',
+ '',
+ 'ok',
+ '';
+} else {
+ http_response_code(302);
+ header("Location: redirected");
+}
+PHP;
+
+php_cli_server_start($code, null, $args);
+
+$client = new SoapClient(null, [
+ 'location' => 'http://' . PHP_CLI_SERVER_ADDRESS . '/svc/start',
+ 'uri' => 'test-uri',
+]);
+
+try {
+ $client->__soapCall("foo", []);
+ echo "redirect followed\n";
+} catch (SoapFault $e) {
+ echo "SoapFault: " . $e->getMessage() . "\n";
+}
+?>
+--EXPECT--
+redirect followed