SubRequestHandlerTest.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. foreach (self::$globalState[1] as $key => $name) {
  26. Request::setTrustedHeaderName($key, $name);
  27. }
  28. Request::setTrustedProxies(self::$globalState[0]);
  29. }
  30. public function testTrustedHeadersAreKept()
  31. {
  32. Request::setTrustedProxies(array('10.0.0.1'));
  33. $globalState = $this->getGlobalState();
  34. $request = Request::create('/');
  35. $request->server->set('REMOTE_ADDR', '10.0.0.1');
  36. $request->headers->set('X-Forwarded-For', '10.0.0.2');
  37. $request->headers->set('X-Forwarded-Host', 'Good');
  38. $request->headers->set('X-Forwarded-Port', '1234');
  39. $request->headers->set('X-Forwarded-Proto', 'https');
  40. $that = $this;
  41. $kernel = new TestSubRequestHandlerKernel(function ($request, $type, $catch) use ($that) {
  42. $that->assertSame('127.0.0.1', $request->server->get('REMOTE_ADDR'));
  43. $that->assertSame('10.0.0.2', $request->getClientIp());
  44. $that->assertSame('Good', $request->headers->get('X-Forwarded-Host'));
  45. $that->assertSame('1234', $request->headers->get('X-Forwarded-Port'));
  46. $that->assertSame('https', $request->headers->get('X-Forwarded-Proto'));
  47. });
  48. SubRequestHandler::handle($kernel, $request, HttpKernelInterface::MASTER_REQUEST, true);
  49. $this->assertSame($globalState, $this->getGlobalState());
  50. }
  51. public function testUntrustedHeadersAreRemoved()
  52. {
  53. $request = Request::create('/');
  54. $request->server->set('REMOTE_ADDR', '10.0.0.1');
  55. $request->headers->set('X-Forwarded-For', '10.0.0.2');
  56. $request->headers->set('X-Forwarded-Host', 'Evil');
  57. $request->headers->set('X-Forwarded-Port', '1234');
  58. $request->headers->set('X-Forwarded-Proto', 'http');
  59. $request->headers->set('Forwarded', 'Evil2');
  60. $that = $this;
  61. $kernel = new TestSubRequestHandlerKernel(function ($request, $type, $catch) use ($that) {
  62. $that->assertSame('127.0.0.1', $request->server->get('REMOTE_ADDR'));
  63. $that->assertSame('10.0.0.1', $request->getClientIp());
  64. $that->assertFalse($request->headers->has('X-Forwarded-Host'));
  65. $that->assertFalse($request->headers->has('X-Forwarded-Port'));
  66. $that->assertFalse($request->headers->has('X-Forwarded-Proto'));
  67. $that->assertSame('for="10.0.0.1";host="localhost";proto=http', $request->headers->get('Forwarded'));
  68. });
  69. SubRequestHandler::handle($kernel, $request, HttpKernelInterface::MASTER_REQUEST, true);
  70. $this->assertSame(self::$globalState, $this->getGlobalState());
  71. }
  72. public function testTrustedForwardedHeader()
  73. {
  74. Request::setTrustedProxies(array('10.0.0.1'));
  75. $globalState = $this->getGlobalState();
  76. $request = Request::create('/');
  77. $request->server->set('REMOTE_ADDR', '10.0.0.1');
  78. $request->headers->set('Forwarded', 'for="10.0.0.2";host="foo.bar";proto=https');
  79. $request->headers->set('X-Forwarded-Host', 'foo.bar');
  80. $request->headers->set('X-Forwarded-Proto', 'https');
  81. $that = $this;
  82. $kernel = new TestSubRequestHandlerKernel(function ($request, $type, $catch) use ($that) {
  83. $that->assertSame('127.0.0.1', $request->server->get('REMOTE_ADDR'));
  84. $that->assertSame('10.0.0.2', $request->getClientIp());
  85. $that->assertSame('foo.bar', $request->getHttpHost());
  86. $that->assertSame('https', $request->getScheme());
  87. $that->assertSame(443, $request->getPort());
  88. });
  89. SubRequestHandler::handle($kernel, $request, HttpKernelInterface::MASTER_REQUEST, true);
  90. $this->assertSame($globalState, $this->getGlobalState());
  91. }
  92. public function testTrustedXForwardedForHeader()
  93. {
  94. Request::setTrustedProxies(array('10.0.0.1'));
  95. $globalState = $this->getGlobalState();
  96. $request = Request::create('/');
  97. $request->server->set('REMOTE_ADDR', '10.0.0.1');
  98. $request->headers->set('X-Forwarded-For', '10.0.0.2');
  99. $request->headers->set('X-Forwarded-Host', 'foo.bar');
  100. $request->headers->set('X-Forwarded-Proto', 'https');
  101. $that = $this;
  102. $kernel = new TestSubRequestHandlerKernel(function ($request, $type, $catch) use ($that) {
  103. $that->assertSame('127.0.0.1', $request->server->get('REMOTE_ADDR'));
  104. $that->assertSame('10.0.0.2', $request->getClientIp());
  105. $that->assertSame('foo.bar', $request->getHttpHost());
  106. $that->assertSame('https', $request->getScheme());
  107. });
  108. SubRequestHandler::handle($kernel, $request, HttpKernelInterface::MASTER_REQUEST, true);
  109. $this->assertSame($globalState, $this->getGlobalState());
  110. }
  111. private function getGlobalState()
  112. {
  113. return array(
  114. Request::getTrustedProxies(),
  115. array(
  116. Request::HEADER_FORWARDED => Request::getTrustedHeaderName(Request::HEADER_FORWARDED),
  117. Request::HEADER_CLIENT_IP => Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP),
  118. Request::HEADER_CLIENT_HOST => Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST),
  119. Request::HEADER_CLIENT_PROTO => Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO),
  120. Request::HEADER_CLIENT_PORT => Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT),
  121. ),
  122. );
  123. }
  124. }
  125. class TestSubRequestHandlerKernel implements HttpKernelInterface
  126. {
  127. private $assertCallback;
  128. public function __construct(\Closure $assertCallback)
  129. {
  130. $this->assertCallback = $assertCallback;
  131. }
  132. public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true)
  133. {
  134. $assertCallback = $this->assertCallback;
  135. $assertCallback($request, $type, $catch);
  136. return new Response();
  137. }
  138. }