file_quota for OembedPlugin too

Don't download huge files that might kill memory limits.
This commit is contained in:
Mikael Nordfeldth 2016-07-21 03:19:05 +02:00
parent 809e2f6d07
commit 1b3d583418
3 changed files with 32 additions and 8 deletions

View File

@ -273,6 +273,10 @@ class File_thumbnail extends Managed_DataObject
return File::getByID($this->file_id); return File::getByID($this->file_id);
} }
public function getFileId()
{
return $this->file_id;
}
static public function hashurl($url) static public function hashurl($url)
{ {

View File

@ -377,16 +377,36 @@ class OembedPlugin extends Plugin
protected function storeRemoteFileThumbnail(File_thumbnail $thumbnail) protected function storeRemoteFileThumbnail(File_thumbnail $thumbnail)
{ {
if (!empty($thumbnail->filename) && file_exists($thumbnail->getPath())) { if (!empty($thumbnail->filename) && file_exists($thumbnail->getPath())) {
throw new AlreadyFulfilledException(sprintf('A thumbnail seems to already exist for remote file with id==%u', $thumbnail->file_id)); throw new AlreadyFulfilledException(sprintf('A thumbnail seems to already exist for remote file with id==%u', $thumbnail->getFileId()));
} }
$url = $thumbnail->getUrl(); $remoteUrl = $thumbnail->getUrl();
$this->checkWhitelist($url); $this->checkWhitelist($remoteUrl);
// First we download the file to memory and test whether it's actually an image file $http = new HTTPClient();
// First see if it's too large for us
common_debug(__METHOD__ . ': '.sprintf('Performing HEAD request for remote file id==%u to avoid unnecessarily downloading too large files. URL: %s', $thumbnail->getFileId(), $remoteUrl));
$head = $http->head($remoteUrl);
$remoteUrl = $head->getEffectiveUrl(); // to avoid going through redirects again
$headers = $head->getHeader();
$filesize = isset($headers['content-length']) ? $headers['content-length'] : null;
// FIXME: I just copied some checks from StoreRemoteMedia, maybe we should have other checks for thumbnails? Or at least embed into some class somewhere.
if (empty($filesize)) {
// file size not specified on remote server
common_debug(sprintf('%s: Ignoring remote thumbnail because we did not get a content length for thumbnail for file id==%u', __CLASS__, $thumbnail->getFileId()));
return true;
} elseif ($filesize > common_config('attachments', 'file_quota')) {
// file too big according to site configuration
common_debug(sprintf('%s: Skip downloading remote thumbnail because content length (%u) is larger than file_quota (%u) for file id==%u', __CLASS__, intval($filesize), common_config('attachments', 'file_quota'), $thumbnail->getFileId()));
return true;
}
// Then we download the file to memory and test whether it's actually an image file
// FIXME: To support remote video/whatever files, this needs reworking. // FIXME: To support remote video/whatever files, this needs reworking.
common_debug(sprintf('Downloading remote thumbnail for file id==%u with thumbnail URL: %s', $thumbnail->file_id, $url)); common_debug(sprintf('Downloading remote thumbnail for file id==%u (should be size %u) with effective URL: %s', $thumbnail->getFileId(), $filesize, _ve($remoteUrl)));
$imgData = HTTPClient::quickGet($url); $imgData = HTTPClient::quickGet($remoteUrl);
$info = @getimagesizefromstring($imgData); $info = @getimagesizefromstring($imgData);
if ($info === false) { if ($info === false) {
throw new UnsupportedMediaException(_('Remote file format was not identified as an image.'), $url); throw new UnsupportedMediaException(_('Remote file format was not identified as an image.'), $url);

View File

@ -91,7 +91,7 @@ class StoreRemoteMediaPlugin extends Plugin
$http = new HTTPClient(); $http = new HTTPClient();
common_debug(sprintf('Performing HEAD request for remote file id==%u to avoid unnecessarily downloading too large files. URL: %s', $file->getID(), $remoteUrl)); common_debug(sprintf('Performing HEAD request for remote file id==%u to avoid unnecessarily downloading too large files. URL: %s', $file->getID(), $remoteUrl));
$head = $http->head($remoteUrl); $head = $http->head($remoteUrl);
$remoteUrl = $head->effectiveUrl; // to avoid going through redirects again $remoteUrl = $head->getEffectiveUrl(); // to avoid going through redirects again
if (!$this->checkBlackList($remoteUrl)) { if (!$this->checkBlackList($remoteUrl)) {
common_log(LOG_WARN, sprintf('%s: Non-blacklisted URL %s redirected to blacklisted URL %s', __CLASS__, $file->getUrl(), $remoteUrl)); common_log(LOG_WARN, sprintf('%s: Non-blacklisted URL %s redirected to blacklisted URL %s', __CLASS__, $file->getUrl(), $remoteUrl));
return true; return true;
@ -120,7 +120,7 @@ class StoreRemoteMediaPlugin extends Plugin
common_debug(sprintf('Downloading remote file id==%u (should be size %u) with effective URL: %s', $file->getID(), $filesize, _ve($remoteUrl))); common_debug(sprintf('Downloading remote file id==%u (should be size %u) with effective URL: %s', $file->getID(), $filesize, _ve($remoteUrl)));
$imgData = HTTPClient::quickGet($remoteUrl); $imgData = HTTPClient::quickGet($remoteUrl);
} catch (HTTP_Request2_ConnectionException $e) { } catch (HTTP_Request2_ConnectionException $e) {
common_log(LOG_ERR, __CLASS__.': quickGet on URL: '._ve($file->getUrl()).' threw exception: '.$e->getMessage()); common_log(LOG_ERR, __CLASS__.': '._ve(get_class($e)).' on URL: '._ve($file->getUrl()).' threw exception: '.$e->getMessage());
return true; return true;
} }
$info = @getimagesizefromstring($imgData); $info = @getimagesizefromstring($imgData);