From 028ea79fff397a6d41bb968885cb1797560a93a3 Mon Sep 17 00:00:00 2001 From: Diogo Peralta Cordeiro Date: Tue, 19 Oct 2021 23:46:01 +0100 Subject: [PATCH] [CORE][Router] Properly act on Accept headers --- plugins/ActivityPub/ActivityPub.php | 45 ++++-------------------- plugins/ActivityPub/Controller/Inbox.php | 6 ---- src/Core/Router/RouteLoader.php | 13 ++++++- 3 files changed, 18 insertions(+), 46 deletions(-) diff --git a/plugins/ActivityPub/ActivityPub.php b/plugins/ActivityPub/ActivityPub.php index 569fc0fbd7..805d0f2e6a 100644 --- a/plugins/ActivityPub/ActivityPub.php +++ b/plugins/ActivityPub/ActivityPub.php @@ -39,6 +39,12 @@ class ActivityPub extends Plugin */ public function onAddRoute(RouteLoader $r): bool { + $r->connect( + 'activitypub_inbox', + '/inbox.json', + [Inbox::class, 'handle'], + options: ['accept' => self::$accept_headers, 'format' => self::$accept_headers[0]] + ); $r->connect( 'activitypub_actor_inbox', '/actor/{gsactor_id<\d+>}/inbox.json', @@ -51,48 +57,9 @@ class ActivityPub extends Plugin [Inbox::class, 'handle'], options: ['accept' => self::$accept_headers, 'format' => self::$accept_headers[0]] ); - $r->connect( - 'activitypub_inbox', - '/inbox.json', - [Inbox::class, 'handle'], - options: ['accept' => self::$accept_headers, 'format' => self::$accept_headers[0]] - ); return Event::next; } - /** - * Validate HTTP Accept headers - * - * @param bool $strict Strict mode - * - * @throws Exception when strict mode enabled - */ - public static function validateAcceptHeader(array|string|null $accept, bool $strict): bool - { - if (\is_string($accept) - && \in_array($accept, self::$accept_headers) - ) { - return true; - } elseif (\is_array($accept) - && \count( - array_intersect($accept, self::$accept_headers), - ) > 0 - ) { - return true; - } - - if (!$strict) { - return false; - } - - throw new Exception( - sprintf( - "HTTP Accept header error. Given: '%s'", - $accept, - ), - ); - } - /** * @throws Exception */ diff --git a/plugins/ActivityPub/Controller/Inbox.php b/plugins/ActivityPub/Controller/Inbox.php index 11b35fad43..c38f52104f 100644 --- a/plugins/ActivityPub/Controller/Inbox.php +++ b/plugins/ActivityPub/Controller/Inbox.php @@ -47,12 +47,6 @@ class Inbox extends Controller } } - // Check accept header - ActivityPub::validateAcceptHeader( - $this->request->headers->get('accept'), - true, - ); - // TODO: Check if Actor can post // Get content diff --git a/src/Core/Router/RouteLoader.php b/src/Core/Router/RouteLoader.php index 91bf4133f5..48868dcbaf 100644 --- a/src/Core/Router/RouteLoader.php +++ b/src/Core/Router/RouteLoader.php @@ -100,6 +100,17 @@ class RouteLoader extends Loader */ public function connect(string $id, string $uri_path, $target, ?array $options = [], ?array $param_reqs = []) { + // XXX: This hack can definitely be optimised by actually intersecting the arrays, + // maybe this helps: https://backbeat.tech/blog/symfony-routing-tricks-part-1 + // see: https://symfony.com/index.php/doc/3.1/components/http_foundation.html#accessing-accept-headers-data + if (isset($options['accept'])) { + $accept_header_condition = ''; + foreach ($options['accept'] as $accept) { + $accept_header_condition .= "('$accept' in request.getAcceptableContentTypes()) ||"; + } + $accept_header_condition = substr($accept_header_condition, 0, -3); + } + $this->rc->add( $id, new Route( @@ -134,7 +145,7 @@ class RouteLoader extends Loader methods: $options['http-methods'] ?? $options['methods'] ?? [], // condition = '' -- Symfony condition expression, // see https://symfony.com/doc/current/routing.html#matching-expressions - condition: isset($options['accept']) ? "request.headers.get('Accept') in " . json_encode($options['accept']) : ($options['condition'] ?? ''), + condition: isset($options['accept']) ? $accept_header_condition : ($options['condition'] ?? ''), ), ); }