merged branch dhotson/request-http-host-port (PR #8882)

This PR was submitted for the master branch but it was merged into the 2.2 branch instead (closes #8882).

Discussion
----------

[HttpFoundation] Request->getPort() should prefer HTTP_HOST over SERVER_PORT

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | https://github.com/symfony/symfony/issues/3420
| License       | MIT
| Doc PR        | none

What is this?
----

_Note to reviewer: This follows on from a previous pull request: https://github.com/symfony/symfony/pull/8184
Since the introduction of `Request->setTrustedHosts()` — the implementation of this fix has been simplified._

This fixes the semantics of the `Request#getPort()` method to prefer the HTTP_HOST header over SERVER_PORT.

This is relevant in situations where the web server is running on a different port to the public facing website. e.g. load balancers, proxies, port forwarding.

Consistency
----

This change makes Symfony more consistent with other popular web frameworks.

Preferring HTTP_HOST over SERVER_NAME and SERVER_PORT is the strategy used by Ruby's Rack and Python's Django.

Python has a PEP that describes how to reconstruct URLs:
http://www.python.org/dev/peps/pep-0333/#url-reconstruction

b6290a184c/lib/rack/request.rb (L92)

Commits
-------

fa97d80 Request->getPort() should prefer HTTP_HOST over SERVER_PORT
This commit is contained in:
Fabien Potencier 2013-09-07 08:11:06 +02:00
commit 85eaec3eda
2 changed files with 20 additions and 0 deletions

View File

@ -887,6 +887,14 @@ class Request
}
}
if ($host = $this->headers->get('HOST')) {
if (preg_match('/:(\d+)$/', $host, $matches)) {
return intval($matches[1]);
}
return 'https' === $this->getScheme() ? 443 : 80;
}
return $this->server->get('SERVER_PORT');
}

View File

@ -1540,6 +1540,18 @@ class RequestTest extends \PHPUnit_Framework_TestCase
// trusted hosts
$request->headers->set('host', 'trusted.com');
$this->assertEquals('trusted.com', $request->getHost());
$this->assertEquals(80, $request->getPort());
$request->server->set('HTTPS', true);
$request->headers->set('host', 'trusted.com');
$this->assertEquals('trusted.com', $request->getHost());
$this->assertEquals(443, $request->getPort());
$request->server->set('HTTPS', false);
$request->headers->set('host', 'trusted.com:8000');
$this->assertEquals('trusted.com', $request->getHost());
$this->assertEquals(8000, $request->getPort());
$request->headers->set('host', 'subdomain.trusted.com');
$this->assertEquals('subdomain.trusted.com', $request->getHost());