diff --git a/src/Module/Photo.php b/src/Module/Photo.php index d1b4b9629e..c521d2be82 100644 --- a/src/Module/Photo.php +++ b/src/Module/Photo.php @@ -352,11 +352,11 @@ class Photo extends BaseModule } if (empty($mimetext)) { if ($customsize <= Proxy::PIXEL_MICRO) { - $url = Contact::getDefaultAvatar($contact, Proxy::SIZE_MICRO); + $url = Contact::getDefaultAvatar($contact ?: [], Proxy::SIZE_MICRO); } elseif ($customsize <= Proxy::PIXEL_THUMB) { - $url = Contact::getDefaultAvatar($contact, Proxy::SIZE_THUMB); + $url = Contact::getDefaultAvatar($contact ?: [], Proxy::SIZE_THUMB); } else { - $url = Contact::getDefaultAvatar($contact, Proxy::SIZE_SMALL); + $url = Contact::getDefaultAvatar($contact ?: [], Proxy::SIZE_SMALL); } } return MPhoto::createPhotoForExternalResource($url, 0, $mimetext); diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index bfff5f84bb..60dd42cb49 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -303,7 +303,7 @@ class Processor if (empty($activity['directmessage']) && ($activity['id'] != $activity['reply-to-id']) && !Post::exists(['uri' => $activity['reply-to-id']])) { $recursion_depth = $activity['recursion-depth'] ?? 0; Logger::notice('Parent not found. Try to refetch it.', ['parent' => $activity['reply-to-id'], 'recursion-depth' => $recursion_depth]); - if ($recursion_depth < 10) { + if ($recursion_depth < DI::config()->get('system', 'max_recursion_depth')) { $result = self::fetchMissingActivity($activity['reply-to-id'], $activity, '', Receiver::COMPLETION_AUTO); if (empty($result) && self::isActivityGone($activity['reply-to-id'])) { // Recursively delete this and all depending entries @@ -1207,13 +1207,19 @@ class Processor $object = DI::cache()->get($cachekey); if (!is_null($object)) { - Logger::debug('Fetch from cache', ['url' => $url, 'uid' => $uid]); + if (!empty($object)) { + Logger::debug('Fetch from cache', ['url' => $url, 'uid' => $uid]); + } else { + Logger::debug('Fetch from negative cache', ['url' => $url, 'uid' => $uid]); + } return $object; } $object = ActivityPub::fetchContent($url, $uid); if (empty($object)) { Logger::notice('Activity was not fetchable, aborting.', ['url' => $url, 'uid' => $uid]); + // We perform negative caching. + DI::cache()->set($cachekey, [], Duration::FIVE_MINUTES); return []; } diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index f09541b13d..600fe31524 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -592,7 +592,7 @@ class Receiver return; } - if (!empty($object_data['entry-id']) && ($push || ($activity['completion-mode'] == self::COMPLETION_RELAY))) { + if (!empty($object_data['entry-id']) && DI::config()->get('system', 'decoupled_receiver') && ($push || ($activity['completion-mode'] == self::COMPLETION_RELAY))) { // We delay by 5 seconds to allow to accumulate all receivers $delayed = date(DateTimeFormat::MYSQL, time() + 5); Logger::debug('Initiate processing', ['id' => $object_data['entry-id'], 'uri' => $object_data['object_id']]); diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 62c8ce71c4..5c0f9b8131 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -3114,7 +3114,7 @@ class Diaspora Logger::notice('Empty addr', ['contact' => $contact ?? [], 'callstack' => System::callstack(20)]); } - $envelope = self::buildMessage($msg, $owner, $contact, $owner['uprvkey'], $pubkey, $public_batch); + $envelope = self::buildMessage($msg, $owner, $contact, $owner['uprvkey'], $pubkey ?? '', $public_batch); $return_code = self::transmit($owner, $contact, $envelope, $public_batch, $guid); diff --git a/static/defaults.config.php b/static/defaults.config.php index 1876ea90d7..a8a23ea9e9 100644 --- a/static/defaults.config.php +++ b/static/defaults.config.php @@ -164,6 +164,10 @@ return [ // Whether to use Memcache, Memcached, Redis or APCu to store temporary cache. 'cache_driver' => 'database', + // decoupled_receiver (Boolean) + // Decouple incoming AP posts by doing the processing in the background. + 'decoupled_receiver' => true, + // distributed_cache_driver (database|memcache|memcached|redis) // Whether to use database, Memcache, Memcached or Redis as a distributed cache. 'distributed_cache_driver' => 'database', @@ -416,6 +420,10 @@ return [ // Maximum number of concurrent database processes for foreground tasks. 'max_processes_frontend' => 20, + // max_recursion_depth (Integer) + // Maximum recursion depth when fetching posts until the job is delegated to a worker task. + 'max_recursion_depth' => 10, + // maximagesize (Integer) // Maximum size in bytes of an uploaded photo. 'maximagesize' => 800000,