greg
greg

Reputation: 6913

Symfony functional test - custom headers not passing through

For some reason when i sent a new $client->request the headers I specify get lost:

public function testGetClientsAction()
{
    $client = static::createClient();

    $cookie = new Cookie('locale2', 'en', time() + 3600 * 24 * 7, '/', null, false, false);
    $client->getCookieJar()->set($cookie);

    // Visit user login page and login
    $crawler = $client->request('GET', '/login');
    $form = $crawler->selectButton('login')->form();
    $crawler = $client->submit($form, array('_username' => 'greg', '_password' => 'greg'));

    $client->request(
       'GET', 
       '/clients', 
        array(), 
        array(), 
        array('X-Requested-With' => 'XMLHttpRequest', 'accept' => 'application/json')
    );

    print_r($client->getResponse());
    die();

}

In the method that is being tested I have this on the first line:

print_r($request->headers->all());

The response is as follows:

Array
(
    [host] => Array
        (
            [0] => localhost
        )

    [user-agent] => Array
        (
            [0] => Symfony2 BrowserKit
        )

    [accept] => Array
        (
            [0] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
        )

    [accept-language] => Array
        (
            [0] => en-us,en;q=0.5
        )

    [accept-charset] => Array
        (
            [0] => ISO-8859-1,utf-8;q=0.7,*;q=0.7
        )

    [referer] => Array
        (
            [0] => http://localhost/login_check
        )

    [x-php-ob-level] => Array
        (
            [0] => 1
        )

)

Upvotes: 42

Views: 29341

Answers (4)

Nuryagdy Mustapayev
Nuryagdy Mustapayev

Reputation: 775

If you are using jsonRequest() method of symfony's KernelBrowser, you can send the header this way:

        $this->client->jsonRequest('GET', '/api/user', [], [
            'HTTP_Authorization' => 'Bearer ' . $token,
        ]);

As already mentioned in previous answers you need to add HTTP_ prefix to your header names.

Upvotes: 0

Rayan arnel
Rayan arnel

Reputation: 123

In addition to the HTTP_ suffix you have to be careful how you try to access them, more information below.

For that request :
     $this->client->request(
            Request::METHOD_POST,
            '/api/auth/login',
            [],
            [],
            [
                'CONTENT_TYPE' => 'application/json',
                'HTTP_X-interface' => "string",
            ],
            json_encode([
                'username' => "[email protected]",
                'password' => "exemplePassword"
            ]));
I want get header with : $request->headers->get('X-interface');

I have an event listener that listens for the 'authentication_success' event for the Lexik JWT bundle.

public function onAuthenticationSuccess(AuthenticationSuccessEvent $event)
{
    $request    = Request::createFromGlobals();
    $interface  = $request->headers->get('X-interface'); // null
}

To

public function onAuthenticationSuccess(AuthenticationSuccessEvent $event)
{
    $requestStack = $this->container->get('request_stack');
    $request = $requestStack->getMainRequest();
  $interface = $request->headers->get('X-interface'); // i have header
}

The Request::createFromGlobals() method works in production because the current request headers are available in the global variables. These global variables are defined by the web server before the request is received by PHP.

In a functional test, the current request headers are not available in the global variables. Therefore, the Request::createFromGlobals() method returns a new request that does not contain the current request headers.

A last exemple :

 #[Route('/postTest', name: 'postTest', methods: ['post'])]

    public function postTest(Request $request)
    {
        dd($_SERVER);
    }

With postMan : i have the header in the super global $_SERVER

With $client->request in the test (KernelBrowser) : I don't have header in the super global $_SERVER

Upvotes: 0

Adrian C.
Adrian C.

Reputation: 762

If you check the definition from Client.php, at method request, you will see in the docblock a very useful information:

  • @param array $server The server parameters (HTTP headers are referenced with a HTTP_ prefix as PHP does)

This means that you should add a HTTP_ prefix to the header you want to send. For example if you want to pass header X-HTTP-Method-Override you specify it like so:

    $client->request(
        Request::METHOD_POST,
        '/api/v1/something',
        $body,
        [],
        ['HTTP_X-HTTP-Method-Override' => Request::METHOD_GET]
    );

Upvotes: 23

Windix
Windix

Reputation: 911

I have the same issue and after a little dig through I think it is a feature that BrowserKit currently doesn't support.

I have logged an issue for it: https://github.com/symfony/symfony/issues/5074

Update: this is not an issue -- see the comments below

Sample Code

Sample request:

$client->request(
    'GET',
    $url,
    array(),
    array(),
    array(
        'HTTP_X_CUSTOM_VAR' => $var
    )
);

Fetching the data:

$request->headers->get('x-custom-var');

Upvotes: 75

Related Questions