mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-04 14:46:19 +08:00 
			
		
		
		
	Fixes #14488: Added support for X-Forwarded-Host to yii\web\Request, fixed getServerPort() usage
				
					
				
			This commit is contained in:
		
				
					committed by
					
						
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							40b038379f
						
					
				
				
					commit
					7bafb7bf09
				
			@ -4,6 +4,7 @@ Yii Framework 2 Change Log
 | 
				
			|||||||
2.0.14 under development
 | 
					2.0.14 under development
 | 
				
			||||||
------------------------
 | 
					------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Enh #14488: Added support for X-Forwarded-Host to `yii\web\Request`, fixed `getServerPort()` usage (si294r, samdark)
 | 
				
			||||||
- Enh #13019: Support JSON in SchemaBuilderTrait (zhukovra, undefinedor)
 | 
					- Enh #13019: Support JSON in SchemaBuilderTrait (zhukovra, undefinedor)
 | 
				
			||||||
- Enh #15047: `yii\db\Query::select()` and `yii\db\Query::addSelect()` now check for duplicate column names (wapmorgan)
 | 
					- Enh #15047: `yii\db\Query::select()` and `yii\db\Query::addSelect()` now check for duplicate column names (wapmorgan)
 | 
				
			||||||
- Enh #14643: Added `yii\web\ErrorAction::$layout` property to conveniently set layout from error action config (swods, cebe, samdark)
 | 
					- Enh #14643: Added `yii\web\ErrorAction::$layout` property to conveniently set layout from error action config (swods, cebe, samdark)
 | 
				
			||||||
 | 
				
			|||||||
@ -218,9 +218,12 @@ class Request extends \yii\base\Request
 | 
				
			|||||||
     * @since 2.0.13
 | 
					     * @since 2.0.13
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public $secureHeaders = [
 | 
					    public $secureHeaders = [
 | 
				
			||||||
 | 
					        // Common:
 | 
				
			||||||
        'X-Forwarded-For',
 | 
					        'X-Forwarded-For',
 | 
				
			||||||
        'X-Forwarded-Host',
 | 
					        'X-Forwarded-Host',
 | 
				
			||||||
        'X-Forwarded-Proto',
 | 
					        'X-Forwarded-Proto',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Microsoft:
 | 
				
			||||||
        'Front-End-Https',
 | 
					        'Front-End-Https',
 | 
				
			||||||
        'X-Rewrite-Url',
 | 
					        'X-Rewrite-Url',
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
@ -233,7 +236,7 @@ class Request extends \yii\base\Request
 | 
				
			|||||||
     * @since 2.0.13
 | 
					     * @since 2.0.13
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public $ipHeaders = [
 | 
					    public $ipHeaders = [
 | 
				
			||||||
        'X-Forwarded-For',
 | 
					        'X-Forwarded-For', // Common
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @var array list of headers to check for determining whether the connection is made via HTTPS.
 | 
					     * @var array list of headers to check for determining whether the connection is made via HTTPS.
 | 
				
			||||||
@ -245,8 +248,8 @@ class Request extends \yii\base\Request
 | 
				
			|||||||
     * @since 2.0.13
 | 
					     * @since 2.0.13
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public $secureProtocolHeaders = [
 | 
					    public $secureProtocolHeaders = [
 | 
				
			||||||
        'X-Forwarded-Proto' => ['https'],
 | 
					        'X-Forwarded-Proto' => ['https'], // Common
 | 
				
			||||||
        'Front-End-Https' => ['on'],
 | 
					        'Front-End-Https' => ['on'], // Microsoft
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -705,7 +708,10 @@ class Request extends \yii\base\Request
 | 
				
			|||||||
        if ($this->_hostInfo === null) {
 | 
					        if ($this->_hostInfo === null) {
 | 
				
			||||||
            $secure = $this->getIsSecureConnection();
 | 
					            $secure = $this->getIsSecureConnection();
 | 
				
			||||||
            $http = $secure ? 'https' : 'http';
 | 
					            $http = $secure ? 'https' : 'http';
 | 
				
			||||||
            if ($this->headers->has('Host')) {
 | 
					
 | 
				
			||||||
 | 
					            if ($this->headers->has('X-Forwarded-Host')) {
 | 
				
			||||||
 | 
					                $this->_hostInfo = $http . '://' . $this->headers->get('X-Forwarded-Host');
 | 
				
			||||||
 | 
					            } elseif ($this->headers->has('Host')) {
 | 
				
			||||||
                $this->_hostInfo = $http . '://' . $this->headers->get('Host');
 | 
					                $this->_hostInfo = $http . '://' . $this->headers->get('Host');
 | 
				
			||||||
            } elseif (isset($_SERVER['SERVER_NAME'])) {
 | 
					            } elseif (isset($_SERVER['SERVER_NAME'])) {
 | 
				
			||||||
                $this->_hostInfo = $http . '://' . $_SERVER['SERVER_NAME'];
 | 
					                $this->_hostInfo = $http . '://' . $_SERVER['SERVER_NAME'];
 | 
				
			||||||
@ -1217,7 +1223,8 @@ class Request extends \yii\base\Request
 | 
				
			|||||||
    public function getPort()
 | 
					    public function getPort()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($this->_port === null) {
 | 
					        if ($this->_port === null) {
 | 
				
			||||||
            $this->_port = !$this->getIsSecureConnection() && isset($_SERVER['SERVER_PORT']) ? (int) $_SERVER['SERVER_PORT'] : 80;
 | 
					            $serverPort = $this->getServerPort();
 | 
				
			||||||
 | 
					            $this->_port = !$this->getIsSecureConnection() && $serverPort !== null ? $serverPort : 80;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->_port;
 | 
					        return $this->_port;
 | 
				
			||||||
@ -1249,7 +1256,8 @@ class Request extends \yii\base\Request
 | 
				
			|||||||
    public function getSecurePort()
 | 
					    public function getSecurePort()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($this->_securePort === null) {
 | 
					        if ($this->_securePort === null) {
 | 
				
			||||||
            $this->_securePort = $this->getIsSecureConnection() && isset($_SERVER['SERVER_PORT']) ? (int) $_SERVER['SERVER_PORT'] : 443;
 | 
					            $serverPort = $this->getServerPort();
 | 
				
			||||||
 | 
					            $this->_securePort = $this->getIsSecureConnection() && $serverPort !== null ? $serverPort : 443;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->_securePort;
 | 
					        return $this->_securePort;
 | 
				
			||||||
 | 
				
			|||||||
@ -266,7 +266,85 @@ class RequestTest extends TestCase
 | 
				
			|||||||
        $this->assertEquals($_GET, ['id' => 63]);
 | 
					        $this->assertEquals($_GET, ['id' => 63]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testGetHostInfo()
 | 
					    public function getHostInfoDataProvider()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            // empty
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                [],
 | 
				
			||||||
 | 
					                [null, null]
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            // normal
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'HTTP_HOST' => 'example1.com',
 | 
				
			||||||
 | 
					                    'SERVER_NAME' => 'example2.com',
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'http://example1.com',
 | 
				
			||||||
 | 
					                    'example1.com',
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            // HTTP header missing
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'SERVER_NAME' => 'example2.com',
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'http://example2.com',
 | 
				
			||||||
 | 
					                    'example2.com',
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            // forwarded from untrusted server
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'HTTP_X_FORWARDED_HOST' => 'example3.com',
 | 
				
			||||||
 | 
					                    'HTTP_HOST' => 'example1.com',
 | 
				
			||||||
 | 
					                    'SERVER_NAME' => 'example2.com',
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'http://example1.com',
 | 
				
			||||||
 | 
					                    'example1.com',
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            // forwarded from trusted proxy
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'HTTP_X_FORWARDED_HOST' => 'example3.com',
 | 
				
			||||||
 | 
					                    'HTTP_HOST' => 'example1.com',
 | 
				
			||||||
 | 
					                    'SERVER_NAME' => 'example2.com',
 | 
				
			||||||
 | 
					                    'REMOTE_ADDR' => '192.168.0.1',
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'http://example3.com',
 | 
				
			||||||
 | 
					                    'example3.com',
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @dataProvider getHostInfoDataProvider
 | 
				
			||||||
 | 
					     * @param array $server
 | 
				
			||||||
 | 
					     * @param array $expected
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function testGetHostInfo($server, $expected)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $original = $_SERVER;
 | 
				
			||||||
 | 
					        $_SERVER = $server;
 | 
				
			||||||
 | 
					        $request = new Request([
 | 
				
			||||||
 | 
					            'trustedHosts' => [
 | 
				
			||||||
 | 
					                '192.168.0.0/24',
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertEquals($expected[0], $request->getHostInfo());
 | 
				
			||||||
 | 
					        $this->assertEquals($expected[1], $request->getHostName());
 | 
				
			||||||
 | 
					        $_SERVER = $original;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testSetHostInfo()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $request = new Request();
 | 
					        $request = new Request();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user