Skip to content

Commit

Permalink
[HttpFoundation] fixed Request::create() method
Browse files Browse the repository at this point in the history
When creating a Request with Request::create(), some information can
come from the URI and the server variable. Until now, it was not clear
which information had precedence over the other and as a matter of fact,
this method was not consistent.

Now, information contained in the URI always take precedence over
information coming from the server array. That makes sense as the server
array is often copied from another existing Request object.
  • Loading branch information
fabpot committed Feb 7, 2013
1 parent 3446cb2 commit bc4a0e7
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/Symfony/Component/HttpFoundation/CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@ CHANGELOG
2.2.0
-----

* fixed the Request::create() precedence (URI information always take precedence now)
* added Request::getTrustedProxies()
* deprecated Request::isProxyTrusted()
* [BC BREAK] JsonResponse does not turn a top level empty array to an object anymore, use an ArrayObject to enforce objects
Expand Down
41 changes: 22 additions & 19 deletions src/Symfony/Component/HttpFoundation/Request.php
Expand Up @@ -253,6 +253,9 @@ public static function createFromGlobals()
/**
* Creates a Request based on a given URI and configuration.
*
* The information contained in the URI always take precedence
* over the other information (server and parameters).
*
* @param string $uri The URI
* @param string $method The HTTP method
* @param array $parameters The query (GET) or request (POST) parameters
Expand All @@ -267,7 +270,7 @@ public static function createFromGlobals()
*/
public static function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null)
{
$defaults = array(
$server = array_replace(array(
'SERVER_NAME' => 'localhost',
'SERVER_PORT' => 80,
'HTTP_HOST' => 'localhost',
Expand All @@ -280,32 +283,38 @@ public static function create($uri, $method = 'GET', $parameters = array(), $coo
'SCRIPT_FILENAME' => '',
'SERVER_PROTOCOL' => 'HTTP/1.1',
'REQUEST_TIME' => time(),
);
), $server);

$server['PATH_INFO'] = '';
$server['REQUEST_METHOD'] = strtoupper($method);

$components = parse_url($uri);
if (isset($components['host'])) {
$defaults['SERVER_NAME'] = $components['host'];
$defaults['HTTP_HOST'] = $components['host'];
$server['SERVER_NAME'] = $components['host'];
$server['HTTP_HOST'] = $components['host'];
}

if (isset($components['scheme'])) {
if ('https' === $components['scheme']) {
$defaults['HTTPS'] = 'on';
$defaults['SERVER_PORT'] = 443;
$server['HTTPS'] = 'on';
$server['SERVER_PORT'] = 443;
} else {
unset($server['HTTPS']);
$server['SERVER_PORT'] = 80;
}
}

if (isset($components['port'])) {
$defaults['SERVER_PORT'] = $components['port'];
$defaults['HTTP_HOST'] = $defaults['HTTP_HOST'].':'.$components['port'];
$server['SERVER_PORT'] = $components['port'];
$server['HTTP_HOST'] = $server['HTTP_HOST'].':'.$components['port'];
}

if (isset($components['user'])) {
$defaults['PHP_AUTH_USER'] = $components['user'];
$server['PHP_AUTH_USER'] = $components['user'];
}

if (isset($components['pass'])) {
$defaults['PHP_AUTH_PW'] = $components['pass'];
$server['PHP_AUTH_PW'] = $components['pass'];
}

if (!isset($components['path'])) {
Expand All @@ -316,7 +325,7 @@ public static function create($uri, $method = 'GET', $parameters = array(), $coo
case 'POST':
case 'PUT':
case 'DELETE':
$defaults['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
$server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
case 'PATCH':
$request = $parameters;
$query = array();
Expand All @@ -333,14 +342,8 @@ public static function create($uri, $method = 'GET', $parameters = array(), $coo
}
$queryString = http_build_query($query, '', '&');

$uri = $components['path'].('' !== $queryString ? '?'.$queryString : '');

$server = array_replace($defaults, $server, array(
'REQUEST_METHOD' => strtoupper($method),
'PATH_INFO' => '',
'REQUEST_URI' => $uri,
'QUERY_STRING' => $queryString,
));
$server['REQUEST_URI'] = $components['path'].('' !== $queryString ? '?'.$queryString : '');
$server['QUERY_STRING'] = $queryString;

return new static($query, $request, array(), $cookies, $files, $server, $content);
}
Expand Down
35 changes: 35 additions & 0 deletions src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
Expand Up @@ -222,6 +222,41 @@ public function testCreate()
$this->assertFalse($request->isSecure());
}

/**
* @covers Symfony\Component\HttpFoundation\Request::create
*/
public function testCreateCheckPrecedence()
{
// server is used by default
$request = Request::create('/', 'GET', array(), array(), array(), array(
'HTTP_HOST' => 'example.com',
'HTTPS' => 'on',
'SERVER_PORT' => 443,
'PHP_AUTH_USER' => 'fabien',
'PHP_AUTH_PW' => 'pa$$',
'QUERY_STRING' => 'foo=bar',
));
$this->assertEquals('example.com', $request->getHost());
$this->assertEquals(443, $request->getPort());
$this->assertTrue($request->isSecure());
$this->assertEquals('fabien', $request->getUser());
$this->assertEquals('pa$$', $request->getPassword());
$this->assertEquals('', $request->getQueryString());

// URI has precedence over server
$request = Request::create('http://thomas:pokemon@example.net:8080/?foo=bar', 'GET', array(), array(), array(), array(
'HTTP_HOST' => 'example.com',
'HTTPS' => 'on',
'SERVER_PORT' => 443,
));
$this->assertEquals('example.net', $request->getHost());
$this->assertEquals(8080, $request->getPort());
$this->assertFalse($request->isSecure());
$this->assertEquals('thomas', $request->getUser());
$this->assertEquals('pokemon', $request->getPassword());
$this->assertEquals('foo=bar', $request->getQueryString());
}

/**
* @covers Symfony\Component\HttpFoundation\Request::duplicate
*/
Expand Down

0 comments on commit bc4a0e7

Please sign in to comment.