Intercepting redirections with the Symfony HttpClient

Published on 2020-03-06 • Modified on 2020-03-06

In this snippet, we will see how to intercept a redirection with the Symfony HttpClient. I am using this in some of my external tests where I check that the non-https versions of my pages are correctly redirected to the canonical versions (www with https). As you can see, if no exception is raised by the request() function then the test fails. Otherwise, we check that the location header is correctly set with the URL we are expecting.


<?php declare(strict_types=1);

namespace App\Tests\External;

use App\Tests\WebTestCase;
use Symfony\Component\HttpClient\Exception\RedirectionException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * Test the SSL redirections.
 */
final class SslTest extends WebTestCase
{
    /**
     * @var HttpClientInterface
     */
    private $httpClient;

    protected function setUp(): void
    {
        self::bootKernel();
        $this->httpClient = self::$container->get('http_client');
    }

    public function urlProvider(): iterable
    {
        // http with www
        yield ['http://www.strangebuzz.com', 'https://www.strangebuzz.com/'];
        yield ['http://www.strangebuzz.com/', 'https://www.strangebuzz.com/'];
        yield ['http://www.strangebuzz.com/en/snippets/freezing-the-vue-js-version-to-a-minor-version', 'https://www.strangebuzz.com/en/snippets/freezing-the-vue-js-version-to-a-minor-version'];

        // http with www
        yield ['http://strangebuzz.com', 'https://www.strangebuzz.com/'];
        yield ['http://strangebuzz.com/', 'https://www.strangebuzz.com/'];
        yield ['http://strangebuzz.com/en/snippets/freezing-the-vue-js-version-to-a-minor-version', 'https://www.strangebuzz.com/'];

        // https with www
        yield ['https://strangebuzz.com', 'https://www.strangebuzz.com/'];
        yield ['https://strangebuzz.com/', 'https://www.strangebuzz.com/'];
        yield ['https://strangebuzz.com/en/snippets/freezing-the-vue-js-version-to-a-minor-version', 'https://www.strangebuzz.com/en/snippets/freezing-the-vue-js-version-to-a-minor-version'];
    }

    /**
     * @dataProvider urlProvider
     */
    public function testSsl(string $url, string $location): void
    {
        try {
            $this->httpClient->request('GET', $url, ['max_redirects' => 0])->getContent();
            $this->fail(sprintf('URL "%s" non redirigée.', $url));
        } catch (RedirectionException $e) {
            $this->assertSame(Response::HTTP_MOVED_PERMANENTLY, $e->getResponse()->getStatusCode());
            $this->assertSame($location, $e->getResponse()->getInfo()['redirect_url'] ?? '');
        }
    }
}