diff --git a/tests/unit/framework/web/ResponseTest.php b/tests/unit/framework/web/ResponseTest.php index b3d9080..2fde63d 100644 --- a/tests/unit/framework/web/ResponseTest.php +++ b/tests/unit/framework/web/ResponseTest.php @@ -41,7 +41,7 @@ class ResponseTest extends \yiiunit\TestCase static::$httpResponseCode = 200; } - public function ranges() + public function rightRanges() { // TODO test more cases for range requests and check for rfc compatibility // http://www.w3.org/Protocols/rfc2616/rfc2616.txt @@ -53,14 +53,14 @@ class ResponseTest extends \yiiunit\TestCase } /** - * @dataProvider ranges + * @dataProvider rightRanges */ public function testSendFileRanges($rangeHeader, $expectedHeader, $length, $expectedFile) { $content = $this->generateTestFileContent(); - $_SERVER['HTTP_RANGE'] = 'bytes=' . $rangeHeader; $sent = $this->runSendFile('testFile.txt', $content, null); + $this->assertEquals($expectedFile, $sent); $this->assertTrue(in_array('HTTP/1.1 206 Partial Content', static::$headers)); $this->assertTrue(in_array('Accept-Ranges: bytes', static::$headers)); @@ -69,6 +69,30 @@ class ResponseTest extends \yiiunit\TestCase $this->assertTrue(in_array('Content-Length: ' . $length, static::$headers)); } + public function wrongRanges() + { + // TODO test more cases for range requests and check for rfc compatibility + // http://www.w3.org/Protocols/rfc2616/rfc2616.txt + return array( + array('1-2,3-5,6-10'), // multiple range request not supported + array('5-1'), // last-byte-pos value is less than its first-byte-pos value + array('-100000'), // last-byte-pos bigger then content length + array('10000-'), // first-byte-pos bigger then content length + ); + } + + /** + * @dataProvider wrongRanges + */ + public function testSendFileWrongRanges($rangeHeader) + { + $this->setExpectedException('yii\base\HttpException', 'Requested Range Not Satisfiable'); + + $content = $this->generateTestFileContent(); + $_SERVER['HTTP_RANGE'] = 'bytes=' . $rangeHeader; + $this->runSendFile('testFile.txt', $content, null); + } + protected function generateTestFileContent() { return '12ёжик3456798áèabcdefghijklmnopqrstuvwxyz!"§$%&/(ёжик)=?'; @@ -83,4 +107,4 @@ class ResponseTest extends \yiiunit\TestCase $file = ob_get_clean(); return $file; } -} \ No newline at end of file +} diff --git a/yii/web/Response.php b/yii/web/Response.php index 954c999..3140c54 100644 --- a/yii/web/Response.php +++ b/yii/web/Response.php @@ -50,7 +50,7 @@ class Response extends \yii\base\Response if (isset($_SERVER['HTTP_RANGE'])) { // client sent us a multibyte range, can not hold this one for now - if (strpos(',', $_SERVER['HTTP_RANGE']) !== false) { + if (strpos($_SERVER['HTTP_RANGE'],',') !== false) { header("Content-Range: bytes $contentStart-$contentEnd/$fileSize"); throw new HttpException(416, 'Requested Range Not Satisfiable'); } @@ -63,14 +63,18 @@ class Response extends \yii\base\Response } else { $range = explode('-', $range); $contentStart = $range[0]; - $contentEnd = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $fileSize - 1; + + // check if the last-byte-pos presents in header + if ((isset($range[1]) && is_numeric($range[1]))) { + $contentEnd = $range[1]; + } } /* Check the range and make sure it's treated according to the specs. * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html */ // End bytes can not be larger than $end. - $contentEnd = ($contentEnd > $fileSize) ? $fileSize : $contentEnd; + $contentEnd = ($contentEnd > $fileSize) ? $fileSize -1 : $contentEnd; // Validate the requested range and return an error if it's not correct. $wrongContentStart = ($contentStart > $contentEnd || $contentStart > $fileSize - 1 || $contentStart < 0);