Skip to content

Ability to unset a default header added by HttpKernelBrowser / Client #33393

@teohhanhui

Description

@teohhanhui

Symfony version(s) affected: 3.4+

Description
There is currently no way to unset a HTTP request header through the BrowserKit AbstractBrowser / Client. This was requested before in #20306, but actually implementing an unsetServerParameter method would not help in our case.

The problem we're facing here (in API Platform) is that when we send a request using HttpKernelBrowser / Client:

protected function filterRequest(DomRequest $request)
{
$httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent());

it calls (HttpFoundation) Request::create which adds some default request headers:

public static function create($uri, $method = 'GET', $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
{
$server = array_replace([
'SERVER_NAME' => 'localhost',
'SERVER_PORT' => 80,
'HTTP_HOST' => 'localhost',
'HTTP_USER_AGENT' => 'Symfony',
'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5',
'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
'REMOTE_ADDR' => '127.0.0.1',
'SCRIPT_NAME' => '',
'SCRIPT_FILENAME' => '',
'SERVER_PROTOCOL' => 'HTTP/1.1',
'REQUEST_TIME' => time(),
], $server);

This includes the Accept header, which we need to be able to remove in order to test content negotiation scenarios where the client doesn't send the Accept header, thereby resulting in the use of the default media type.

How to reproduce
We had been using a workaround to unset the Accept header in our test suite, basically:

$client->setServerParameter('HTTP_ACCEPT', null);

The end result in the HeaderBag is:

array(1) {
  ["accept"]=>
  array(1) {
    [0]=>
    NULL
  }
}

However, fixes in HeaderBag::get, specifically the change made to this line:

return \count($headers[$key]) ? (string) $headers[$key][0] : $default;

means that we get an empty string now instead of null.

Possible Solution
So this breaks our test suite. We could find new workarounds, including checking for the case where the Accept header is an empty string (weird!), or overriding / extending some parts of the chain which sends the request in our test suite.

However, we're wondering if there might be a better way of fixing this for everyone. It was an ugly workaround in the first place.

This problem also affects ApiTestCase in API Platform, as the user would be unable to send a request without any of the default headers.

Additional context

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions