static function view(array $fileData, $options = array())
{
if (!array_key_exists("tmp_name", $fileData) || empty($fileData["tmp_name"]))
return false;
/** @global CMain $APPLICATION */
global $APPLICATION;
$fastDownload = (COption::GetOptionString('main', 'bx_fast_download', 'N') == 'Y');
$attachment_name = "";
$content_type = (array_key_exists("type", $fileData) && !empty($fileData["type"]) ? $fileData["type"] : "");
$cache_time = 10800;
$fromClouds = false;
$filetime = 0;
if(is_array($options))
{
if(isset($options["content_type"]))
$content_type = $options["content_type"];
if(isset($options["specialchars"]))
$specialchars = $options["specialchars"];
if(isset($options["force_download"]))
$force_download = $options["force_download"];
if(isset($options["cache_time"]))
$cache_time = intval($options["cache_time"]);
if(isset($options["attachment_name"]))
$attachment_name = $options["attachment_name"];
}
if($cache_time < 0)
$cache_time = 0;
$name = str_replace(array("n", "r"), '', $fileData["name"]);
if ($attachment_name)
$attachment_name = str_replace(array("n", "r"), '', $attachment_name);
else
$attachment_name = $name;
$content_type = WebMimeType::normalize($content_type);
$src = null;
$file = null;
if (mb_strpos($fileData["tmp_name"], CTempFile::GetAbsoluteRoot()) === 0)
{
$file = new BitrixMainIOFile($fileData["tmp_name"]);
try
{
$src = $file->open(BitrixMainIOFileStreamOpenMode::READ);
}
catch(BitrixMainIOIoException $e)
{
return false;
}
$filetime = $file->getModificationTime();
}
else
{
$fromClouds = true;
}
$APPLICATION->RestartBuffer();
$cur_pos = 0;
$filesize = $fileData["size"];
$size = $filesize-1;
$server = Application::getInstance()->getContext()->getServer();
$p = $server->get("HTTP_RANGE") && mb_strpos($server->get("HTTP_RANGE"), "=");
if(intval($p)>0)
{
$bytes = mb_substr($server->get("HTTP_RANGE"), $p + 1);
$p = mb_strpos($bytes, "-");
if($p !== false)
{
$cur_pos = floatval(mb_substr($bytes, 0, $p));
$size = floatval(mb_substr($bytes, $p + 1));
if ($size <= 0)
{
$size = $filesize - 1;
}
if ($cur_pos > $size)
{
$cur_pos = 0;
$size = $filesize - 1;
}
}
}
if ($server->getRequestMethod() == "HEAD")
{
CHTTP::SetStatus("200 OK");
header("Accept-Ranges: bytes");
header("Content-Type: ".$content_type);
header("Content-Length: ".($size-$cur_pos+1));
if($filetime > 0)
header("Last-Modified: ".date("r", $filetime));
}
else
{
$lastModified = '';
if($cache_time > 0)
{
//Handle ETag
$ETag = md5($fileData["tmp_name"].$filesize.$filetime);
if ($server->get("HTTP_IF_NONE_MATCH") === $ETag)
{
CHTTP::SetStatus("304 Not Modified");
header("Cache-Control: private, max-age=".$cache_time.", pre-check=".$cache_time);
die();
}
header("ETag: ".$ETag);
//Handle Last Modified
if($filetime > 0)
{
$lastModified = gmdate('D, d M Y H:i:s', $filetime).' GMT';
if ($server->get("HTTP_IF_NONE_MATCH") === $lastModified)
{
CHTTP::SetStatus("304 Not Modified");
header("Cache-Control: private, max-age=".$cache_time.", pre-check=".$cache_time);
die();
}
}
}
$utfName = Uri::urnEncode($attachment_name, "UTF-8");
$translitName = CUtil::translit($attachment_name, LANGUAGE_ID, array(
"max_len" => 1024,
"safe_chars" => ".",
"replace_space" => '-',
"change_case" => false,
));
//Disable zlib for old versions of php <= 5.3.0
//it has broken Content-Length handling
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
if($cur_pos > 0)
CHTTP::SetStatus("206 Partial Content");
else
CHTTP::SetStatus("200 OK");
header("Content-Type: ".$content_type);
header("Content-Disposition: attachment; filename="".$translitName.""; filename*=utf-8''".$utfName);
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".($size-$cur_pos+1));
if(is_resource($src))
{
header("Accept-Ranges: bytes");
header("Content-Range: bytes ".$cur_pos."-".$size."/".$filesize);
}
if($cache_time > 0)
{
header("Cache-Control: private, max-age=".$cache_time.", pre-check=".$cache_time);
if($filetime > 0)
header('Last-Modified: '.$lastModified);
}
else
{
header("Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0");
}
header("Expires: 0");
header("Pragma: public");
// Download from front-end
if($fastDownload && ($fromClouds || mb_strpos($fileData["tmp_name"], Application::getInstance()->getContext()->getServer()->getDocumentRoot()) === 0))
{
if($fromClouds)
{
$filename = preg_replace('~^(http[s]?)(://)~i', '\1.' , $fileData["tmp_name"]);
$cloudUploadPath = COption::GetOptionString('main', 'bx_cloud_upload', '/upload/bx_cloud_upload/');
header('X-Accel-Redirect: '.$cloudUploadPath.$filename);
}
else
{
header('X-Accel-Redirect: '.BitrixMainTextEncoding::convertEncoding($fileData["tmp_name"], SITE_CHARSET, "UTF-8"));
}
}
else if ($src)
{
session_write_close();
$file->seek($cur_pos);
while(!feof($src) && ($cur_pos <= $size))
{
$bufsize = 131072; //128K
if($cur_pos + $bufsize > $size)
$bufsize = $size - $cur_pos + 1;
$cur_pos += $bufsize;
echo fread($src, $bufsize);
}
$file->close();
}
else
{
$src = new BitrixMainWebHttpClient();
$fp = fopen("php://output", "wb");
$src->setOutputStream($fp);
$src->get($fileData["tmp_name"]);
}
}
CMain::FinalActions();
die();
}