Commit c6c29db9 by Paweł 'Zibi' Zaremba Committed by Qiang Xue

Fixes #4636: Added `yii\web\Response::setDownloadHeaders()`

parent 4846643f
...@@ -180,6 +180,7 @@ Yii Framework 2 Change Log ...@@ -180,6 +180,7 @@ Yii Framework 2 Change Log
- Enh #4602: Added $key param in ActionColumn buttons Closure call (disem) - Enh #4602: Added $key param in ActionColumn buttons Closure call (disem)
- Enh #4607: AR model will throw an exception if it does not have a primary key to avoid updating/deleting data massively (qiangxue) - Enh #4607: AR model will throw an exception if it does not have a primary key to avoid updating/deleting data massively (qiangxue)
- Enh #4630: Added automatic generating of unique slug value to `yii\behaviors\Sluggable` (klimov-paul) - Enh #4630: Added automatic generating of unique slug value to `yii\behaviors\Sluggable` (klimov-paul)
- Enh #4636: Added `yii\web\Response::setDownloadHeaders()` (pawzar)
- Enh #4644: Added `\yii\db\Schema::createColumnSchema()` to be able to customize column schema used (mcd-php) - Enh #4644: Added `\yii\db\Schema::createColumnSchema()` to be able to customize column schema used (mcd-php)
- Enh #4656: HtmlPurifier helper config can now be a closure to change the purifier config object after it was created (Alex-Code) - Enh #4656: HtmlPurifier helper config can now be a closure to change the purifier config object after it was created (Alex-Code)
- Enh #4691: Encoding on `ActiveForm` and `ActiveField` validation errors is now configurable (Alex-Code) - Enh #4691: Encoding on `ActiveForm` and `ActiveField` validation errors is now configurable (Alex-Code)
......
...@@ -455,24 +455,19 @@ class Response extends \yii\base\Response ...@@ -455,24 +455,19 @@ class Response extends \yii\base\Response
public function sendContentAsFile($content, $attachmentName, $mimeType = 'application/octet-stream') public function sendContentAsFile($content, $attachmentName, $mimeType = 'application/octet-stream')
{ {
$headers = $this->getHeaders(); $headers = $this->getHeaders();
$contentLength = StringHelper::byteLength($content); $contentLength = StringHelper::byteLength($content);
$range = $this->getHttpRange($contentLength); $range = $this->getHttpRange($contentLength);
if ($range === false) { if ($range === false) {
$headers->set('Content-Range', "bytes */$contentLength"); $headers->set('Content-Range', "bytes */$contentLength");
throw new HttpException(416, 'Requested range not satisfiable'); throw new HttpException(416, 'Requested range not satisfiable');
} }
$headers->setDefault('Pragma', 'public') $this->setDownloadHeaders($attachmentName, $mimeType, $contentLength);
->setDefault('Accept-Ranges', 'bytes')
->setDefault('Expires', '0')
->setDefault('Content-Type', $mimeType)
->setDefault('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->setDefault('Content-Transfer-Encoding', 'binary')
->setDefault('Content-Length', StringHelper::byteLength($content))
->setDefault('Content-Disposition', "attachment; filename=\"$attachmentName\"");
list($begin, $end) = $range; list($begin, $end) = $range;
if ($begin !=0 || $end != $contentLength - 1) { if ($begin != 0 || $end != $contentLength - 1) {
$this->setStatusCode(206); $this->setStatusCode(206);
$headers->set('Content-Range', "bytes $begin-$end/$contentLength"); $headers->set('Content-Range', "bytes $begin-$end/$contentLength");
$this->content = StringHelper::byteSubstr($content, $begin, $end - $begin + 1); $this->content = StringHelper::byteSubstr($content, $begin, $end - $begin + 1);
...@@ -500,7 +495,7 @@ class Response extends \yii\base\Response ...@@ -500,7 +495,7 @@ class Response extends \yii\base\Response
*/ */
public function sendStreamAsFile($handle, $attachmentName, $mimeType = 'application/octet-stream') public function sendStreamAsFile($handle, $attachmentName, $mimeType = 'application/octet-stream')
{ {
$headers = $this->getHeaders(); $headers = $this->getHeaders();
fseek($handle, 0, SEEK_END); fseek($handle, 0, SEEK_END);
$fileSize = ftell($handle); $fileSize = ftell($handle);
...@@ -511,25 +506,46 @@ class Response extends \yii\base\Response ...@@ -511,25 +506,46 @@ class Response extends \yii\base\Response
} }
list($begin, $end) = $range; list($begin, $end) = $range;
if ($begin !=0 || $end != $fileSize - 1) { if ($begin != 0 || $end != $fileSize - 1) {
$this->setStatusCode(206); $this->setStatusCode(206);
$headers->set('Content-Range', "bytes $begin-$end/$fileSize"); $headers->set('Content-Range', "bytes $begin-$end/$fileSize");
} else { } else {
$this->setStatusCode(200); $this->setStatusCode(200);
} }
$length = $end - $begin + 1; $this->setDownloadHeaders($attachmentName, $mimeType, $end - $begin + 1);
$this->format = self::FORMAT_RAW;
$this->stream = [$handle, $begin, $end];
return $this;
}
/**
* Sets a default set of HTTP headers for file downloading purpose.
* @param string $attachmentName the attachment file name
* @param string $mimeType the MIME type for the response. If null, `Content-Type` header will NOT be set.
* @param integer $contentLength the byte length of the file being downloaded. If null, `Content-Length` header will NOT be set.
* @return static the response object itself
*/
public function setDownloadHeaders($attachmentName, $mimeType = null, $contentLength = null)
{
$headers = $this->getHeaders();
$headers->setDefault('Pragma', 'public') $headers->setDefault('Pragma', 'public')
->setDefault('Accept-Ranges', 'bytes') ->setDefault('Accept-Ranges', 'bytes')
->setDefault('Expires', '0') ->setDefault('Expires', '0')
->setDefault('Content-Type', $mimeType)
->setDefault('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') ->setDefault('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->setDefault('Content-Transfer-Encoding', 'binary') ->setDefault('Content-Transfer-Encoding', 'binary')
->setDefault('Content-Length', $length)
->setDefault('Content-Disposition', "attachment; filename=\"$attachmentName\""); ->setDefault('Content-Disposition', "attachment; filename=\"$attachmentName\"");
$this->format = self::FORMAT_RAW;
$this->stream = [$handle, $begin, $end]; if ($mimeType !== null) {
$headers->setDefault('Content-Type', $mimeType);
}
if ($contentLength !== null) {
$headers->setDefault('Content-Length', $contentLength);
}
return $this; return $this;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment