hhvm icon indicating copy to clipboard operation
hhvm copied to clipboard

Move stream context http header processing

Open pondermatic opened this issue 8 years ago • 2 comments

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

pondermatic avatar Nov 17 '17 23:11 pondermatic

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 avatar Nov 17 '17 23:11 pondermatic

@pondermatic has updated the pull request. View: changes

facebook-github-bot avatar Nov 21 '17 15:11 facebook-github-bot