[backend/federation] Fall back to JRD during host-meta step of the WebFinger process (ISH-162)
This commit is contained in:
parent
91137b7fd9
commit
0833cf49d2
2 changed files with 72 additions and 8 deletions
|
@ -2,14 +2,26 @@ using J = System.Text.Json.Serialization.JsonPropertyNameAttribute;
|
|||
|
||||
namespace Iceshrimp.Backend.Controllers.Federation.Schemas;
|
||||
|
||||
public class HostMetaJsonResponse(string webDomain)
|
||||
public class HostMetaJsonResponse()
|
||||
{
|
||||
[J("links")] public List<HostMetaJsonResponseLink> Links => [new HostMetaJsonResponseLink(webDomain)];
|
||||
public HostMetaJsonResponse(string webDomain) : this()
|
||||
{
|
||||
Links = [new HostMetaJsonResponseLink(webDomain)];
|
||||
}
|
||||
|
||||
[J("links")] public List<HostMetaJsonResponseLink>? Links { get; set; }
|
||||
}
|
||||
|
||||
public class HostMetaJsonResponseLink(string webDomain)
|
||||
public class HostMetaJsonResponseLink()
|
||||
{
|
||||
[J("rel")] public string Rel => "lrdd";
|
||||
[J("type")] public string Type => "application/jrd+json";
|
||||
[J("template")] public string Template => $"https://{webDomain}/.well-known/webfinger?resource={{uri}}";
|
||||
public HostMetaJsonResponseLink(string webDomain) : this()
|
||||
{
|
||||
Rel = "lrdd";
|
||||
Type = "application/jrd+json";
|
||||
Template = $"https://{webDomain}/.well-known/webfinger?resource={{uri}}";
|
||||
}
|
||||
|
||||
[J("rel")] public string? Rel { get; set; }
|
||||
[J("type")] public string? Type { get; set; }
|
||||
[J("template")] public string? Template { get; set; }
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using System.Net;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Xml;
|
||||
using Iceshrimp.Backend.Controllers.Federation.Schemas;
|
||||
using Iceshrimp.Backend.Core.Middleware;
|
||||
using Iceshrimp.Backend.Core.Services;
|
||||
|
||||
|
@ -75,17 +76,20 @@ public class WebFingerService(HttpClient client, HttpRequestService httpRqSvc, I
|
|||
|
||||
private async Task<string> GetWebFingerUrlAsync(string query, string proto, string domain)
|
||||
{
|
||||
var template = await GetWebFingerTemplateFromHostMetaAsync($"{proto}://{domain}/.well-known/host-meta") ??
|
||||
var template = await GetWebFingerTemplateFromHostMetaXmlAsync(proto, domain) ??
|
||||
await GetWebFingerTemplateFromHostMetaJsonAsync(proto, domain) ??
|
||||
$"{proto}://{domain}/.well-known/webfinger?resource={{uri}}";
|
||||
|
||||
var finalQuery = query.StartsWith('@') ? $"acct:{query[1..]}" : query;
|
||||
var encoded = UrlEncoder.Default.Encode(finalQuery);
|
||||
return template.Replace("{uri}", encoded);
|
||||
}
|
||||
|
||||
private async Task<string?> GetWebFingerTemplateFromHostMetaAsync(string hostMetaUrl)
|
||||
private async Task<string?> GetWebFingerTemplateFromHostMetaXmlAsync(string proto, string domain)
|
||||
{
|
||||
try
|
||||
{
|
||||
var hostMetaUrl = $"{proto}://{domain}/.well-known/host-meta";
|
||||
using var res = await client.SendAsync(httpRqSvc.Get(hostMetaUrl, ["application/xrd+xml"]),
|
||||
HttpCompletionOption.ResponseHeadersRead);
|
||||
using var stream = await res.Content.ReadAsStreamAsync();
|
||||
|
@ -109,4 +113,52 @@ public class WebFingerService(HttpClient client, HttpRequestService httpRqSvc, I
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string?> GetWebFingerTemplateFromHostMetaJsonAsync(string proto, string domain)
|
||||
{
|
||||
try
|
||||
{
|
||||
var hostMetaUrl = $"{proto}://{domain}/.well-known/host-meta.json";
|
||||
using var res = await client.SendAsync(httpRqSvc.Get(hostMetaUrl, ["application/jrd+json"]),
|
||||
HttpCompletionOption.ResponseHeadersRead);
|
||||
var deserialized = await res.Content.ReadFromJsonAsync<HostMetaJsonResponse>();
|
||||
|
||||
var result = deserialized?.Links?.FirstOrDefault(p => p is
|
||||
{
|
||||
Rel: "lrdd",
|
||||
Type: "application/jrd+json",
|
||||
Template: not null
|
||||
});
|
||||
|
||||
if (result?.Template != null)
|
||||
return result.Template;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var hostMetaUrl = $"{proto}://{domain}/.well-known/host-meta";
|
||||
using var res = await client.SendAsync(httpRqSvc.Get(hostMetaUrl, ["application/jrd+json"]),
|
||||
HttpCompletionOption.ResponseHeadersRead);
|
||||
var deserialized = await res.Content.ReadFromJsonAsync<HostMetaJsonResponse>();
|
||||
|
||||
var result = deserialized?.Links?.FirstOrDefault(p => p is
|
||||
{
|
||||
Rel: "lrdd",
|
||||
Type: "application/jrd+json",
|
||||
Template: not null
|
||||
});
|
||||
|
||||
return result?.Template;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue