BinaryFileResponseTest.php 5.3 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\HttpFoundation\Tests;
  11. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpFoundation\ResponseHeaderBag;
  14. class BinaryFileResponseTest extends ResponseTestCase
  15. {
  16. public function testConstruction()
  17. {
  18. $response = new BinaryFileResponse('README.md', 404, array('X-Header' => 'Foo'), true, null, true, true);
  19. $this->assertEquals(404, $response->getStatusCode());
  20. $this->assertEquals('Foo', $response->headers->get('X-Header'));
  21. $this->assertTrue($response->headers->has('ETag'));
  22. $this->assertTrue($response->headers->has('Last-Modified'));
  23. $this->assertFalse($response->headers->has('Content-Disposition'));
  24. $response = BinaryFileResponse::create('README.md', 404, array(), true, ResponseHeaderBag::DISPOSITION_INLINE);
  25. $this->assertEquals(404, $response->getStatusCode());
  26. $this->assertFalse($response->headers->has('ETag'));
  27. $this->assertEquals('inline; filename="README.md"', $response->headers->get('Content-Disposition'));
  28. }
  29. /**
  30. * @expectedException \LogicException
  31. */
  32. public function testSetContent()
  33. {
  34. $response = new BinaryFileResponse('README.md');
  35. $response->setContent('foo');
  36. }
  37. public function testGetContent()
  38. {
  39. $response = new BinaryFileResponse('README.md');
  40. $this->assertFalse($response->getContent());
  41. }
  42. /**
  43. * @dataProvider provideRanges
  44. */
  45. public function testRequests($requestRange, $offset, $length, $responseRange)
  46. {
  47. $response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif')->setAutoEtag();
  48. // do a request to get the ETag
  49. $request = Request::create('/');
  50. $response->prepare($request);
  51. $etag = $response->headers->get('ETag');
  52. // prepare a request for a range of the testing file
  53. $request = Request::create('/');
  54. $request->headers->set('If-Range', $etag);
  55. $request->headers->set('Range', $requestRange);
  56. $file = fopen(__DIR__.'/File/Fixtures/test.gif', 'r');
  57. fseek($file, $offset);
  58. $data = fread($file, $length);
  59. fclose($file);
  60. $this->expectOutputString($data);
  61. $response = clone $response;
  62. $response->prepare($request);
  63. $response->sendContent();
  64. $this->assertEquals(206, $response->getStatusCode());
  65. $this->assertEquals('binary', $response->headers->get('Content-Transfer-Encoding'));
  66. $this->assertEquals($responseRange, $response->headers->get('Content-Range'));
  67. }
  68. public function provideRanges()
  69. {
  70. return array(
  71. array('bytes=1-4', 1, 4, 'bytes 1-4/35'),
  72. array('bytes=-5', 30, 5, 'bytes 30-34/35'),
  73. array('bytes=-35', 0, 35, 'bytes 0-34/35'),
  74. array('bytes=-40', 0, 35, 'bytes 0-34/35'),
  75. array('bytes=30-', 30, 5, 'bytes 30-34/35'),
  76. array('bytes=30-30', 30, 1, 'bytes 30-30/35'),
  77. array('bytes=30-34', 30, 5, 'bytes 30-34/35'),
  78. array('bytes=30-40', 30, 5, 'bytes 30-34/35')
  79. );
  80. }
  81. public function testXSendfile()
  82. {
  83. $request = Request::create('/');
  84. $request->headers->set('X-Sendfile-Type', 'X-Sendfile');
  85. BinaryFileResponse::trustXSendfileTypeHeader();
  86. $response = BinaryFileResponse::create('README.md');
  87. $response->prepare($request);
  88. $this->expectOutputString('');
  89. $response->sendContent();
  90. $this->assertContains('README.md', $response->headers->get('X-Sendfile'));
  91. }
  92. /**
  93. * @dataProvider getSampleXAccelMappings
  94. */
  95. public function testXAccelMapping($realpath, $mapping, $virtual)
  96. {
  97. $request = Request::create('/');
  98. $request->headers->set('X-Sendfile-Type', 'X-Accel-Redirect');
  99. $request->headers->set('X-Accel-Mapping', $mapping);
  100. $file = $this->getMockBuilder('Symfony\Component\HttpFoundation\File\File')
  101. ->disableOriginalConstructor()
  102. ->getMock();
  103. $file->expects($this->any())
  104. ->method('getRealPath')
  105. ->will($this->returnValue($realpath));
  106. $file->expects($this->any())
  107. ->method('isReadable')
  108. ->will($this->returnValue(true));
  109. BinaryFileResponse::trustXSendFileTypeHeader();
  110. $response = new BinaryFileResponse('README.md');
  111. $reflection = new \ReflectionObject($response);
  112. $property = $reflection->getProperty('file');
  113. $property->setAccessible(true);
  114. $property->setValue($response, $file);
  115. $response->prepare($request);
  116. $this->assertEquals($virtual, $response->headers->get('X-Accel-Redirect'));
  117. }
  118. public function getSampleXAccelMappings()
  119. {
  120. return array(
  121. array('/var/www/var/www/files/foo.txt', '/files/=/var/www/', '/files/var/www/files/foo.txt'),
  122. array('/home/foo/bar.txt', '/files/=/var/www/,/baz/=/home/foo/', '/baz/bar.txt'),
  123. );
  124. }
  125. protected function provideResponse()
  126. {
  127. return new BinaryFileResponse('README.md');
  128. }
  129. }