From 6a5266c6b8a2a5324fe3f1543ec63230e4d1f16d Mon Sep 17 00:00:00 2001 From: Gidi Kroon Date: Sun, 25 Jun 2023 03:22:41 +0200 Subject: [PATCH 1/2] Add Vary header in case of content negotiation Sometimes we return different content depending on whether JSON, XML or HTML was requested in the Accept request header. The Vary response header should list that header in these cases, to allow caching frameworks to determine what to cache. --- src/Module/ActivityPub/Objects.php | 2 ++ src/Module/Friendica.php | 3 +++ src/Module/Item/Display.php | 2 ++ src/Module/Profile/Profile.php | 3 +++ src/Module/Xrd.php | 4 +++- 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Module/ActivityPub/Objects.php b/src/Module/ActivityPub/Objects.php index 34d460951..2d5862a1c 100644 --- a/src/Module/ActivityPub/Objects.php +++ b/src/Module/ActivityPub/Objects.php @@ -130,6 +130,8 @@ class Objects extends BaseModule // Relaxed CORS header for public items header('Access-Control-Allow-Origin: *'); + header('Vary: Accept', false); + System::jsonExit($data, 'application/activity+json'); } } diff --git a/src/Module/Friendica.php b/src/Module/Friendica.php index 90869878e..739078763 100644 --- a/src/Module/Friendica.php +++ b/src/Module/Friendica.php @@ -90,6 +90,8 @@ class Friendica extends BaseModule $blocked = null; } + header('Vary: Accept', false); + $hooked = ''; Hook::callAll('about_hook', $hooked); @@ -125,6 +127,7 @@ class Friendica extends BaseModule $data = ActivityPub\Transmitter::getProfile(0); header('Access-Control-Allow-Origin: *'); header('Cache-Control: max-age=23200, stale-while-revalidate=23200'); + header('Vary: Accept', false); System::jsonExit($data, 'application/activity+json'); } catch (HTTPException\NotFoundException $e) { System::jsonError(404, ['error' => 'Record not found']); diff --git a/src/Module/Item/Display.php b/src/Module/Item/Display.php index b2ed43c5b..54e55de2f 100644 --- a/src/Module/Item/Display.php +++ b/src/Module/Item/Display.php @@ -162,6 +162,8 @@ class Display extends BaseModule $output .= $this->getDisplayData($item); + header('Vary: Accept', false); + return $output; } diff --git a/src/Module/Profile/Profile.php b/src/Module/Profile/Profile.php index 5e5028cb8..b8f16656e 100644 --- a/src/Module/Profile/Profile.php +++ b/src/Module/Profile/Profile.php @@ -87,6 +87,7 @@ class Profile extends BaseProfile $data = ActivityPub\Transmitter::getProfile($user['uid']); header('Access-Control-Allow-Origin: *'); header('Cache-Control: max-age=23200, stale-while-revalidate=23200'); + header('Vary: Accept', false); System::jsonExit($data, 'application/activity+json'); } catch (HTTPException\NotFoundException $e) { System::jsonError(404, ['error' => 'Record not found']); @@ -103,6 +104,8 @@ class Profile extends BaseProfile System::jsonError(404, []); } } + + header('Vary: Accept', false); } protected function content(array $request = []): string diff --git a/src/Module/Xrd.php b/src/Module/Xrd.php index 6a4c0e860..71a3d37a9 100644 --- a/src/Module/Xrd.php +++ b/src/Module/Xrd.php @@ -152,6 +152,7 @@ class Xrd extends BaseModule ] ]; header('Access-Control-Allow-Origin: *'); + header('Vary: Accept', false); System::jsonExit($json, 'application/jrd+json; charset=utf-8'); } @@ -229,6 +230,7 @@ class Xrd extends BaseModule ]; header('Access-Control-Allow-Origin: *'); + header('Vary: Accept', false); System::jsonExit($json, 'application/jrd+json; charset=utf-8'); } @@ -326,7 +328,7 @@ class Xrd extends BaseModule ]); header('Access-Control-Allow-Origin: *'); - + header('Vary: Accept', false); System::httpExit($xmlString, Response::TYPE_XML, 'application/xrd+xml'); } } From 40783db16118e79f019ef68cfaffd2ac128b8c1b Mon Sep 17 00:00:00 2001 From: Gidi Kroon Date: Sun, 25 Jun 2023 20:54:04 +0200 Subject: [PATCH 2/2] Make requested changes --- src/Module/ActivityPub/Objects.php | 4 ++-- src/Module/Friendica.php | 5 ++--- src/Module/Item/Display.php | 4 ++-- src/Module/Profile/Profile.php | 5 ++--- src/Module/Xrd.php | 5 ++--- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/Module/ActivityPub/Objects.php b/src/Module/ActivityPub/Objects.php index 2d5862a1c..f93c8b957 100644 --- a/src/Module/ActivityPub/Objects.php +++ b/src/Module/ActivityPub/Objects.php @@ -46,6 +46,8 @@ class Objects extends BaseModule throw new HTTPException\BadRequestException(); } + header('Vary: Accept', false); + if (!ActivityPub::isRequest()) { DI::baseUrl()->redirect(str_replace('objects/', 'display/', DI::args()->getQueryString())); } @@ -130,8 +132,6 @@ class Objects extends BaseModule // Relaxed CORS header for public items header('Access-Control-Allow-Origin: *'); - header('Vary: Accept', false); - System::jsonExit($data, 'application/activity+json'); } } diff --git a/src/Module/Friendica.php b/src/Module/Friendica.php index 739078763..73d5f633c 100644 --- a/src/Module/Friendica.php +++ b/src/Module/Friendica.php @@ -90,8 +90,6 @@ class Friendica extends BaseModule $blocked = null; } - header('Vary: Accept', false); - $hooked = ''; Hook::callAll('about_hook', $hooked); @@ -117,6 +115,8 @@ class Friendica extends BaseModule protected function rawContent(array $request = []) { + header('Vary: Accept', false); + // @TODO: Replace with parameter from router if (DI::args()->getArgc() <= 1 || (DI::args()->getArgv()[1] !== 'json')) { if (!ActivityPub::isRequest()) { @@ -127,7 +127,6 @@ class Friendica extends BaseModule $data = ActivityPub\Transmitter::getProfile(0); header('Access-Control-Allow-Origin: *'); header('Cache-Control: max-age=23200, stale-while-revalidate=23200'); - header('Vary: Accept', false); System::jsonExit($data, 'application/activity+json'); } catch (HTTPException\NotFoundException $e) { System::jsonError(404, ['error' => 'Record not found']); diff --git a/src/Module/Item/Display.php b/src/Module/Item/Display.php index 54e55de2f..a0d1ecbf5 100644 --- a/src/Module/Item/Display.php +++ b/src/Module/Item/Display.php @@ -88,6 +88,8 @@ class Display extends BaseModule protected function content(array $request = []): string { + header('Vary: Accept', false); + if (ActivityPub::isRequest()) { $this->baseUrl->redirect(str_replace('display/', 'objects/', $this->args->getQueryString())); } @@ -162,8 +164,6 @@ class Display extends BaseModule $output .= $this->getDisplayData($item); - header('Vary: Accept', false); - return $output; } diff --git a/src/Module/Profile/Profile.php b/src/Module/Profile/Profile.php index b8f16656e..31ef8d05b 100644 --- a/src/Module/Profile/Profile.php +++ b/src/Module/Profile/Profile.php @@ -80,6 +80,8 @@ class Profile extends BaseProfile protected function rawContent(array $request = []) { + header('Vary: Accept', false); + if (ActivityPub::isRequest()) { $user = $this->database->selectFirst('user', ['uid'], ['nickname' => $this->parameters['nickname'] ?? '', 'account_removed' => false]); if ($user) { @@ -87,7 +89,6 @@ class Profile extends BaseProfile $data = ActivityPub\Transmitter::getProfile($user['uid']); header('Access-Control-Allow-Origin: *'); header('Cache-Control: max-age=23200, stale-while-revalidate=23200'); - header('Vary: Accept', false); System::jsonExit($data, 'application/activity+json'); } catch (HTTPException\NotFoundException $e) { System::jsonError(404, ['error' => 'Record not found']); @@ -104,8 +105,6 @@ class Profile extends BaseProfile System::jsonError(404, []); } } - - header('Vary: Accept', false); } protected function content(array $request = []): string diff --git a/src/Module/Xrd.php b/src/Module/Xrd.php index 71a3d37a9..3267e9e9a 100644 --- a/src/Module/Xrd.php +++ b/src/Module/Xrd.php @@ -80,6 +80,8 @@ class Xrd extends BaseModule throw new NotFoundException('Invalid host name for xrd query: ' . $host); } + header('Vary: Accept', false); + if ($name == User::getActorName()) { $owner = User::getSystemAccount(); if (empty($owner)) { @@ -152,7 +154,6 @@ class Xrd extends BaseModule ] ]; header('Access-Control-Allow-Origin: *'); - header('Vary: Accept', false); System::jsonExit($json, 'application/jrd+json; charset=utf-8'); } @@ -230,7 +231,6 @@ class Xrd extends BaseModule ]; header('Access-Control-Allow-Origin: *'); - header('Vary: Accept', false); System::jsonExit($json, 'application/jrd+json; charset=utf-8'); } @@ -328,7 +328,6 @@ class Xrd extends BaseModule ]); header('Access-Control-Allow-Origin: *'); - header('Vary: Accept', false); System::httpExit($xmlString, Response::TYPE_XML, 'application/xrd+xml'); } }