hhvm
hhvm copied to clipboard
Move stream context http header processing
Commit eec9da990e7344af985735ec53d73325579931eb appended the http header from the stream context to the curl list of headers. This was done to allow a SoapClient to be constructed with a stream context that contained http headers. It created issues #7684 and #8046.
HttpClient::request() has a requestHeaders argument that should be used instead. Because there are three places that use HttpClient with a StreamContext object, this commit adds HttpClient.streamContextHttpHeader() and moves all processing of stream context http headers there.
Places that use HttpClient.setStreamContextOptions()
- SoapClient::__construct(), -> sdl.cpp load_wsdl_ex()
- SoapClient::__dorequest()
- UrlFile->open()
Closes #5553 Closes #7684 Closes #8046 Closes #8047
I am not sure how to write a regression test that uses a server-side script. Here are the client and server side scripts I used to test behavior.
<?php
/**
* test_7684_client.php
*
* To see the raw TCP:
* sudo tcpdump -A -n -s 2024 dst port 80
*/
$url = 'http://YOUR_SERVER)HOST/test_7684_server.php';
$headers = [
'X-TEST-STRING-1: value1',
"X-TEST-STRING-2: value2\r\nX-TEST-STRING-3: value3",
['X-TEST-ELEMENT-1: element1', 'X-TEST-ELEMENT-2: element2']
];
foreach($headers as $header) {
$context = stream_context_create(['http' => ['header' => $header]]);
$returnedHeaders = sendSoapRequest($url, $context);
assertHeaders($header, $returnedHeaders, 'sendSoapRequest()');
$returnedHeaders = file_get_contents($url, null, $context);
assertHeaders($header, $returnedHeaders, 'file_get_contents()');
}
function sendSoapRequest($url, $context)
{
$client = new SoapClient(null, [
'location' => $url,
'stream_context' => $context,
'style' => SOAP_RPC, # PHP will default to SOAP_RPC, HHVM defaults to an empty SOAP body
'uri' => 'http://testing.dev',
]);
try {
return $client->__soapCall('getRequestHeaders', array());
} catch(SoapFault $e) {
echo get_class($e) . ': [' . $e->faultcode . '] ' . $e->getMessage() . "\n";
return false;
}
}
/**
* @param array|string $requestHeaders
* @param string|false $returnedHeaders
* @param string $function
* @return bool
*/
function assertHeaders($requestHeaders, $returnedHeaders, $function)
{
if (is_string($requestHeaders)) {
$requestHeaders = explode("\r\n", $requestHeaders);
}
if ($returnedHeaders === false) {
$result = false;
$returnedHeaders = 'false';
} else {
$returnedHeaders = explode("\r\n", $returnedHeaders);
$result = true;
foreach ($requestHeaders as $requestHeader) {
if (!in_array($requestHeader, $returnedHeaders)) {
$result = false;
break;
}
}
}
if ($result == false) {
echo "$function FAILED!\n";
echo "Request headers: " . print_r($requestHeaders, true);
echo "Returned headers: " . print_r($returnedHeaders, true);
}
return $result;
}
<?php
/**
* test_7684_server.php
*/
class MyAPI
{
public function getRequestHeaders()
{
$headers = [];
foreach($_SERVER as $key => $value) {
if (substr($key, 0, 5) == 'HTTP_') {
$key = str_replace('_', '-', substr($key, 5));
$headers[] = "$key: $value";
}
}
return implode("\r\n", $headers);
}
}
if (isset($_SERVER['HTTP_SOAPACTION'])) {
$options = array('uri' => 'http://testing.dev');
$server = new SoapServer(null, $options);
$server->setClass('MyAPI');
$server->handle();
} else {
$api = new MyAPI();
echo $api->getRequestHeaders();
}
@pondermatic has updated the pull request. View: changes