[backend/core] Move AsyncLocals to FlagService, fix IsPleroma flag for streaming connections

This commit is contained in:
Laura Hausmann 2025-03-22 20:56:36 +01:00
parent ca8f28c1fd
commit cefbf4f898
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
6 changed files with 33 additions and 26 deletions

View file

@ -2,6 +2,7 @@ using Iceshrimp.Backend.Components.PublicPreview.Schemas;
using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Extensions; using Iceshrimp.Backend.Core.Extensions;
using Iceshrimp.Backend.Core.Helpers.LibMfm.Conversion; using Iceshrimp.Backend.Core.Helpers.LibMfm.Conversion;
using Iceshrimp.Backend.Core.Services;
using Iceshrimp.MfmSharp; using Iceshrimp.MfmSharp;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@ -11,7 +12,7 @@ namespace Iceshrimp.Backend.Components.PublicPreview.Renderers;
public readonly record struct MfmRenderData(MarkupString Html, List<MfmInlineMedia> InlineMedia); public readonly record struct MfmRenderData(MarkupString Html, List<MfmInlineMedia> InlineMedia);
[UsedImplicitly] [UsedImplicitly]
public class MfmRenderer(MfmConverter converter) : ISingletonService public class MfmRenderer(MfmConverter converter, FlagService flags) : ISingletonService
{ {
public async Task<MfmRenderData?> RenderAsync( public async Task<MfmRenderData?> RenderAsync(
string? text, string? host, List<Note.MentionedUser> mentions, List<Emoji> emoji, string rootElement, string? text, string? host, List<Note.MentionedUser> mentions, List<Emoji> emoji, string rootElement,
@ -22,8 +23,8 @@ public class MfmRenderer(MfmConverter converter) : ISingletonService
var parsed = MfmParser.Parse(text); var parsed = MfmParser.Parse(text);
// Ensure we are rendering HTML markup (AsyncLocal) // Ensure we are rendering HTML markup (AsyncLocal)
converter.SupportsHtmlFormatting.Value = true; flags.SupportsHtmlFormatting.Value = true;
converter.SupportsInlineMedia.Value = true; flags.SupportsInlineMedia.Value = true;
var mfmInlineMedia = media?.Select(m => new MfmInlineMedia(MfmInlineMedia.GetType(m.MimeType), m.Url, m.Alt)).ToList(); var mfmInlineMedia = media?.Select(m => new MfmInlineMedia(MfmInlineMedia.GetType(m.MimeType), m.Url, m.Alt)).ToList();
var serialized = await converter.ToHtmlAsync(parsed, mentions, host, emoji: emoji, rootElement: rootElement, media: mfmInlineMedia); var serialized = await converter.ToHtmlAsync(parsed, mentions, host, emoji: emoji, rootElement: rootElement, media: mfmInlineMedia);

View file

@ -8,7 +8,6 @@ using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Events; using Iceshrimp.Backend.Core.Events;
using Iceshrimp.Backend.Core.Extensions; using Iceshrimp.Backend.Core.Extensions;
using Iceshrimp.Backend.Core.Helpers; using Iceshrimp.Backend.Core.Helpers;
using Iceshrimp.Backend.Core.Helpers.LibMfm.Conversion;
using Iceshrimp.Backend.Core.Services; using Iceshrimp.Backend.Core.Services;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -394,9 +393,10 @@ public sealed class WebSocketConnection(
private void InitializeScopeLocalParameters(IServiceScope scope) private void InitializeScopeLocalParameters(IServiceScope scope)
{ {
var mfmConverter = scope.ServiceProvider.GetRequiredService<MfmConverter>(); var flags = scope.ServiceProvider.GetRequiredService<FlagService>();
mfmConverter.SupportsHtmlFormatting.Value = Token.SupportsHtmlFormatting; flags.SupportsHtmlFormatting.Value = Token.SupportsHtmlFormatting;
mfmConverter.SupportsInlineMedia.Value = Token.SupportsInlineMedia; flags.SupportsInlineMedia.Value = Token.SupportsInlineMedia;
flags.IsPleroma.Value = Token.IsPleroma;
} }
public async Task CloseAsync(WebSocketCloseStatus status) public async Task CloseAsync(WebSocketCloseStatus status)

View file

@ -43,12 +43,10 @@ public readonly record struct MfmHtmlData(string Html, List<MfmInlineMedia> Inli
public class MfmConverter( public class MfmConverter(
IOptions<Config.InstanceSection> config, IOptions<Config.InstanceSection> config,
MediaProxyService mediaProxy MediaProxyService mediaProxy,
FlagService flags
) : ISingletonService ) : ISingletonService
{ {
public AsyncLocal<bool> SupportsHtmlFormatting { get; } = new();
public AsyncLocal<bool> SupportsInlineMedia { get; } = new();
public static async Task<HtmlMfmData> FromHtmlAsync( public static async Task<HtmlMfmData> FromHtmlAsync(
string? html, List<Note.MentionedUser>? mentions = null, List<string>? hashtags = null string? html, List<Note.MentionedUser>? mentions = null, List<string>? hashtags = null
) )
@ -194,7 +192,7 @@ public class MfmConverter(
{ {
usedMedia.Add(current); usedMedia.Add(current);
if (!SupportsInlineMedia.Value || current.Type == MfmInlineMedia.MediaType.Other) if (!flags.SupportsInlineMedia.Value || current.Type == MfmInlineMedia.MediaType.Other)
{ {
var el = document.CreateElement("a"); var el = document.CreateElement("a");
el.SetAttribute("href", current.Src); el.SetAttribute("href", current.Src);
@ -452,12 +450,12 @@ public class MfmConverter(
private IElement CreateInlineFormattingElement(IDocument document, string name) private IElement CreateInlineFormattingElement(IDocument document, string name)
{ {
return document.CreateElement(SupportsHtmlFormatting.Value ? name : "span"); return document.CreateElement(flags.SupportsHtmlFormatting.Value ? name : "span");
} }
private void AddHtmlMarkup(IDocument document, IElement node, string chars) private void AddHtmlMarkup(IDocument document, IElement node, string chars)
{ {
if (SupportsHtmlFormatting.Value) return; if (flags.SupportsHtmlFormatting.Value) return;
var el = document.CreateElement("span"); var el = document.CreateElement("span");
el.AppendChild(document.CreateTextNode(chars)); el.AppendChild(document.CreateTextNode(chars));
node.AppendChild(el); node.AppendChild(el);
@ -465,7 +463,7 @@ public class MfmConverter(
private void AddHtmlMarkupTag(IDocument document, IElement node, string tag) private void AddHtmlMarkupTag(IDocument document, IElement node, string tag)
{ {
if (SupportsHtmlFormatting.Value) return; if (flags.SupportsHtmlFormatting.Value) return;
var el = document.CreateElement(tag); var el = document.CreateElement(tag);
node.AppendChild(el); node.AppendChild(el);
} }

View file

@ -1,10 +1,8 @@
using Iceshrimp.Backend.Controllers.Mastodon.Attributes; using Iceshrimp.Backend.Controllers.Mastodon.Attributes;
using Iceshrimp.Backend.Controllers.Mastodon.Renderers;
using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Extensions; using Iceshrimp.Backend.Core.Extensions;
using Iceshrimp.Backend.Core.Helpers; using Iceshrimp.Backend.Core.Helpers;
using Iceshrimp.Backend.Core.Helpers.LibMfm.Conversion;
using Iceshrimp.Backend.Core.Services; using Iceshrimp.Backend.Core.Services;
using Microsoft.AspNetCore.Components.Endpoints; using Microsoft.AspNetCore.Components.Endpoints;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -14,8 +12,7 @@ namespace Iceshrimp.Backend.Core.Middleware;
public class AuthenticationMiddleware( public class AuthenticationMiddleware(
DatabaseContext db, DatabaseContext db,
UserService userSvc, UserService userSvc,
MfmConverter mfmConverter, FlagService flags
NoteRenderer mastoNoteRenderer
) : ConditionalMiddleware<AuthenticateAttribute>, IMiddlewareService ) : ConditionalMiddleware<AuthenticateAttribute>, IMiddlewareService
{ {
public static ServiceLifetime Lifetime => ServiceLifetime.Scoped; public static ServiceLifetime Lifetime => ServiceLifetime.Scoped;
@ -81,9 +78,9 @@ public class AuthenticationMiddleware(
userSvc.UpdateOauthTokenMetadata(oauthToken); userSvc.UpdateOauthTokenMetadata(oauthToken);
ctx.SetOauthToken(oauthToken); ctx.SetOauthToken(oauthToken);
mfmConverter.SupportsHtmlFormatting.Value = oauthToken.SupportsHtmlFormatting; flags.SupportsHtmlFormatting.Value = oauthToken.SupportsHtmlFormatting;
mfmConverter.SupportsInlineMedia.Value = oauthToken.SupportsInlineMedia; flags.SupportsInlineMedia.Value = oauthToken.SupportsInlineMedia;
mastoNoteRenderer.IsPleroma = oauthToken.IsPleroma; flags.IsPleroma.Value = oauthToken.IsPleroma;
} }
else else
{ {

View file

@ -5,7 +5,6 @@ using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Extensions; using Iceshrimp.Backend.Core.Extensions;
using Iceshrimp.Backend.Core.Federation.Cryptography; using Iceshrimp.Backend.Core.Federation.Cryptography;
using Iceshrimp.Backend.Core.Helpers.LibMfm.Conversion;
using Iceshrimp.Backend.Core.Services; using Iceshrimp.Backend.Core.Services;
using Iceshrimp.Utils.Common; using Iceshrimp.Utils.Common;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -25,7 +24,7 @@ public class AuthorizedFetchMiddleware(
ActivityPub.FederationControlService fedCtrlSvc, ActivityPub.FederationControlService fedCtrlSvc,
ILogger<AuthorizedFetchMiddleware> logger, ILogger<AuthorizedFetchMiddleware> logger,
IHostApplicationLifetime appLifetime, IHostApplicationLifetime appLifetime,
MfmConverter mfmConverter FlagService flags
) : ConditionalMiddleware<AuthorizedFetchAttribute>, IMiddlewareService ) : ConditionalMiddleware<AuthorizedFetchAttribute>, IMiddlewareService
{ {
public static ServiceLifetime Lifetime => ServiceLifetime.Scoped; public static ServiceLifetime Lifetime => ServiceLifetime.Scoped;
@ -36,8 +35,8 @@ public class AuthorizedFetchMiddleware(
public async Task InvokeAsync(HttpContext ctx, RequestDelegate next) public async Task InvokeAsync(HttpContext ctx, RequestDelegate next)
{ {
// Ensure we're rendering HTML markup (AsyncLocal) // Ensure we're rendering HTML markup (AsyncLocal)
mfmConverter.SupportsHtmlFormatting.Value = true; flags.SupportsHtmlFormatting.Value = true;
mfmConverter.SupportsInlineMedia.Value = true; flags.SupportsInlineMedia.Value = true;
// Short-circuit fetches when signature validation is disabled // Short-circuit fetches when signature validation is disabled
if (config.Value is { AuthorizedFetch: false, ValidateRequestSignatures: false }) if (config.Value is { AuthorizedFetch: false, ValidateRequestSignatures: false })

View file

@ -0,0 +1,12 @@
using Iceshrimp.Backend.Core.Extensions;
using JetBrains.Annotations;
namespace Iceshrimp.Backend.Core.Services;
[UsedImplicitly]
public class FlagService : ISingletonService
{
public AsyncLocal<bool> SupportsHtmlFormatting { get; } = new();
public AsyncLocal<bool> SupportsInlineMedia { get; } = new();
public AsyncLocal<bool> IsPleroma { get; } = new();
}