From 2b513a48c796927bcb028d61a763f47e73598351 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 26 Feb 2023 14:08:33 +0000 Subject: [PATCH] Catch all errors thrown by "fetchRaw" --- src/Contact/Avatar.php | 7 +++++- src/Core/Storage/Type/ExternalResource.php | 1 + src/Model/APContact.php | 25 +++++++++++++--------- src/Model/Contact.php | 21 +++++++++++------- src/Model/Post/Link.php | 9 ++++++-- src/Module/Proxy.php | 15 ++++++++----- src/Protocol/ActivityPub/Processor.php | 7 +++++- src/Util/HTTPSignature.php | 7 +++++- 8 files changed, 64 insertions(+), 28 deletions(-) diff --git a/src/Contact/Avatar.php b/src/Contact/Avatar.php index e039a52799..4843e5d37c 100644 --- a/src/Contact/Avatar.php +++ b/src/Contact/Avatar.php @@ -73,7 +73,12 @@ class Avatar return $fields; } - $fetchResult = HTTPSignature::fetchRaw($avatar, 0, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]); + try { + $fetchResult = HTTPSignature::fetchRaw($avatar, 0, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]); + } catch (\Throwable $th) { + Logger::notice('Avatar is invalid', ['avatar' => $avatar, 'error' => $th]); + return $fields; + } $img_str = $fetchResult->getBody(); if (empty($img_str)) { diff --git a/src/Core/Storage/Type/ExternalResource.php b/src/Core/Storage/Type/ExternalResource.php index 055db0deaa..54d47e5bf4 100644 --- a/src/Core/Storage/Type/ExternalResource.php +++ b/src/Core/Storage/Type/ExternalResource.php @@ -57,6 +57,7 @@ class ExternalResource implements ICanReadFromStorage try { $fetchResult = HTTPSignature::fetchRaw($data->url, $data->uid, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]); } catch (Exception $exception) { + Logger::notice('URL is invalid', ['url' => $data->url, 'error' => $exception]); throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $exception->getCode(), $exception); } if (!empty($fetchResult) && $fetchResult->isSuccess()) { diff --git a/src/Model/APContact.php b/src/Model/APContact.php index 215d7e317d..a429a7a5d4 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -189,17 +189,22 @@ class APContact if (empty($data)) { $local_owner = []; - $curlResult = HTTPSignature::fetchRaw($url); - $failed = empty($curlResult) || empty($curlResult->getBody()) || - (!$curlResult->isSuccess() && ($curlResult->getReturnCode() != 410)); + try { + $curlResult = HTTPSignature::fetchRaw($url); + $failed = empty($curlResult) || empty($curlResult->getBody()) || + (!$curlResult->isSuccess() && ($curlResult->getReturnCode() != 410)); + + if (!$failed) { + $data = json_decode($curlResult->getBody(), true); + $failed = empty($data) || !is_array($data); + } - if (!$failed) { - $data = json_decode($curlResult->getBody(), true); - $failed = empty($data) || !is_array($data); - } - - if (!$failed && ($curlResult->getReturnCode() == 410)) { - $data = ['@context' => ActivityPub::CONTEXT, 'id' => $url, 'type' => 'Tombstone']; + if (!$failed && ($curlResult->getReturnCode() == 410)) { + $data = ['@context' => ActivityPub::CONTEXT, 'id' => $url, 'type' => 'Tombstone']; + } + } catch (\Throwable $th) { + Logger::notice('Error fetching url', ['url' => $url, 'error' => $th]); + $failed = true; } if ($failed) { diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 571253f425..64509b5d22 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -2216,16 +2216,21 @@ class Contact if (($contact['avatar'] != $avatar) || empty($contact['blurhash'])) { $update_fields = ['avatar' => $avatar]; if (!Network::isLocalLink($avatar)) { - $fetchResult = HTTPSignature::fetchRaw($avatar, 0, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]); + try { + $fetchResult = HTTPSignature::fetchRaw($avatar, 0, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]); - $img_str = $fetchResult->getBody(); - if (!empty($img_str)) { - $image = new Image($img_str, Images::getMimeTypeByData($img_str)); - if ($image->isValid()) { - $update_fields['blurhash'] = $image->getBlurHash(); - } else { - return; + $img_str = $fetchResult->getBody(); + if (!empty($img_str)) { + $image = new Image($img_str, Images::getMimeTypeByData($img_str)); + if ($image->isValid()) { + $update_fields['blurhash'] = $image->getBlurHash(); + } else { + return; + } } + } catch (\Throwable $th) { + Logger::notice('Error fetching avatar', ['avatar' => $avatar, 'error' => $th]); + return; } } elseif (!empty($contact['blurhash'])) { $update_fields['blurhash'] = null; diff --git a/src/Model/Post/Link.php b/src/Model/Post/Link.php index 343ad815c3..4ac8173799 100644 --- a/src/Model/Post/Link.php +++ b/src/Model/Post/Link.php @@ -125,8 +125,13 @@ class Link { $timeout = DI::config()->get('system', 'xrd_timeout'); - $curlResult = HTTPSignature::fetchRaw($url, 0, [HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::ACCEPT_CONTENT => $accept]); - if (empty($curlResult) || !$curlResult->isSuccess()) { + try { + $curlResult = HTTPSignature::fetchRaw($url, 0, [HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::ACCEPT_CONTENT => $accept]); + if (empty($curlResult) || !$curlResult->isSuccess()) { + return []; + } + } catch (\Throwable $th) { + Logger::notice('Error fetching url', ['url' => $url, 'error' => $th]); return []; } $fields = ['mimetype' => $curlResult->getHeader('Content-Type')[0]]; diff --git a/src/Module/Proxy.php b/src/Module/Proxy.php index ab129a82c9..3f1e4b2b80 100644 --- a/src/Module/Proxy.php +++ b/src/Module/Proxy.php @@ -83,13 +83,18 @@ class Proxy extends BaseModule $request['url'] = str_replace(' ', '+', $request['url']); // Fetch the content with the local user - $fetchResult = HTTPSignature::fetchRaw($request['url'], DI::userSession()->getLocalUserId(), [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE], 'timeout' => 10]); - $img_str = $fetchResult->getBody(); + try { + $fetchResult = HTTPSignature::fetchRaw($request['url'], DI::userSession()->getLocalUserId(), [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE], 'timeout' => 10]); + $img_str = $fetchResult->getBody(); - if (!$fetchResult->isSuccess() || empty($img_str)) { - Logger::notice('Error fetching image', ['image' => $request['url'], 'return' => $fetchResult->getReturnCode(), 'empty' => empty($img_str)]); + if (!$fetchResult->isSuccess() || empty($img_str)) { + Logger::notice('Error fetching image', ['image' => $request['url'], 'return' => $fetchResult->getReturnCode(), 'empty' => empty($img_str)]); + self::responseError(); + // stop. + } + } catch (\Throwable $th) { + Logger::notice('Error fetching image', ['image' => $request['url'], 'error' => $th]); self::responseError(); - // stop. } Logger::debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => DI::userSession()->getLocalUserId(), 'image' => $request['url']]); diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 11267cfaf5..20736504ef 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -570,7 +570,12 @@ class Processor */ public static function isActivityGone(string $url): bool { - $curlResult = HTTPSignature::fetchRaw($url, 0); + try { + $curlResult = HTTPSignature::fetchRaw($url, 0); + } catch (\Throwable $th) { + Logger::notice('Error fetching url', ['url' => $url, 'error' => $th]); + return true; + } if (Network::isUrlBlocked($url)) { return true; diff --git a/src/Util/HTTPSignature.php b/src/Util/HTTPSignature.php index f082fe32f7..fe623f2968 100644 --- a/src/Util/HTTPSignature.php +++ b/src/Util/HTTPSignature.php @@ -422,7 +422,12 @@ class HTTPSignature */ public static function fetch(string $request, int $uid): array { - $curlResult = self::fetchRaw($request, $uid); + try { + $curlResult = self::fetchRaw($request, $uid); + } catch (\Throwable $th) { + Logger::notice('Error fetching url', ['url' => $request, 'error' => $th]); + return []; + } if (empty($curlResult)) { return [];