<?php
namespace Adawolfa\Nette\Application\Responses;
use Nette\Application\BadRequestException;
use Nette\Http;
use Nette\Application\IResponse;
* Response file with remote sources support.
*
* @author Adam Klvač <adam@klva.cz>
*/
class FileResponse implements IResponse
{
private $file;
private $name;
private $contentType;
private $forceDownload;
* @param string $file
* @param string|null $name
* @param string|null $contentType
* @param bool $forceDownload
*/
public function __construct($file, $name = null, $contentType = null, $forceDownload = true)
{
$this->file = $file;
$this->name = $name;
$this->contentType = $contentType;
$this->forceDownload = $forceDownload;
}
public function send(Http\IRequest $httpRequest, Http\IResponse $httpResponse): void
{
$stream = @fopen($this->file, 'rb');
if ($stream === false) {
throw new BadRequestException("File '{$this->file}' could not be opened.");
}
$name = $this->name;
$contentType = $this->contentType;
$charset = null;
$length = null;
if (isset($http_response_header)) {
foreach ($http_response_header as $header) {
if ($name === null && stripos($header, 'Content-Disposition:') === 0) {
if (preg_match('#^Content-Disposition: (inline|attachment);\s*filename(\*?)=(([^\']+)\'\')?(.+)$#i', $header, $matches)) {
if ($matches[2] === '*') {
$name = iconv($matches[4], 'UTF-8', rawurldecode($matches[5]));
} else {
$name = $matches[5];
}
}
}
if ($contentType === null && stripos($header, 'Content-Type:') === 0) {
list ($contentType, $charset) = explode(';', explode(':', $header . ';')[1]);
$contentType = trim($contentType) ?: null;
$charset = trim($charset) ?: null;
}
if ($length === null && stripos($header, 'Content-Length:') === 0) {
$length = trim(explode(':', $header)[1]);
}
}
} elseif (is_file($this->file)) {
$length = filesize($this->file);
}
if ($name === null) {
$name = basename(parse_url($this->file, PHP_URL_PATH));
}
if ($contentType === null) {
$contentType = 'application/octet-stream';
}
$httpResponse->setHeader(
'Content-Disposition',
($this->forceDownload ? 'attachment' : 'inline')
. '; filename*=UTF-8\'\''
. rawurlencode($name)
);
$httpResponse->setContentType($contentType, $charset);
if ($length !== null) {
$httpResponse->setHeader('Content-Length', $length);
}
while (!feof($stream)) {
print fread($stream, 4096);
}
fclose($stream);
}
}