SubRequestHandlerTest.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\HttpKernel\Tests\HttpCache;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpFoundation\Response;
  14. use Symfony\Component\HttpKernel\HttpCache\SubRequestHandler;
  15. use Symfony\Component\HttpKernel\HttpKernelInterface;
  16. class SubRequestHandlerTest extends TestCase
  17. {
  18. private static $globalState;
  19. protected function setUp()
  20. {
  21. self::$globalState = $this->getGlobalState();
  22. }
  23. protected function tearDown()
  24. {
  25. Request::setTrustedProxies(self::$globalState[0], self::$globalState[1]);
  26. }
  27. public function testTrustedHeadersAreKept()
  28. {
  29. Request::setTrustedProxies(['10.0.0.1'], -1);
  30. $globalState = $this->getGlobalState();
  31. $request = Request::create('/');
  32. $request->server->set('REMOTE_ADDR', '10.0.0.1');
  33. $request->headers->set('X-Forwarded-For', '10.0.0.2');
  34. $request->headers->set('X-Forwarded-Host', 'Good');
  35. $request->headers->set('X-Forwarded-Port', '1234');
  36. $request->headers->set('X-Forwarded-Proto', 'https');
  37. $kernel = new TestSubRequestHandlerKernel(function ($request, $type, $catch) {
  38. $this->assertSame('127.0.0.1', $request->server->get('REMOTE_ADDR'));
  39. $this->assertSame('10.0.0.2', $request->getClientIp());
  40. $this->assertSame('Good', $request->headers->get('X-Forwarded-Host'));
  41. $this->assertSame('1234', $request->headers->get('X-Forwarded-Port'));
  42. $this->assertSame('https', $request->headers->get('X-Forwarded-Proto'));
  43. });
  44. SubRequestHandler::handle($kernel, $request, HttpKernelInterface::MASTER_REQUEST, true);
  45. $this->assertSame($globalState, $this->getGlobalState());
  46. }
  47. public function testUntrustedHeadersAreRemoved()
  48. {
  49. $request = Request::create('/');
  50. $request->server->set('REMOTE_ADDR', '10.0.0.1');
  51. $request->headers->set('X-Forwarded-For', '10.0.0.2');
  52. $request->headers->set('X-Forwarded-Host', 'Evil');
  53. $request->headers->set('X-Forwarded-Port', '1234');
  54. $request->headers->set('X-Forwarded-Proto', 'http');
  55. $request->headers->set('Forwarded', 'Evil2');
  56. $kernel = new TestSubRequestHandlerKernel(function ($request, $type, $catch) {
  57. $this->assertSame('127.0.0.1', $request->server->get('REMOTE_ADDR'));
  58. $this->assertSame('10.0.0.1', $request->getClientIp());
  59. $this->assertFalse($request->headers->has('X-Forwarded-Host'));
  60. $this->assertFalse($request->headers->has('X-Forwarded-Port'));
  61. $this->assertFalse($request->headers->has('X-Forwarded-Proto'));
  62. $this->assertSame('for="10.0.0.1";host="localhost";proto=http', $request->headers->get('Forwarded'));
  63. });
  64. SubRequestHandler::handle($kernel, $request, HttpKernelInterface::MASTER_REQUEST, true);
  65. $this->assertSame(self::$globalState, $this->getGlobalState());
  66. }
  67. public function testTrustedForwardedHeader()
  68. {
  69. Request::setTrustedProxies(['10.0.0.1'], -1);
  70. $globalState = $this->getGlobalState();
  71. $request = Request::create('/');
  72. $request->server->set('REMOTE_ADDR', '10.0.0.1');
  73. $request->headers->set('Forwarded', 'for="10.0.0.2";host="foo.bar:1234";proto=https');
  74. $kernel = new TestSubRequestHandlerKernel(function ($request, $type, $catch) {
  75. $this->assertSame('127.0.0.1', $request->server->get('REMOTE_ADDR'));
  76. $this->assertSame('10.0.0.2', $request->getClientIp());
  77. $this->assertSame('foo.bar:1234', $request->getHttpHost());
  78. $this->assertSame('https', $request->getScheme());
  79. $this->assertSame(1234, $request->getPort());
  80. });
  81. SubRequestHandler::handle($kernel, $request, HttpKernelInterface::MASTER_REQUEST, true);
  82. $this->assertSame($globalState, $this->getGlobalState());
  83. }
  84. public function testTrustedXForwardedForHeader()
  85. {
  86. Request::setTrustedProxies(['10.0.0.1'], -1);
  87. $globalState = $this->getGlobalState();
  88. $request = Request::create('/');
  89. $request->server->set('REMOTE_ADDR', '10.0.0.1');
  90. $request->headers->set('X-Forwarded-For', '10.0.0.2');
  91. $request->headers->set('X-Forwarded-Host', 'foo.bar');
  92. $request->headers->set('X-Forwarded-Proto', 'https');
  93. $kernel = new TestSubRequestHandlerKernel(function ($request, $type, $catch) {
  94. $this->assertSame('127.0.0.1', $request->server->get('REMOTE_ADDR'));
  95. $this->assertSame('10.0.0.2', $request->getClientIp());
  96. $this->assertSame('foo.bar', $request->getHttpHost());
  97. $this->assertSame('https', $request->getScheme());
  98. });
  99. SubRequestHandler::handle($kernel, $request, HttpKernelInterface::MASTER_REQUEST, true);
  100. $this->assertSame($globalState, $this->getGlobalState());
  101. }
  102. private function getGlobalState()
  103. {
  104. return [
  105. Request::getTrustedProxies(),
  106. Request::getTrustedHeaderSet(),
  107. ];
  108. }
  109. }
  110. class TestSubRequestHandlerKernel implements HttpKernelInterface
  111. {
  112. private $assertCallback;
  113. public function __construct(\Closure $assertCallback)
  114. {
  115. $this->assertCallback = $assertCallback;
  116. }
  117. public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true)
  118. {
  119. $assertCallback = $this->assertCallback;
  120. $assertCallback($request, $type, $catch);
  121. return new Response();
  122. }
  123. }