2

from the $_SERVER php array:

$_SERVER['APP_ENV']                 prod
$_SERVER['APP_DEBUG']               0
$_SERVER['TRUSTED_PROXIES']         172.16.0.0/12
$_SERVER['HTTP_X_FORWARDED_FOR']    XXX.XXX.XXX.XXX
$_SERVER['HTTP_X_FORWARDED_HOST']   my.website.com
$_SERVER['HTTP_X_FORWARDED_PORT']   443
$_SERVER['HTTP_X_FORWARDED_PROTO']  https

from the HTTP Headers:

X-Forwarded-For     XXX.XXX.XXX.XXX
X-Forwarded-Host    my.website.com
X-Forwarded-Port    443
X-Forwarded-Proto   https

in src/public/index.php

if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? false) {
    Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
}

in /src/Controller/TestController.php

class TestController 
{
    public function index(Request $request)
    {
        $response = new Response();
        $response->setContent(  $request->getScheme() );
        return $response;
    }
}

output

http

but the expected output is

https

why symfony return the wrong http scheme?

3 Answers 3

1

The problem comes from the bad header name HTTP_X_FORWARDED_PROTO returned by Traefik

Symfony recognize the FORWARDED or the X_FORWARDED_PROTO

Source (for symfony 3.4 (deprecated code removed in 4.x)

protected static $trustedHeaders = array(
    self::HEADER_FORWARDED => 'FORWARDED',
    self::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',
    self::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST',
    self::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO',
    self::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT',
);

According to this documentation you must set the right Trusted Proxies in the public/index.php file like this (AWS ELB enabled, which recognize HTTP_X_FORWARDED_PROTO

...
$kernel = new Kernel($env, $debug);
$request = Request::createFromGlobals();

// tell Symfony about your reverse proxy

Request::setTrustedProxies(
// the IP address (or range) of your proxy
['192.0.0.1', '10.0.0.0/8'],

// trust *all* "X-Forwarded-*" headers
// Request::HEADER_X_FORWARDED_ALL

// or, if your proxy instead uses the "Forwarded" header
// Request::HEADER_FORWARDED

// or, if you're using AWS ELB
Request::HEADER_X_FORWARDED_AWS_ELB
);
...
Sign up to request clarification or add additional context in comments.

Comments

1

In Symfony 5 and up you can tell the framework to trust the reverse proxy by using these settings in config/packages/framework.yaml:

framework:

    # the IP address (or range) of your proxy
    trusted_proxies: '192.0.0.1,10.0.0.0/8'

    # trust *all* "X-Forwarded-*" headers
    trusted_headers: ['x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port']

This will result in the correct https protocol when creating urls or using $request->getScheme().

More about this in the Symfony documentation.

Comments

0

Do you have the same output when you use the abstract class AbstractController ?

Like class TestController extends AbstractController

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.