forked from GNUsocial/gnu-social
[CORE][Router] Properly act on Accept headers
This commit is contained in:
parent
99fd2f725b
commit
028ea79fff
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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'] ?? ''),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user