2015-08-17 17:00:26 -07:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\HttpFoundation\Tests ;
use Symfony\Component\HttpFoundation\BinaryFileResponse ;
use Symfony\Component\HttpFoundation\Request ;
use Symfony\Component\HttpFoundation\ResponseHeaderBag ;
use Symfony\Component\HttpFoundation\Tests\File\FakeFile ;
class BinaryFileResponseTest extends ResponseTestCase
{
public function testConstruction ()
{
$file = __DIR__ . '/../README.md' ;
$response = new BinaryFileResponse ( $file , 404 , array ( 'X-Header' => 'Foo' ), true , null , true , true );
$this -> assertEquals ( 404 , $response -> getStatusCode ());
$this -> assertEquals ( 'Foo' , $response -> headers -> get ( 'X-Header' ));
$this -> assertTrue ( $response -> headers -> has ( 'ETag' ));
$this -> assertTrue ( $response -> headers -> has ( 'Last-Modified' ));
$this -> assertFalse ( $response -> headers -> has ( 'Content-Disposition' ));
$response = BinaryFileResponse :: create ( $file , 404 , array (), true , ResponseHeaderBag :: DISPOSITION_INLINE );
$this -> assertEquals ( 404 , $response -> getStatusCode ());
$this -> assertFalse ( $response -> headers -> has ( 'ETag' ));
$this -> assertEquals ( 'inline; filename="README.md"' , $response -> headers -> get ( 'Content-Disposition' ));
}
/**
* @ expectedException \LogicException
*/
public function testSetContent ()
{
$response = new BinaryFileResponse ( __FILE__ );
$response -> setContent ( 'foo' );
}
public function testGetContent ()
{
$response = new BinaryFileResponse ( __FILE__ );
$this -> assertFalse ( $response -> getContent ());
}
/**
* @ dataProvider provideRanges
*/
public function testRequests ( $requestRange , $offset , $length , $responseRange )
{
2015-10-08 11:40:12 -07:00
$response = BinaryFileResponse :: create ( __DIR__ . '/File/Fixtures/test.gif' , 200 , array ( 'Content-Type' => 'application/octet-stream' )) -> setAutoEtag ();
2015-08-17 17:00:26 -07:00
// do a request to get the ETag
$request = Request :: create ( '/' );
$response -> prepare ( $request );
$etag = $response -> headers -> get ( 'ETag' );
// prepare a request for a range of the testing file
$request = Request :: create ( '/' );
$request -> headers -> set ( 'If-Range' , $etag );
$request -> headers -> set ( 'Range' , $requestRange );
$file = fopen ( __DIR__ . '/File/Fixtures/test.gif' , 'r' );
fseek ( $file , $offset );
$data = fread ( $file , $length );
fclose ( $file );
$this -> expectOutputString ( $data );
$response = clone $response ;
$response -> prepare ( $request );
$response -> sendContent ();
$this -> assertEquals ( 206 , $response -> getStatusCode ());
$this -> assertEquals ( $responseRange , $response -> headers -> get ( 'Content-Range' ));
}
public function provideRanges ()
{
return array (
array ( 'bytes=1-4' , 1 , 4 , 'bytes 1-4/35' ),
array ( 'bytes=-5' , 30 , 5 , 'bytes 30-34/35' ),
array ( 'bytes=30-' , 30 , 5 , 'bytes 30-34/35' ),
array ( 'bytes=30-30' , 30 , 1 , 'bytes 30-30/35' ),
array ( 'bytes=30-34' , 30 , 5 , 'bytes 30-34/35' ),
);
}
/**
* @ dataProvider provideFullFileRanges
*/
public function testFullFileRequests ( $requestRange )
{
2015-10-08 11:40:12 -07:00
$response = BinaryFileResponse :: create ( __DIR__ . '/File/Fixtures/test.gif' , 200 , array ( 'Content-Type' => 'application/octet-stream' )) -> setAutoEtag ();
2015-08-17 17:00:26 -07:00
// prepare a request for a range of the testing file
$request = Request :: create ( '/' );
$request -> headers -> set ( 'Range' , $requestRange );
$file = fopen ( __DIR__ . '/File/Fixtures/test.gif' , 'r' );
$data = fread ( $file , 35 );
fclose ( $file );
$this -> expectOutputString ( $data );
$response = clone $response ;
$response -> prepare ( $request );
$response -> sendContent ();
$this -> assertEquals ( 200 , $response -> getStatusCode ());
}
public function provideFullFileRanges ()
{
return array (
array ( 'bytes=0-' ),
array ( 'bytes=0-34' ),
array ( 'bytes=-35' ),
// Syntactical invalid range-request should also return the full resource
array ( 'bytes=20-10' ),
array ( 'bytes=50-40' ),
);
}
/**
* @ dataProvider provideInvalidRanges
*/
public function testInvalidRequests ( $requestRange )
{
2015-10-08 11:40:12 -07:00
$response = BinaryFileResponse :: create ( __DIR__ . '/File/Fixtures/test.gif' , 200 , array ( 'Content-Type' => 'application/octet-stream' )) -> setAutoEtag ();
2015-08-17 17:00:26 -07:00
// prepare a request for a range of the testing file
$request = Request :: create ( '/' );
$request -> headers -> set ( 'Range' , $requestRange );
$response = clone $response ;
$response -> prepare ( $request );
$response -> sendContent ();
$this -> assertEquals ( 416 , $response -> getStatusCode ());
#$this->assertEquals('', $response->headers->get('Content-Range'));
}
public function provideInvalidRanges ()
{
return array (
array ( 'bytes=-40' ),
array ( 'bytes=30-40' ),
);
}
public function testXSendfile ()
{
$request = Request :: create ( '/' );
$request -> headers -> set ( 'X-Sendfile-Type' , 'X-Sendfile' );
BinaryFileResponse :: trustXSendfileTypeHeader ();
2015-10-08 11:40:12 -07:00
$response = BinaryFileResponse :: create ( __DIR__ . '/../README.md' , 200 , array ( 'Content-Type' => 'application/octet-stream' ));
2015-08-17 17:00:26 -07:00
$response -> prepare ( $request );
$this -> expectOutputString ( '' );
$response -> sendContent ();
$this -> assertContains ( 'README.md' , $response -> headers -> get ( 'X-Sendfile' ));
}
/**
* @ dataProvider getSampleXAccelMappings
*/
public function testXAccelMapping ( $realpath , $mapping , $virtual )
{
$request = Request :: create ( '/' );
$request -> headers -> set ( 'X-Sendfile-Type' , 'X-Accel-Redirect' );
$request -> headers -> set ( 'X-Accel-Mapping' , $mapping );
$file = new FakeFile ( $realpath , __DIR__ . '/File/Fixtures/test' );
2015-08-27 12:03:05 -07:00
BinaryFileResponse :: trustXSendfileTypeHeader ();
2015-10-08 11:40:12 -07:00
$response = new BinaryFileResponse ( $file , 200 , array ( 'Content-Type' => 'application/octet-stream' ));
2015-08-17 17:00:26 -07:00
$reflection = new \ReflectionObject ( $response );
$property = $reflection -> getProperty ( 'file' );
$property -> setAccessible ( true );
$property -> setValue ( $response , $file );
$response -> prepare ( $request );
$this -> assertEquals ( $virtual , $response -> headers -> get ( 'X-Accel-Redirect' ));
}
public function testDeleteFileAfterSend ()
{
$request = Request :: create ( '/' );
$path = __DIR__ . '/File/Fixtures/to_delete' ;
touch ( $path );
$realPath = realpath ( $path );
$this -> assertFileExists ( $realPath );
2015-10-08 11:40:12 -07:00
$response = new BinaryFileResponse ( $realPath , 200 , array ( 'Content-Type' => 'application/octet-stream' ));
2015-08-17 17:00:26 -07:00
$response -> deleteFileAfterSend ( true );
$response -> prepare ( $request );
$response -> sendContent ();
$this -> assertFileNotExists ( $path );
}
public function testAcceptRangeOnUnsafeMethods ()
{
$request = Request :: create ( '/' , 'POST' );
2015-10-08 11:40:12 -07:00
$response = BinaryFileResponse :: create ( __DIR__ . '/File/Fixtures/test.gif' , 200 , array ( 'Content-Type' => 'application/octet-stream' ));
2015-08-17 17:00:26 -07:00
$response -> prepare ( $request );
$this -> assertEquals ( 'none' , $response -> headers -> get ( 'Accept-Ranges' ));
}
public function testAcceptRangeNotOverriden ()
{
$request = Request :: create ( '/' , 'POST' );
2015-10-08 11:40:12 -07:00
$response = BinaryFileResponse :: create ( __DIR__ . '/File/Fixtures/test.gif' , 200 , array ( 'Content-Type' => 'application/octet-stream' ));
2015-08-17 17:00:26 -07:00
$response -> headers -> set ( 'Accept-Ranges' , 'foo' );
$response -> prepare ( $request );
$this -> assertEquals ( 'foo' , $response -> headers -> get ( 'Accept-Ranges' ));
}
public function getSampleXAccelMappings ()
{
return array (
array ( '/var/www/var/www/files/foo.txt' , '/var/www/=/files/' , '/files/var/www/files/foo.txt' ),
array ( '/home/foo/bar.txt' , '/var/www/=/files/,/home/foo/=/baz/' , '/baz/bar.txt' ),
);
}
protected function provideResponse ()
{
2015-10-08 11:40:12 -07:00
return new BinaryFileResponse ( __DIR__ . '/../README.md' , 200 , array ( 'Content-Type' => 'application/octet-stream' ));
2015-08-17 17:00:26 -07:00
}
public static function tearDownAfterClass ()
{
$path = __DIR__ . '/../Fixtures/to_delete' ;
if ( file_exists ( $path )) {
@ unlink ( $path );
}
}
}