namespace Symfony\Component\HttpFoundation\Tests;
use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Request;
class RequestTest extends TestCase
{
+ protected function tearDown()
+ {
+ // reset
+ Request::setTrustedProxies(array(), -1);
+ }
+
public function testInitialize()
{
$request = new Request();
public function testGetUser()
{
- $request = Request::create('http://user_test:password_test@test.com/');
+ $request = Request::create('http://user:password@test.com');
$user = $request->getUser();
- $this->assertEquals('user_test', $user);
+ $this->assertEquals('user', $user);
}
public function testGetPassword()
{
- $request = Request::create('http://user_test:password_test@test.com/');
+ $request = Request::create('http://user:password@test.com');
$password = $request->getPassword();
- $this->assertEquals('password_test', $password);
+ $this->assertEquals('password', $password);
}
public function testIsNoCache()
array('js', array('application/javascript', 'application/x-javascript', 'text/javascript')),
array('css', array('text/css')),
array('json', array('application/json', 'application/x-json')),
+ array('jsonld', array('application/ld+json')),
array('xml', array('text/xml', 'application/xml', 'application/x-xml')),
array('rdf', array('application/rdf+xml')),
array('atom', array('application/atom+xml')),
$this->assertEquals(80, $port, 'Without trusted proxies FORWARDED_PROTO and FORWARDED_PORT are ignored.');
- Request::setTrustedProxies(array('1.1.1.1'));
+ Request::setTrustedProxies(array('1.1.1.1'), Request::HEADER_X_FORWARDED_ALL);
$request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
'HTTP_X_FORWARDED_PROTO' => 'https',
'HTTP_X_FORWARDED_PORT' => '8443',
));
$port = $request->getPort();
$this->assertEquals(80, $port, 'With only PROTO set and value is not recognized, getPort() defaults to 80.');
-
- Request::setTrustedProxies(array());
}
/**
$request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
$this->assertEquals($expected[0], $request->getClientIp());
-
- Request::setTrustedProxies(array());
}
/**
$request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
$this->assertEquals($expected, $request->getClientIps());
-
- Request::setTrustedProxies(array());
}
/**
$request = $this->getRequestInstanceForClientIpsForwardedTests($remoteAddr, $httpForwarded, $trustedProxies);
$this->assertEquals($expected, $request->getClientIps());
-
- Request::setTrustedProxies(array());
}
public function getClientIpsForwardedProvider()
'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
);
- Request::setTrustedProxies(array('88.88.88.88'));
+ Request::setTrustedProxies(array('88.88.88.88'), Request::HEADER_X_FORWARDED_ALL | Request::HEADER_FORWARDED);
$request->initialize(array(), array(), array(), array(), array(), $server);
$request->getClientIps();
}
+ /**
+ * @dataProvider getClientIpsWithConflictingHeadersProvider
+ */
+ public function testGetClientIpsOnlyXHttpForwardedForTrusted($httpForwarded, $httpXForwardedFor)
+ {
+ $request = new Request();
+
+ $server = array(
+ 'REMOTE_ADDR' => '88.88.88.88',
+ 'HTTP_FORWARDED' => $httpForwarded,
+ 'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
+ );
+
+ Request::setTrustedProxies(array('88.88.88.88'), Request::HEADER_X_FORWARDED_FOR);
+
+ $request->initialize(array(), array(), array(), array(), array(), $server);
+
+ $this->assertSame(array_reverse(explode(',', $httpXForwardedFor)), $request->getClientIps());
+ }
+
public function getClientIpsWithConflictingHeadersProvider()
{
// $httpForwarded $httpXForwardedFor
'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
);
- Request::setTrustedProxies(array('88.88.88.88'));
+ Request::setTrustedProxies(array('88.88.88.88'), Request::HEADER_X_FORWARDED_ALL);
$request->initialize(array(), array(), array(), array(), array(), $server);
$clientIps = $request->getClientIps();
- Request::setTrustedProxies(array());
-
$this->assertSame($expectedIps, $clientIps);
}
$request->headers->set('X_FORWARDED_PROTO', 'https');
- Request::setTrustedProxies(array('1.1.1.1'));
+ Request::setTrustedProxies(array('1.1.1.1'), Request::HEADER_X_FORWARDED_ALL);
$this->assertFalse($request->isSecure());
$request->server->set('REMOTE_ADDR', '1.1.1.1');
$this->assertTrue($request->isSecure());
- Request::setTrustedProxies(array());
$request->overrideGlobals();
$request = new Request();
$request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
+ $request->cookies->set('Foo', 'Bar');
+
+ $asString = (string) $request;
+
+ $this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $asString);
+ $this->assertContains('Cookie: Foo=Bar', $asString);
+
+ $request->cookies->set('Another', 'Cookie');
- $this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $request->__toString());
+ $asString = (string) $request;
+
+ $this->assertContains('Cookie: Foo=Bar; Another=Cookie', $asString);
}
public function testIsMethod()
}
if ($trustedProxies) {
- Request::setTrustedProxies($trustedProxies);
+ Request::setTrustedProxies($trustedProxies, Request::HEADER_X_FORWARDED_ALL);
}
$request->initialize(array(), array(), array(), array(), array(), $server);
}
if ($trustedProxies) {
- Request::setTrustedProxies($trustedProxies);
+ Request::setTrustedProxies($trustedProxies, Request::HEADER_FORWARDED);
}
$request->initialize(array(), array(), array(), array(), array(), $server);
$request->headers->set('X_FORWARDED_HOST', 'foo.example.com:1234, real.example.com:8080');
$request->headers->set('X_FORWARDED_PROTO', 'https');
$request->headers->set('X_FORWARDED_PORT', 443);
- $request->headers->set('X_MY_FOR', '3.3.3.3, 4.4.4.4');
- $request->headers->set('X_MY_HOST', 'my.example.com');
- $request->headers->set('X_MY_PROTO', 'http');
- $request->headers->set('X_MY_PORT', 81);
// no trusted proxies
$this->assertEquals('3.3.3.3', $request->getClientIp());
$this->assertFalse($request->isSecure());
// disabling proxy trusting
- Request::setTrustedProxies(array());
+ Request::setTrustedProxies(array(), Request::HEADER_X_FORWARDED_ALL);
$this->assertEquals('3.3.3.3', $request->getClientIp());
$this->assertEquals('example.com', $request->getHost());
$this->assertEquals(80, $request->getPort());
$this->assertFalse($request->isSecure());
// request is forwarded by a non-trusted proxy
- Request::setTrustedProxies(array('2.2.2.2'));
+ Request::setTrustedProxies(array('2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
$this->assertEquals('3.3.3.3', $request->getClientIp());
$this->assertEquals('example.com', $request->getHost());
$this->assertEquals(80, $request->getPort());
$this->assertFalse($request->isSecure());
// trusted proxy via setTrustedProxies()
- Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
+ Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
$this->assertEquals('1.1.1.1', $request->getClientIp());
$this->assertEquals('foo.example.com', $request->getHost());
$this->assertEquals(443, $request->getPort());
$this->assertTrue($request->isSecure());
// trusted proxy via setTrustedProxies()
- Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2'));
+ Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
$this->assertEquals('3.3.3.3', $request->getClientIp());
$this->assertEquals('example.com', $request->getHost());
$this->assertEquals(80, $request->getPort());
$this->assertFalse($request->isSecure());
// check various X_FORWARDED_PROTO header values
- Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
+ Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
$request->headers->set('X_FORWARDED_PROTO', 'ssl');
$this->assertTrue($request->isSecure());
$request->headers->set('X_FORWARDED_PROTO', 'https, http');
$this->assertTrue($request->isSecure());
+ }
+
+ /**
+ * @group legacy
+ * @expectedDeprecation The "Symfony\Component\HttpFoundation\Request::setTrustedHeaderName()" method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the $trustedHeaderSet argument of the Request::setTrustedProxies() method instead.
+ */
+ public function testLegacyTrustedProxies()
+ {
+ $request = Request::create('http://example.com/');
+ $request->server->set('REMOTE_ADDR', '3.3.3.3');
+ $request->headers->set('X_FORWARDED_FOR', '1.1.1.1, 2.2.2.2');
+ $request->headers->set('X_FORWARDED_HOST', 'foo.example.com, real.example.com:8080');
+ $request->headers->set('X_FORWARDED_PROTO', 'https');
+ $request->headers->set('X_FORWARDED_PORT', 443);
+ $request->headers->set('X_MY_FOR', '3.3.3.3, 4.4.4.4');
+ $request->headers->set('X_MY_HOST', 'my.example.com');
+ $request->headers->set('X_MY_PROTO', 'http');
+ $request->headers->set('X_MY_PORT', 81);
+
+ Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
// custom header names
Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_MY_FOR');
$this->assertEquals(80, $request->getPort());
$this->assertFalse($request->isSecure());
- // reset
- Request::setTrustedProxies(array());
+ //reset
+ Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'FORWARDED');
Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_FORWARDED_FOR');
Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_FORWARDED_HOST');
Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_FORWARDED_PORT');
$this->assertFalse($request->isSecure());
// disabling proxy trusting
- Request::setTrustedProxies(array());
+ Request::setTrustedProxies(array(), Request::HEADER_FORWARDED);
$this->assertEquals('3.3.3.3', $request->getClientIp());
$this->assertEquals('example.com', $request->getHost());
$this->assertEquals(80, $request->getPort());
$this->assertFalse($request->isSecure());
// request is forwarded by a non-trusted proxy
- Request::setTrustedProxies(array('2.2.2.2'));
+ Request::setTrustedProxies(array('2.2.2.2'), Request::HEADER_FORWARDED);
$this->assertEquals('3.3.3.3', $request->getClientIp());
$this->assertEquals('example.com', $request->getHost());
$this->assertEquals(80, $request->getPort());
$this->assertFalse($request->isSecure());
// trusted proxy via setTrustedProxies()
- Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
+ Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_FORWARDED);
$this->assertEquals('1.1.1.1', $request->getClientIp());
$this->assertEquals('foo.example.com', $request->getHost());
$this->assertEquals(8080, $request->getPort());
$this->assertTrue($request->isSecure());
// trusted proxy via setTrustedProxies()
- Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2'));
+ Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2'), Request::HEADER_FORWARDED);
$this->assertEquals('3.3.3.3', $request->getClientIp());
$this->assertEquals('example.com', $request->getHost());
$this->assertEquals(80, $request->getPort());
$this->assertFalse($request->isSecure());
// check various X_FORWARDED_PROTO header values
- Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
+ Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_FORWARDED);
$request->headers->set('FORWARDED', 'proto=ssl');
$this->assertTrue($request->isSecure());
}
/**
+ * @group legacy
* @expectedException \InvalidArgumentException
*/
public function testSetTrustedProxiesInvalidHeaderName()
}
/**
+ * @group legacy
* @expectedException \InvalidArgumentException
*/
public function testGetTrustedProxiesInvalidHeaderName()
try {
$request->getHost();
$this->fail('Request::getHost() should throw an exception when host is not trusted.');
- } catch (\UnexpectedValueException $e) {
- $this->assertEquals('Untrusted Host "evil.com"', $e->getMessage());
+ } catch (SuspiciousOperationException $e) {
+ $this->assertEquals('Untrusted Host "evil.com".', $e->getMessage());
}
// trusted hosts
}
} else {
if (method_exists($this, 'expectException')) {
- $this->expectException('UnexpectedValueException');
+ $this->expectException(SuspiciousOperationException::class);
$this->expectExceptionMessage('Invalid Host');
} else {
- $this->setExpectedException('UnexpectedValueException', 'Invalid Host');
+ $this->setExpectedException(SuspiciousOperationException::class, 'Invalid Host');
}
$request->getHost();
/**
* @group legacy
- * @expectedDeprecation Checking only for cacheable HTTP methods with Symfony\Component\HttpFoundation\Request::isMethodSafe() is deprecated since version 3.2 and will throw an exception in 4.0. Disable checking only for cacheable methods by calling the method with `false` as first argument or use the Request::isMethodCacheable() instead.
+ * @expectedDeprecation Checking only for cacheable HTTP methods with Symfony\Component\HttpFoundation\Request::isMethodSafe() is deprecated since Symfony 3.2 and will throw an exception in 4.0. Disable checking only for cacheable methods by calling the method with `false` as first argument or use the Request::isMethodCacheable() instead.
*/
public function testMethodSafeChecksCacheable()
{
/**
* @dataProvider methodCacheableProvider
*/
- public function testMethodCacheable($method, $chacheable)
+ public function testMethodCacheable($method, $cacheable)
{
$request = new Request();
$request->setMethod($method);
- $this->assertEquals($chacheable, $request->isMethodCacheable());
+ $this->assertEquals($cacheable, $request->isMethodCacheable());
}
public function methodCacheableProvider()
);
}
+ /**
+ * @group legacy
+ */
+ public function testGetTrustedHeaderName()
+ {
+ Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_X_FORWARDED_ALL);
+
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
+ $this->assertSame('X_FORWARDED_FOR', Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
+ $this->assertSame('X_FORWARDED_HOST', Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
+ $this->assertSame('X_FORWARDED_PORT', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
+ $this->assertSame('X_FORWARDED_PROTO', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
+
+ Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_FORWARDED);
+
+ $this->assertSame('FORWARDED', Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
+
+ Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'A');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'B');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'C');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'D');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'E');
+
+ Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_FORWARDED);
+
+ $this->assertSame('A', Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
+
+ Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_X_FORWARDED_ALL);
+
+ $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
+ $this->assertSame('B', Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
+ $this->assertSame('C', Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
+ $this->assertSame('D', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
+ $this->assertSame('E', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
+
+ Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_FORWARDED);
+
+ $this->assertSame('A', Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
+
+ //reset
+ Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'FORWARDED');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_FORWARDED_FOR');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_FORWARDED_HOST');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_FORWARDED_PORT');
+ Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_FORWARDED_PROTO');
+ }
+
+ /**
+ * @dataProvider protocolVersionProvider
+ */
+ public function testProtocolVersion($serverProtocol, $trustedProxy, $via, $expected)
+ {
+ if ($trustedProxy) {
+ Request::setTrustedProxies(array('1.1.1.1'), -1);
+ }
+
+ $request = new Request();
+ $request->server->set('SERVER_PROTOCOL', $serverProtocol);
+ $request->server->set('REMOTE_ADDR', '1.1.1.1');
+ $request->headers->set('Via', $via);
+
+ $this->assertSame($expected, $request->getProtocolVersion());
+ }
+
+ public function protocolVersionProvider()
+ {
+ return array(
+ 'untrusted without via' => array('HTTP/2.0', false, '', 'HTTP/2.0'),
+ 'untrusted with via' => array('HTTP/2.0', false, '1.0 fred, 1.1 nowhere.com (Apache/1.1)', 'HTTP/2.0'),
+ 'trusted without via' => array('HTTP/2.0', true, '', 'HTTP/2.0'),
+ 'trusted with via' => array('HTTP/2.0', true, '1.0 fred, 1.1 nowhere.com (Apache/1.1)', 'HTTP/1.0'),
+ 'trusted with via and protocol name' => array('HTTP/2.0', true, 'HTTP/1.0 fred, HTTP/1.1 nowhere.com (Apache/1.1)', 'HTTP/1.0'),
+ 'trusted with broken via' => array('HTTP/2.0', true, 'HTTP/1^0 foo', 'HTTP/2.0'),
+ 'trusted with partially-broken via' => array('HTTP/2.0', true, '1.0 fred, foo', 'HTTP/1.0'),
+ );
+ }
+
public function nonstandardRequestsData()
{
return array(
{
public function getContent($asResource = false)
{
- return http_build_query(array('_method' => 'PUT', 'content' => 'mycontent'));
+ return http_build_query(array('_method' => 'PUT', 'content' => 'mycontent'), '', '&');
}
}