InboxService is split the way the roadmap lays out Federation/Inbox:
- InboxReceiver reads and verifies the request exactly as before, runs
the checks that need no fetch (the activity id's origin, a Follow of a
missing or local-only actor, an Undo of someone else's activity, an
embedded object attributed to someone else), queues a ProcessInbox job
and answers 202. The job's dedupe key is the activity id, so a peer that
delivers the same activity twice is processed once.
- InboxProcessor (two at a time, eight attempts) loads the verified actor
and hands the activity to the handler for its type.
- Handlers/{Follow,Undo,Create,Delete,Update}Handler are the old methods,
unchanged except that they no longer produce status codes; the JSON
helpers live in Objects/ActivityJson and the group membership helpers in
Inbox/ForeignMembers.
A slow fetch of an object or a remote actor now delays the job, not the
sender's HTTP request.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CzABvBkbcFqoHdmi8b9WB
40 lines
1.0 KiB
C#
40 lines
1.0 KiB
C#
using System.Text.Json.Nodes;
|
|
|
|
namespace PrivaPub.Federation.Objects
|
|
{
|
|
public static class ActivityJson
|
|
{
|
|
public static string Id(JsonNode node) => node switch
|
|
{
|
|
JsonValue value when value.TryGetValue<string>(out var text) => text,
|
|
JsonObject obj => Value(obj, "id") ?? Value(obj, "href"),
|
|
JsonArray array => array.Select(Id).FirstOrDefault(i => i != default),
|
|
_ => default
|
|
};
|
|
|
|
public static string Value(JsonNode node, string property) =>
|
|
node is JsonObject obj && obj[property] is JsonValue value && value.TryGetValue<string>(out var text) ? text : default;
|
|
|
|
public static IEnumerable<string> Addresses(JsonNode node)
|
|
{
|
|
foreach (var field in new[] { "to", "cc", "bto", "bcc", "audience" })
|
|
{
|
|
switch (node[field])
|
|
{
|
|
case JsonArray array:
|
|
foreach (var item in array)
|
|
{
|
|
var id = Id(item);
|
|
if (id != default)
|
|
yield return id;
|
|
}
|
|
break;
|
|
case JsonNode single when Id(single) is { } id:
|
|
yield return id;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|