mirror of https://github.com/MISP/MISP
chg: [internal] Slightly optimise CakeResponseTmp
parent
458e900a73
commit
c2bdf167a6
|
@ -315,28 +315,27 @@ class AttributesController extends AppController
|
|||
if (empty($attributes)) {
|
||||
throw new UnauthorizedException(__('Attribute does not exists or you do not have the permission to download this attribute.'));
|
||||
}
|
||||
$this->__downloadAttachment($attributes[0]['Attribute']);
|
||||
return $this->__downloadAttachment($attributes[0]['Attribute']);
|
||||
}
|
||||
|
||||
private function __downloadAttachment($attribute)
|
||||
private function __downloadAttachment(array $attribute)
|
||||
{
|
||||
$file = $this->Attribute->getAttachmentFile($attribute);
|
||||
|
||||
if ('attachment' == $attribute['type']) {
|
||||
if ('attachment' === $attribute['type']) {
|
||||
$filename = $attribute['value'];
|
||||
$fileExt = pathinfo($filename, PATHINFO_EXTENSION);
|
||||
$filename = substr($filename, 0, strlen($filename) - strlen($fileExt) - 1);
|
||||
} elseif ('malware-sample' == $attribute['type']) {
|
||||
} elseif ('malware-sample' === $attribute['type']) {
|
||||
$filenameHash = explode('|', $attribute['value']);
|
||||
$filename = substr($filenameHash[0], strrpos($filenameHash[0], '\\'));
|
||||
$fileExt = "zip";
|
||||
} else {
|
||||
throw new NotFoundException(__('Attribute not an attachment or malware-sample'));
|
||||
}
|
||||
$this->autoRender = false;
|
||||
$this->response->type($fileExt);
|
||||
|
||||
$download_attachments_on_load = Configure::check('MISP.download_attachments_on_load') ? Configure::read('MISP.download_attachments_on_load') : true;
|
||||
$this->response->file($file->path, array('download' => $download_attachments_on_load, 'name' => $filename . '.' . $fileExt));
|
||||
return $this->RestResponse->sendFile($file, $fileExt, $download_attachments_on_load, $filename . '.' . $fileExt);
|
||||
}
|
||||
|
||||
public function add_attachment($eventId = null)
|
||||
|
@ -1762,7 +1761,7 @@ class AttributesController extends AppController
|
|||
if (empty($attributes)) {
|
||||
throw new UnauthorizedException(__('Attribute does not exists or you do not have the permission to download this attribute.'));
|
||||
}
|
||||
$this->__downloadAttachment($attributes[0]['Attribute']);
|
||||
return $this->__downloadAttachment($attributes[0]['Attribute']);
|
||||
}
|
||||
|
||||
// returns an XML with attributes that belong to an event. The type of attributes to be returned can be restricted by type using the 3rd parameter.
|
||||
|
|
|
@ -590,8 +590,8 @@ class RestResponseComponent extends Component
|
|||
}
|
||||
|
||||
if ($response instanceof TmpFileTool) {
|
||||
App::uses('CakeResponseTmp', 'Tools');
|
||||
$cakeResponse = new CakeResponseTmp(['status' => $code, 'type' => $type]);
|
||||
App::uses('CakeResponseFile', 'Tools');
|
||||
$cakeResponse = new CakeResponseFile(['status' => $code, 'type' => $type]);
|
||||
$cakeResponse->file($response);
|
||||
} else {
|
||||
$cakeResponse = new CakeResponse(array('body' => $response, 'status' => $code, 'type' => $type));
|
||||
|
@ -655,13 +655,24 @@ class RestResponseComponent extends Component
|
|||
return $this->__sendResponse($data, 200, $format, $raw, $download, $headers);
|
||||
}
|
||||
|
||||
public function sendFile($path, $format = false, $download = false, $name = 'download')
|
||||
/**
|
||||
* @param string|File|TmpFileTool $path
|
||||
* @param string|null $type
|
||||
* @param bool $download
|
||||
* @param string $name
|
||||
* @return CakeResponseFile
|
||||
* @throws Exception
|
||||
*/
|
||||
public function sendFile($path, $type = null, $download = false, $name = 'download')
|
||||
{
|
||||
$cakeResponse = new CakeResponse(array(
|
||||
'status' => 200,
|
||||
'type' => $format
|
||||
));
|
||||
$cakeResponse->file($path, array('name' => $name, 'download' => true));
|
||||
App::uses('CakeResponseFile', 'Tools');
|
||||
$cakeResponse = new CakeResponseFile([
|
||||
'type' => $type
|
||||
]);
|
||||
$cakeResponse->file($path, ['name' => $name, 'download' => $download]);
|
||||
if (Configure::read('Security.disable_browser_cache')) {
|
||||
$cakeResponse->disableCache();
|
||||
}
|
||||
return $cakeResponse;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
class CakeResponseFile extends CakeResponse
|
||||
{
|
||||
/**
|
||||
* Modified version that supports also TmpFileTool and File
|
||||
*
|
||||
* @param string|TmpFileTool|File $path
|
||||
* @param array $options
|
||||
* @throws Exception
|
||||
*/
|
||||
public function file($path, $options = array())
|
||||
{
|
||||
if ($path instanceof TmpFileTool) {
|
||||
$this->header('Content-Length', $path->size());
|
||||
$this->_clearBuffer();
|
||||
$this->_file = $path;
|
||||
} else if ($path instanceof File) {
|
||||
$options += array(
|
||||
'name' => null,
|
||||
'download' => null
|
||||
);
|
||||
|
||||
if ($options['download']) {
|
||||
$name = $options['name'] === null ? $path->name : $options['name'];
|
||||
$this->download($name);
|
||||
$this->header('Content-Transfer-Encoding', 'binary');
|
||||
}
|
||||
|
||||
$this->header('Accept-Ranges', 'bytes');
|
||||
$httpRange = env('HTTP_RANGE');
|
||||
if (isset($httpRange)) {
|
||||
$this->_fileRange($path, $httpRange);
|
||||
} else {
|
||||
$this->header('Content-Length', filesize($path->path));
|
||||
}
|
||||
|
||||
$this->_clearBuffer();
|
||||
$this->_file = $path;
|
||||
} else {
|
||||
parent::file($path, $options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method supports TmpFileTool and also provides optimised variant for sending file from `File` object
|
||||
* @param File|TmpFileTool $file
|
||||
* @param array $range
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function _sendFile($file, $range)
|
||||
{
|
||||
set_time_limit(0);
|
||||
session_write_close();
|
||||
|
||||
if ($file instanceof TmpFileTool) {
|
||||
foreach ($file->intoChunks() as $chunk) {
|
||||
if (!$this->_isActive()) {
|
||||
$file->close();
|
||||
return false;
|
||||
}
|
||||
echo $chunk;
|
||||
}
|
||||
} else {
|
||||
$handler = fopen($file->path, 'rb');
|
||||
if ($handler === false) {
|
||||
throw new Exception("File $file->path doesn't exists anymore or is not readable.");
|
||||
}
|
||||
|
||||
$end = $start = false;
|
||||
if ($range && is_array($range)) {
|
||||
list($start, $end) = $range;
|
||||
}
|
||||
if ($start !== false) {
|
||||
fseek($handler, $start);
|
||||
}
|
||||
|
||||
$bufferSize = 8192;
|
||||
while (!feof($handler)) {
|
||||
if (!$this->_isActive()) {
|
||||
$file->close();
|
||||
return false;
|
||||
}
|
||||
$offset = ftell($handler);
|
||||
if ($end && $offset >= $end) {
|
||||
break;
|
||||
}
|
||||
if ($end && $offset + $bufferSize >= $end) {
|
||||
$bufferSize = $end - $offset + 1;
|
||||
}
|
||||
echo fread($handler, $bufferSize);
|
||||
}
|
||||
fclose($handler);
|
||||
}
|
||||
$this->_flushBuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Faster version that do not do redundant check
|
||||
* @return bool
|
||||
*/
|
||||
protected function _isActive()
|
||||
{
|
||||
return connection_status() === CONNECTION_NORMAL;
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
class CakeResponseTmp extends CakeResponse
|
||||
{
|
||||
public function file($path, $options = array())
|
||||
{
|
||||
if ($path instanceof TmpFileTool) {
|
||||
$this->header('Content-Length', $path->size());
|
||||
$this->_clearBuffer();
|
||||
$this->_file = $path;
|
||||
} else {
|
||||
parent::file($path, $options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param File|TmpFileTool $file
|
||||
* @param array $range
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function _sendFile($file, $range)
|
||||
{
|
||||
if ($file instanceof TmpFileTool) {
|
||||
set_time_limit(0);
|
||||
session_write_close();
|
||||
|
||||
foreach ($file->intoChunks() as $chunk) {
|
||||
if (!$this->_isActive()) {
|
||||
$file->close();
|
||||
return false;
|
||||
}
|
||||
echo $chunk;
|
||||
$this->_flushBuffer();
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return parent::_sendFile($file, $range);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue