Skip to content

Commit 7771ec0

Browse files
committed
Fix bug #61525: SOAP functions require at least one space after HTTP header colon
HTTP/1.1 does not require a single whitespace after the colon, and SoapServer does implement HTTP/1.1. The header value is already correctly whitespace-trimmed, so no behaviour change happens w.r.t. header values. Closes GH-15793.
1 parent 0f3b2e5 commit 7771ec0

File tree

3 files changed

+49
-12
lines changed

3 files changed

+49
-12
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ PHP NEWS
4949
. Fixed bug GH-15718 (Segfault on ReflectionProperty::get{Hook,Hooks}() on
5050
dynamic properties). (DanielEScherzer)
5151

52+
- SOAP:
53+
. Fixed bug #61525 (SOAP functions require at least one space after HTTP
54+
header colon). (nielsdos)
55+
5256
- Standard:
5357
. Fixed bug GH-15552 (Signed integer overflow in ext/standard/scanf.c). (cmb)
5458
. Implemented GH-15685 (improve proc_open error reporting on Windows). (cmb)

ext/soap/php_http.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ int make_http_soap_request(zval *this_ptr,
980980
*/
981981
cookie_itt = ZSTR_VAL(http_headers);
982982

983-
while ((cookie_itt = get_http_header_value_nodup(cookie_itt, "Set-Cookie: ", &cookie_len))) {
983+
while ((cookie_itt = get_http_header_value_nodup(cookie_itt, "Set-Cookie:", &cookie_len))) {
984984
zval *cookies = Z_CLIENT_COOKIES_P(this_ptr);
985985
SEPARATE_ARRAY(cookies);
986986

@@ -1049,7 +1049,7 @@ int make_http_soap_request(zval *this_ptr,
10491049
if (http_1_1) {
10501050
http_close = FALSE;
10511051
if (use_proxy && !use_ssl) {
1052-
connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection: ");
1052+
connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection:");
10531053
if (connection) {
10541054
if (strncasecmp(connection, "close", sizeof("close")-1) == 0) {
10551055
http_close = TRUE;
@@ -1058,7 +1058,7 @@ int make_http_soap_request(zval *this_ptr,
10581058
}
10591059
}
10601060
if (http_close == FALSE) {
1061-
connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection: ");
1061+
connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection:");
10621062
if (connection) {
10631063
if (strncasecmp(connection, "close", sizeof("close")-1) == 0) {
10641064
http_close = TRUE;
@@ -1069,7 +1069,7 @@ int make_http_soap_request(zval *this_ptr,
10691069
} else {
10701070
http_close = TRUE;
10711071
if (use_proxy && !use_ssl) {
1072-
connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection: ");
1072+
connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection:");
10731073
if (connection) {
10741074
if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) {
10751075
http_close = FALSE;
@@ -1078,7 +1078,7 @@ int make_http_soap_request(zval *this_ptr,
10781078
}
10791079
}
10801080
if (http_close == TRUE) {
1081-
connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection: ");
1081+
connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection:");
10821082
if (connection) {
10831083
if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) {
10841084
http_close = FALSE;
@@ -1121,7 +1121,7 @@ int make_http_soap_request(zval *this_ptr,
11211121
if (http_status >= 300 && http_status < 400) {
11221122
char *loc;
11231123

1124-
if ((loc = get_http_header_value(ZSTR_VAL(http_headers), "Location: ")) != NULL) {
1124+
if ((loc = get_http_header_value(ZSTR_VAL(http_headers), "Location:")) != NULL) {
11251125
php_url *new_url = php_url_parse(loc);
11261126

11271127
if (new_url != NULL) {
@@ -1170,7 +1170,7 @@ int make_http_soap_request(zval *this_ptr,
11701170
zval *digest = Z_CLIENT_DIGEST_P(this_ptr);
11711171
zval *login = Z_CLIENT_LOGIN_P(this_ptr);
11721172
zval *password = Z_CLIENT_PASSWORD_P(this_ptr);
1173-
char *auth = get_http_header_value(ZSTR_VAL(http_headers), "WWW-Authenticate: ");
1173+
char *auth = get_http_header_value(ZSTR_VAL(http_headers), "WWW-Authenticate:");
11741174
if (auth && strstr(auth, "Digest") == auth && Z_TYPE_P(digest) != IS_ARRAY
11751175
&& Z_TYPE_P(login) == IS_STRING && Z_TYPE_P(password) == IS_STRING) {
11761176
char *s;
@@ -1240,7 +1240,7 @@ int make_http_soap_request(zval *this_ptr,
12401240
smart_str_free(&soap_headers_z);
12411241

12421242
/* Check and see if the server even sent a xml document */
1243-
content_type = get_http_header_value(ZSTR_VAL(http_headers), "Content-Type: ");
1243+
content_type = get_http_header_value(ZSTR_VAL(http_headers), "Content-Type:");
12441244
if (content_type) {
12451245
char *pos = NULL;
12461246
int cmplen;
@@ -1270,7 +1270,7 @@ int make_http_soap_request(zval *this_ptr,
12701270
}
12711271

12721272
/* Decompress response */
1273-
content_encoding = get_http_header_value(ZSTR_VAL(http_headers), "Content-Encoding: ");
1273+
content_encoding = get_http_header_value(ZSTR_VAL(http_headers), "Content-Encoding:");
12741274
if (content_encoding) {
12751275
zval func;
12761276
zval retval;
@@ -1430,18 +1430,18 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers)
14301430
int header_close = close, header_chunked = 0, header_length = 0, http_buf_size = 0;
14311431

14321432
if (!close) {
1433-
header = get_http_header_value(headers, "Connection: ");
1433+
header = get_http_header_value(headers, "Connection:");
14341434
if (header) {
14351435
if(!strncasecmp(header, "close", sizeof("close")-1)) header_close = 1;
14361436
efree(header);
14371437
}
14381438
}
1439-
header = get_http_header_value(headers, "Transfer-Encoding: ");
1439+
header = get_http_header_value(headers, "Transfer-Encoding:");
14401440
if (header) {
14411441
if(!strncasecmp(header, "chunked", sizeof("chunked")-1)) header_chunked = 1;
14421442
efree(header);
14431443
}
1444-
header = get_http_header_value(headers, "Content-Length: ");
1444+
header = get_http_header_value(headers, "Content-Length:");
14451445
if (header) {
14461446
header_length = atoi(header);
14471447
efree(header);

ext/soap/tests/bugs/bug61525.phpt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Bug #61525 (SOAP functions require at least one space after HTTP header colon)
3+
--EXTENSIONS--
4+
soap
5+
--SKIPIF--
6+
<?php
7+
if (@!include __DIR__."/../../../standard/tests/http/server.inc") die('skip server.inc not available');
8+
http_server_skipif();
9+
?>
10+
--FILE--
11+
<?php
12+
require __DIR__."/../../../standard/tests/http/server.inc";
13+
14+
$response = <<<XML
15+
<?xml version="1.0" encoding="UTF-8"?>
16+
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testuri.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
17+
<SOAP-ENV:Body>
18+
<ns1:AddResponse>
19+
<return xsi:type="xsd:int">7</return>
20+
</ns1:AddResponse>
21+
</SOAP-ENV:Body>
22+
</SOAP-ENV:Envelope>
23+
XML;
24+
25+
$length = strlen($response);
26+
$server_response = "data://text/xml;base64," . base64_encode("HTTP/1.1 200 OK\r\nConnection:close\r\nContent-Length:$length\r\n\r\n$response");
27+
['pid' => $pid, 'uri' => $uri] = http_server([$server_response]);
28+
$client = new SoapClient(NULL, ['location' => $uri, 'uri' => $uri]);
29+
var_dump($client->Add(3, 4));
30+
http_server_kill($pid);
31+
?>
32+
--EXPECT--
33+
int(7)

0 commit comments

Comments
 (0)