diff --git a/appinfo/database.xml b/appinfo/database.xml index 21f239a2..54153c46 100644 --- a/appinfo/database.xml +++ b/appinfo/database.xml @@ -434,6 +434,13 @@ true + + error + integer + 1 + true + + creation timestamp diff --git a/appinfo/info.xml b/appinfo/info.xml index 771cfc66..ba6f24f8 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -5,7 +5,7 @@ Social 🎉 Nextcloud becomes part of the federated social networks! - 0.0.42 + 0.0.43 agpl Maxence Lange Julius Härtl diff --git a/lib/Db/CacheDocumentsRequest.php b/lib/Db/CacheDocumentsRequest.php index fa6f8935..70484f39 100644 --- a/lib/Db/CacheDocumentsRequest.php +++ b/lib/Db/CacheDocumentsRequest.php @@ -80,6 +80,7 @@ class CacheDocumentsRequest extends CacheDocumentsRequestBuilder { $qb = $this->getCacheDocumentsUpdateSql(); $this->limitToIdString($qb, $document->getId()); $qb->set('local_copy', $qb->createNamedParameter($document->getLocalCopy())); + $qb->set('error', $qb->createNamedParameter($document->getError())); $qb->execute(); } diff --git a/lib/Db/CacheDocumentsRequestBuilder.php b/lib/Db/CacheDocumentsRequestBuilder.php index 6e52293e..56e0c223 100644 --- a/lib/Db/CacheDocumentsRequestBuilder.php +++ b/lib/Db/CacheDocumentsRequestBuilder.php @@ -31,8 +31,6 @@ namespace OCA\Social\Db; use daita\MySmallPhpTools\Traits\TArrayTools; -use OCA\Social\Exceptions\SocialAppConfigException; -use OCA\Social\Exceptions\UrlCloudException; use OCA\Social\Model\ActivityPub\Document; use OCP\DB\QueryBuilder\IQueryBuilder; @@ -79,7 +77,7 @@ class CacheDocumentsRequestBuilder extends CoreRequestBuilder { /** @noinspection PhpMethodParametersCountMismatchInspection */ $qb->select( 'cd.id', 'cd.type', 'cd.media_type', 'cd.mime_type', 'cd.url', 'cd.local_copy', - 'cd.public', 'cd.creation', 'cd.caching' + 'cd.public', 'cd.error', 'cd.creation', 'cd.caching' ) ->from(self::TABLE_CACHE_DOCUMENTS, 'cd'); diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index f5d2053c..2e598bc2 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -155,7 +155,6 @@ class CoreRequestBuilder { } - /** * Limit the request to the ActorId * @@ -477,6 +476,8 @@ class CoreRequestBuilder { ->selectAlias('cd.url', 'cachedocument_url') ->selectAlias('cd.local_copy', 'cachedocument_local_copy') ->selectAlias('cd.caching', 'cachedocument_caching') + ->selectAlias('cd.public', 'cachedocument_public') + ->selectAlias('cd.error', 'cachedocument_error') ->selectAlias('ca.creation', 'cachedocument_creation') ->leftJoin( $this->defaultSelectAlias, CoreRequestBuilder::TABLE_CACHE_DOCUMENTS, 'cd', diff --git a/lib/Exceptions/CacheContentSizeException.php b/lib/Exceptions/CacheContentSizeException.php new file mode 100644 index 00000000..1a264915 --- /dev/null +++ b/lib/Exceptions/CacheContentSizeException.php @@ -0,0 +1,8 @@ +error; + } + + /** + * @param int $error + * + * @return Document + */ + public function setError(int $error): Document { + $this->error = $error; + + return $this; + } + + /** * @return string */ @@ -192,6 +214,7 @@ class Document extends ACore implements JsonSerializable { parent::importFromDatabase($data); $this->setPublic(($this->getInt('public', $data, 0) === 1) ? true : false); + $this->setError($this->getInt('error', $data, 0)); $this->setLocalCopy($this->get('local_copy', $data, '')); $this->setMediaType($this->get('media_type', $data, '')); $this->setMimeType($this->get('mime_type', $data, '')); diff --git a/lib/Service/ActivityPub/DocumentService.php b/lib/Service/ActivityPub/DocumentService.php index 8f6bc8e0..94e4c085 100644 --- a/lib/Service/ActivityPub/DocumentService.php +++ b/lib/Service/ActivityPub/DocumentService.php @@ -33,6 +33,7 @@ namespace OCA\Social\Service\ActivityPub; use OCA\Social\Db\CacheDocumentsRequest; use OCA\Social\Exceptions\CacheContentException; +use OCA\Social\Exceptions\CacheContentSizeException; use OCA\Social\Exceptions\CacheDocumentDoesNotExistException; use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\ActivityPub\Document; @@ -99,6 +100,8 @@ class DocumentService implements ICoreService { $document->setMimeType($mime); $document->setLocalCopy($localCopy); $this->cacheDocumentsRequest->endCaching($document); + } catch (CacheContentSizeException $e) { + $this->cacheDocumentsRequest->endCaching($document); } catch (CacheContentException $e) { } diff --git a/lib/Service/CacheService.php b/lib/Service/CacheService.php index a9d27b51..60c5827a 100644 --- a/lib/Service/CacheService.php +++ b/lib/Service/CacheService.php @@ -32,6 +32,7 @@ namespace OCA\Social\Service; use Exception; use OCA\Social\Exceptions\CacheContentException; +use OCA\Social\Exceptions\CacheContentSizeException; use OCP\Files\IAppData; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; @@ -41,9 +42,15 @@ use OCP\Files\SimpleFS\ISimpleFile; class CacheService { + const ERROR_MAX_SIZE = 1; + + /** @var IAppData */ private $appData; + /** @var ConfigService */ + private $configService; + /** @var MiscService */ private $miscService; @@ -52,10 +59,14 @@ class CacheService { * CacheService constructor. * * @param IAppData $appData + * @param ConfigService $configService * @param MiscService $miscService */ - public function __construct(IAppData $appData, MiscService $miscService) { + public function __construct( + IAppData $appData, ConfigService $configService, MiscService $miscService + ) { $this->appData = $appData; + $this->configService = $configService; $this->miscService = $miscService; } @@ -68,6 +79,7 @@ class CacheService { * @return string * @throws CacheContentException * @throws NotPermittedException + * @throws CacheContentSizeException */ public function saveRemoteFileToCache(string $url, &$mime = '') { @@ -131,13 +143,26 @@ class CacheService { * * @return string * @throws CacheContentException + * @throws CacheContentSizeException */ public function retrieveContent(string $url) { - $content = file_get_contents($url); - if ($content === false) { + $maxSize = + $this->configService->getAppValueInt(ConfigService::SOCIAL_MAX_SIZE) * 1024 * 1024; + + $fd = fopen($url, "r"); + if ($fd === false) { throw new CacheContentException(); } + $content = ''; + while (!feof($fd)) { + $content .= fread($fd, 4096); + if (strlen($content) > $maxSize) { + throw new CacheContentSizeException(); + } + } + fclose($fd); + return $content; } diff --git a/lib/Service/ConfigService.php b/lib/Service/ConfigService.php index 578db10e..34d4bb16 100644 --- a/lib/Service/ConfigService.php +++ b/lib/Service/ConfigService.php @@ -52,10 +52,12 @@ class ConfigService { const SOCIAL_ADDRESS = 'address'; + const SOCIAL_MAX_SIZE = 'max_size'; /** @var array */ public $defaults = [ - self::SOCIAL_ADDRESS => '' + self::SOCIAL_ADDRESS => '', + self::SOCIAL_MAX_SIZE => 25 ]; /** @var string */ @@ -111,6 +113,22 @@ class ConfigService { return $this->config->getAppValue(Application::APP_NAME, $key, $defaultValue); } + /** + * Get a value by key + * + * @param string $key + * + * @return int + */ + public function getAppValueInt(string $key): int { + $defaultValue = null; + if (array_key_exists($key, $this->defaults)) { + $defaultValue = $this->defaults[$key]; + } + + return (int)$this->config->getAppValue(Application::APP_NAME, $key, $defaultValue); + } + /** * Set a value by key * @@ -248,6 +266,7 @@ class ConfigService { /** * // TODO - check the Apps folder + * * @return string * @throws SocialAppConfigException */