WIP Mail REST API: do NOT read attachments into memory, they might be to big

This commit is contained in:
ralf 2023-06-30 17:13:42 +02:00
parent 8a3fd670ee
commit 65b239ca2c
2 changed files with 22 additions and 5 deletions

View File

@ -1522,13 +1522,14 @@ class CalDAV extends HTTP_WebDAV_Server
if (method_exists($handler, 'post'))
{
// read the content in a string, if a stream is given
if (isset($options['stream']))
if (isset($options['stream']) && !self::isFileUpload())
{
$options['content'] = '';
while(!feof($options['stream']))
{
$options['content'] .= fread($options['stream'],8192);
}
fseek($options['stream'], 0);
}
return $handler->post($options,$id,$user);
}
@ -2331,8 +2332,8 @@ class CalDAV extends HTTP_WebDAV_Server
{
self::$request_starttime = microtime(true);
// do NOT log non-text attachments
$this->store_request = $_SERVER['REQUEST_METHOD'] != 'POST' || !isset($_GET['action']) ||
!in_array($_GET['action'], array('attachment-add', 'attachment-update')) ||
$this->store_request = $_SERVER['REQUEST_METHOD'] != 'POST' ||
!self::isFileUpload() ||
substr($_SERVER['CONTENT_TYPE'], 0, 5) == 'text/';
ob_start();
}
@ -2341,6 +2342,19 @@ class CalDAV extends HTTP_WebDAV_Server
if (self::$request_starttime) self::log_request();
}
/**
* Check if request is a possibly large, binary file upload:
* - CalDAV managed attachments or
* - Mail REST API attachment upload
*
* @return bool
*/
protected static function isFileUpload()
{
return (isset($_GET['action']) && in_array($_GET['action'], array('attachment-add', 'attachment-update'))) ||
strpos($_SERVER['REQUEST_URI'], '/mail/attachments/');
}
/**
* Sanitizing filename to gard agains path traversal and / eg. in UserAgent string
*

View File

@ -58,7 +58,7 @@ class ApiHandler extends Api\CalDAV\Handler
try {
if (str_starts_with($path, '/mail/attachments/'))
{
return self::storeAttachment($path, $options['content']);
return self::storeAttachment($path, $options['stream'] ?? $options['content']);
}
elseif (preg_match('#^/mail(/(\d+))?(/compose)?#', $path, $matches))
{
@ -146,8 +146,11 @@ class ApiHandler extends Api\CalDAV\Handler
{
$attachment_path = tempnam($GLOBALS['egw_info']['server']['temp_dir'], 'attach--'.
(str_replace('/', '-', substr($path, 18)) ?: 'no-name').'--');
if (file_put_contents($attachment_path, $content))
if (is_resource($content) ?
stream_copy_to_stream($content, $fp=fopen($attachment_path, 'w')) :
file_put_contents($attachment_path, $content))
{
if (isset($fp)) fclose($fp);
header('Location: '.($location = '/mail/attachments/'.substr(basename($attachment_path), 8)));
echo json_encode([
'status' => 200,