EsiTest.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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\Esi;
  15. class EsiTest extends TestCase
  16. {
  17. public function testHasSurrogateEsiCapability()
  18. {
  19. $esi = new Esi();
  20. $request = Request::create('/');
  21. $request->headers->set('Surrogate-Capability', 'abc="ESI/1.0"');
  22. $this->assertTrue($esi->hasSurrogateCapability($request));
  23. $request = Request::create('/');
  24. $request->headers->set('Surrogate-Capability', 'foobar');
  25. $this->assertFalse($esi->hasSurrogateCapability($request));
  26. $request = Request::create('/');
  27. $this->assertFalse($esi->hasSurrogateCapability($request));
  28. }
  29. public function testAddSurrogateEsiCapability()
  30. {
  31. $esi = new Esi();
  32. $request = Request::create('/');
  33. $esi->addSurrogateCapability($request);
  34. $this->assertEquals('symfony="ESI/1.0"', $request->headers->get('Surrogate-Capability'));
  35. $esi->addSurrogateCapability($request);
  36. $this->assertEquals('symfony="ESI/1.0", symfony="ESI/1.0"', $request->headers->get('Surrogate-Capability'));
  37. }
  38. public function testAddSurrogateControl()
  39. {
  40. $esi = new Esi();
  41. $response = new Response('foo <esi:include src="" />');
  42. $esi->addSurrogateControl($response);
  43. $this->assertEquals('content="ESI/1.0"', $response->headers->get('Surrogate-Control'));
  44. $response = new Response('foo');
  45. $esi->addSurrogateControl($response);
  46. $this->assertEquals('', $response->headers->get('Surrogate-Control'));
  47. }
  48. public function testNeedsEsiParsing()
  49. {
  50. $esi = new Esi();
  51. $response = new Response();
  52. $response->headers->set('Surrogate-Control', 'content="ESI/1.0"');
  53. $this->assertTrue($esi->needsParsing($response));
  54. $response = new Response();
  55. $this->assertFalse($esi->needsParsing($response));
  56. }
  57. public function testRenderIncludeTag()
  58. {
  59. $esi = new Esi();
  60. $this->assertEquals('<esi:include src="/" onerror="continue" alt="/alt" />', $esi->renderIncludeTag('/', '/alt', true));
  61. $this->assertEquals('<esi:include src="/" alt="/alt" />', $esi->renderIncludeTag('/', '/alt', false));
  62. $this->assertEquals('<esi:include src="/" onerror="continue" />', $esi->renderIncludeTag('/'));
  63. $this->assertEquals('<esi:comment text="some comment" />'."\n".'<esi:include src="/" onerror="continue" alt="/alt" />', $esi->renderIncludeTag('/', '/alt', true, 'some comment'));
  64. }
  65. public function testProcessDoesNothingIfContentTypeIsNotHtml()
  66. {
  67. $esi = new Esi();
  68. $request = Request::create('/');
  69. $response = new Response();
  70. $response->headers->set('Content-Type', 'text/plain');
  71. $esi->process($request, $response);
  72. $this->assertFalse($response->headers->has('x-body-eval'));
  73. }
  74. public function testMultilineEsiRemoveTagsAreRemoved()
  75. {
  76. $esi = new Esi();
  77. $request = Request::create('/');
  78. $response = new Response('<esi:remove> <a href="http://www.example.com">www.example.com</a> </esi:remove> Keep this'."<esi:remove>\n <a>www.example.com</a> </esi:remove> And this");
  79. $esi->process($request, $response);
  80. $this->assertEquals(' Keep this And this', $response->getContent());
  81. }
  82. public function testCommentTagsAreRemoved()
  83. {
  84. $esi = new Esi();
  85. $request = Request::create('/');
  86. $response = new Response('<esi:comment text="some comment &gt;" /> Keep this');
  87. $esi->process($request, $response);
  88. $this->assertEquals(' Keep this', $response->getContent());
  89. }
  90. public function testProcess()
  91. {
  92. $esi = new Esi();
  93. $request = Request::create('/');
  94. $response = new Response('foo <esi:comment text="some comment" /><esi:include src="..." alt="alt" onerror="continue" />');
  95. $esi->process($request, $response);
  96. $this->assertEquals('foo <?php echo $this->surrogate->handle($this, \'...\', \'alt\', true) ?>'."\n", $response->getContent());
  97. $this->assertEquals('ESI', $response->headers->get('x-body-eval'));
  98. $response = new Response('foo <esi:comment text="some comment" /><esi:include src="foo\'" alt="bar\'" onerror="continue" />');
  99. $esi->process($request, $response);
  100. $this->assertEquals('foo <?php echo $this->surrogate->handle($this, \'foo\\\'\', \'bar\\\'\', true) ?>'."\n", $response->getContent());
  101. $response = new Response('foo <esi:include src="..." />');
  102. $esi->process($request, $response);
  103. $this->assertEquals('foo <?php echo $this->surrogate->handle($this, \'...\', \'\', false) ?>'."\n", $response->getContent());
  104. $response = new Response('foo <esi:include src="..."></esi:include>');
  105. $esi->process($request, $response);
  106. $this->assertEquals('foo <?php echo $this->surrogate->handle($this, \'...\', \'\', false) ?>'."\n", $response->getContent());
  107. }
  108. public function testProcessEscapesPhpTags()
  109. {
  110. $esi = new Esi();
  111. $request = Request::create('/');
  112. $response = new Response('<?php <? <% <script language=php>');
  113. $esi->process($request, $response);
  114. $this->assertEquals('<?php echo "<?"; ?>php <?php echo "<?"; ?> <?php echo "<%"; ?> <?php echo "<s"; ?>cript language=php>', $response->getContent());
  115. }
  116. /**
  117. * @expectedException \RuntimeException
  118. */
  119. public function testProcessWhenNoSrcInAnEsi()
  120. {
  121. $esi = new Esi();
  122. $request = Request::create('/');
  123. $response = new Response('foo <esi:include />');
  124. $esi->process($request, $response);
  125. }
  126. public function testProcessRemoveSurrogateControlHeader()
  127. {
  128. $esi = new Esi();
  129. $request = Request::create('/');
  130. $response = new Response('foo <esi:include src="..." />');
  131. $response->headers->set('Surrogate-Control', 'content="ESI/1.0"');
  132. $esi->process($request, $response);
  133. $this->assertEquals('ESI', $response->headers->get('x-body-eval'));
  134. $response->headers->set('Surrogate-Control', 'no-store, content="ESI/1.0"');
  135. $esi->process($request, $response);
  136. $this->assertEquals('ESI', $response->headers->get('x-body-eval'));
  137. $this->assertEquals('no-store', $response->headers->get('surrogate-control'));
  138. $response->headers->set('Surrogate-Control', 'content="ESI/1.0", no-store');
  139. $esi->process($request, $response);
  140. $this->assertEquals('ESI', $response->headers->get('x-body-eval'));
  141. $this->assertEquals('no-store', $response->headers->get('surrogate-control'));
  142. }
  143. public function testHandle()
  144. {
  145. $esi = new Esi();
  146. $cache = $this->getCache(Request::create('/'), new Response('foo'));
  147. $this->assertEquals('foo', $esi->handle($cache, '/', '/alt', true));
  148. }
  149. /**
  150. * @expectedException \RuntimeException
  151. */
  152. public function testHandleWhenResponseIsNot200()
  153. {
  154. $esi = new Esi();
  155. $response = new Response('foo');
  156. $response->setStatusCode(404);
  157. $cache = $this->getCache(Request::create('/'), $response);
  158. $esi->handle($cache, '/', '/alt', false);
  159. }
  160. public function testHandleWhenResponseIsNot200AndErrorsAreIgnored()
  161. {
  162. $esi = new Esi();
  163. $response = new Response('foo');
  164. $response->setStatusCode(404);
  165. $cache = $this->getCache(Request::create('/'), $response);
  166. $this->assertEquals('', $esi->handle($cache, '/', '/alt', true));
  167. }
  168. public function testHandleWhenResponseIsNot200AndAltIsPresent()
  169. {
  170. $esi = new Esi();
  171. $response1 = new Response('foo');
  172. $response1->setStatusCode(404);
  173. $response2 = new Response('bar');
  174. $cache = $this->getCache(Request::create('/'), [$response1, $response2]);
  175. $this->assertEquals('bar', $esi->handle($cache, '/', '/alt', false));
  176. }
  177. protected function getCache($request, $response)
  178. {
  179. $cache = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpCache\HttpCache')->setMethods(['getRequest', 'handle'])->disableOriginalConstructor()->getMock();
  180. $cache->expects($this->any())
  181. ->method('getRequest')
  182. ->will($this->returnValue($request))
  183. ;
  184. if (\is_array($response)) {
  185. $cache->expects($this->any())
  186. ->method('handle')
  187. ->will($this->onConsecutiveCalls(...$response))
  188. ;
  189. } else {
  190. $cache->expects($this->any())
  191. ->method('handle')
  192. ->will($this->returnValue($response))
  193. ;
  194. }
  195. return $cache;
  196. }
  197. }