mirror of
https://gitlab.melroy.org/melroy/fediresolve.git
synced 2025-06-07 20:08:57 +00:00
Improve performance
This commit is contained in:
parent
1c8dad5500
commit
d85cf4bd11
3 changed files with 67 additions and 108 deletions
|
@ -1,7 +1,6 @@
|
||||||
package formatter
|
package formatter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -13,13 +12,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Format takes ActivityPub data and returns a formatted string representation
|
// Format takes ActivityPub data and returns a formatted string representation
|
||||||
func Format(data map[string]interface{}) (string, error) {
|
func Format(jsonData []byte) (string, error) {
|
||||||
// First, get the beautified JSON
|
|
||||||
jsonData, err := json.MarshalIndent(data, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("error formatting JSON: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a summary based on the object type
|
// Create a summary based on the object type
|
||||||
summary := createSummary(jsonData)
|
summary := createSummary(jsonData)
|
||||||
|
|
||||||
|
|
|
@ -24,31 +24,31 @@ const (
|
||||||
|
|
||||||
// fetchActivityPubObjectWithSignature is a helper function that always signs HTTP requests
|
// fetchActivityPubObjectWithSignature is a helper function that always signs HTTP requests
|
||||||
// This is the preferred way to fetch ActivityPub content as many instances require signatures
|
// This is the preferred way to fetch ActivityPub content as many instances require signatures
|
||||||
func (r *Resolver) fetchActivityPubObjectWithSignature(objectURL string) ([]byte, map[string]interface{}, error) {
|
func (r *Resolver) fetchActivityPubObjectWithSignature(objectURL string) ([]byte, error) {
|
||||||
fmt.Printf("Fetching ActivityPub object with HTTP signatures from: %s\n", objectURL)
|
fmt.Printf("Fetching ActivityPub object with HTTP signatures from: %s\n", objectURL)
|
||||||
|
|
||||||
// Fetch the object itself
|
// Fetch the object itself
|
||||||
_, data, err := r.fetchActivityPubObjectDirect(objectURL)
|
data, err := r.fetchActivityPubObjectDirect(objectURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the public key ID
|
// Extract the public key ID
|
||||||
keyID, err := r.extractPublicKey(data)
|
keyID, err := r.extractPublicKey(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("could not extract public key: %v", err)
|
return nil, fmt.Errorf("could not extract public key: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new private key for signing (in a real app, we would use a persistent key)
|
// Create a new private key for signing (in a real app, we would use a persistent key)
|
||||||
privateKey, err := generateRSAKey()
|
privateKey, err := generateRSAKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("could not generate RSA key: %v", err)
|
return nil, fmt.Errorf("could not generate RSA key: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, sign and send the request
|
// Now, sign and send the request
|
||||||
req, err := http.NewRequest("GET", objectURL, nil)
|
req, err := http.NewRequest("GET", objectURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error creating signed request: %v", err)
|
return nil, fmt.Errorf("error creating signed request: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set headers
|
// Set headers
|
||||||
|
@ -58,42 +58,36 @@ func (r *Resolver) fetchActivityPubObjectWithSignature(objectURL string) ([]byte
|
||||||
|
|
||||||
// Sign the request
|
// Sign the request
|
||||||
if err := signRequest(req, keyID, privateKey); err != nil {
|
if err := signRequest(req, keyID, privateKey); err != nil {
|
||||||
return nil, nil, fmt.Errorf("could not sign request: %v", err)
|
return nil, fmt.Errorf("could not sign request: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the request
|
// Send the request
|
||||||
fmt.Printf("Sending signed request with headers: %v\n", req.Header)
|
fmt.Printf("Sending signed request with headers: %v\n", req.Header)
|
||||||
resp, err := r.client.Do(req)
|
resp, err := r.client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error sending signed request: %v", err)
|
return nil, fmt.Errorf("error sending signed request: %v", err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
body, _ := io.ReadAll(resp.Body)
|
body, _ := io.ReadAll(resp.Body)
|
||||||
return nil, nil, fmt.Errorf("signed request failed with status: %s, body: %s", resp.Status, string(body))
|
return nil, fmt.Errorf("signed request failed with status: %s, body: %s", resp.Status, string(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
bodyBytes, err := io.ReadAll(resp.Body)
|
bodyBytes, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error reading response: %v", err)
|
return nil, fmt.Errorf("error reading response: %v", err)
|
||||||
}
|
}
|
||||||
if len(bodyBytes) == 0 {
|
if len(bodyBytes) == 0 {
|
||||||
return nil, nil, fmt.Errorf("received empty response body")
|
return nil, fmt.Errorf("received empty response body")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to decode the JSON response
|
return bodyBytes, nil
|
||||||
var body map[string]interface{}
|
|
||||||
if err := json.Unmarshal(bodyBytes, &body); err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("error decoding signed response: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return bodyBytes, body, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetchActivityPubObjectDirect is a helper function to fetch content without signatures
|
// fetchActivityPubObjectDirect is a helper function to fetch content without signatures
|
||||||
// This is used as a fallback when signing fails
|
// This is used as a fallback when signing fails
|
||||||
func (r *Resolver) fetchActivityPubObjectDirect(objectURL string) ([]byte, map[string]interface{}, error) {
|
func (r *Resolver) fetchActivityPubObjectDirect(objectURL string) ([]byte, error) {
|
||||||
fmt.Printf("Fetching ActivityPub object directly from: %s\n", objectURL)
|
fmt.Printf("Fetching ActivityPub object directly from: %s\n", objectURL)
|
||||||
|
|
||||||
// Create a custom client that doesn't follow redirects automatically
|
// Create a custom client that doesn't follow redirects automatically
|
||||||
|
@ -107,7 +101,7 @@ func (r *Resolver) fetchActivityPubObjectDirect(objectURL string) ([]byte, map[s
|
||||||
// Create the request
|
// Create the request
|
||||||
req, err := http.NewRequest("GET", objectURL, nil)
|
req, err := http.NewRequest("GET", objectURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error creating request: %v", err)
|
return nil, fmt.Errorf("error creating request: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Accept headers to request ActivityPub data
|
// Set Accept headers to request ActivityPub data
|
||||||
|
@ -118,7 +112,7 @@ func (r *Resolver) fetchActivityPubObjectDirect(objectURL string) ([]byte, map[s
|
||||||
fmt.Printf("Sending direct request with headers: %v\n", req.Header)
|
fmt.Printf("Sending direct request with headers: %v\n", req.Header)
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error fetching content: %v", err)
|
return nil, fmt.Errorf("error fetching content: %v", err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
@ -139,13 +133,13 @@ func (r *Resolver) fetchActivityPubObjectDirect(objectURL string) ([]byte, map[s
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
// Read body for error info
|
// Read body for error info
|
||||||
body, _ := io.ReadAll(resp.Body)
|
body, _ := io.ReadAll(resp.Body)
|
||||||
return nil, nil, fmt.Errorf("request failed with status: %s, body: %s", resp.Status, string(body))
|
return nil, fmt.Errorf("request failed with status: %s, body: %s", resp.Status, string(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read and parse the response
|
// Read and parse the response
|
||||||
bodyBytes, err := io.ReadAll(resp.Body)
|
bodyBytes, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error reading response: %v", err)
|
return nil, fmt.Errorf("error reading response: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug output
|
// Debug output
|
||||||
|
@ -153,26 +147,20 @@ func (r *Resolver) fetchActivityPubObjectDirect(objectURL string) ([]byte, map[s
|
||||||
|
|
||||||
// Check if the response is empty
|
// Check if the response is empty
|
||||||
if len(bodyBytes) == 0 {
|
if len(bodyBytes) == 0 {
|
||||||
return nil, nil, fmt.Errorf("received empty response body")
|
return nil, fmt.Errorf("received empty response body")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to decode the JSON response
|
return bodyBytes, nil
|
||||||
var body map[string]interface{}
|
|
||||||
if err := json.Unmarshal(bodyBytes, &body); err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("error decoding response: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return bodyBytes, body, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetchActorData fetches actor data from an actor URL
|
// fetchActorData fetches actor data from an actor URL
|
||||||
func (r *Resolver) fetchActorData(actorURL string) ([]byte, map[string]interface{}, error) {
|
func (r *Resolver) fetchActorData(actorURL string) ([]byte, error) {
|
||||||
fmt.Printf("Fetching actor data from: %s\n", actorURL)
|
fmt.Printf("Fetching actor data from: %s\n", actorURL)
|
||||||
|
|
||||||
// Create the request
|
// Create the request
|
||||||
req, err := http.NewRequest("GET", actorURL, nil)
|
req, err := http.NewRequest("GET", actorURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error creating request: %v", err)
|
return nil, fmt.Errorf("error creating request: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set headers
|
// Set headers
|
||||||
|
@ -182,66 +170,48 @@ func (r *Resolver) fetchActorData(actorURL string) ([]byte, map[string]interface
|
||||||
// Send the request
|
// Send the request
|
||||||
resp, err := r.client.Do(req)
|
resp, err := r.client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error fetching actor data: %v", err)
|
return nil, fmt.Errorf("error fetching actor data: %v", err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return nil, nil, fmt.Errorf("actor request failed with status: %s", resp.Status)
|
return nil, fmt.Errorf("actor request failed with status: %s", resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read and parse the response
|
// Read and parse the response
|
||||||
bodyBytes, err := io.ReadAll(resp.Body)
|
bodyBytes, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error reading actor response: %v", err)
|
return nil, fmt.Errorf("error reading actor response: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse JSON
|
return bodyBytes, nil
|
||||||
var data map[string]interface{}
|
|
||||||
if err := json.Unmarshal(bodyBytes, &data); err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("error parsing actor data: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return bodyBytes, data, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// extractPublicKey extracts the public key ID from actor data
|
// extractPublicKey extracts the public key ID from actor data
|
||||||
func (r *Resolver) extractPublicKey(data map[string]interface{}) (string, error) {
|
func (r *Resolver) extractPublicKey(data []byte) (string, error) {
|
||||||
// Convert to JSON string for easier parsing with gjson
|
// Try to find the attributedTo URL
|
||||||
dataJSON, err := json.Marshal(data)
|
actorURL := gjson.GetBytes(data, "attributedTo").String()
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("error marshaling actor data: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to find the attributedTo URL using dataJSON
|
|
||||||
actorURL := gjson.GetBytes(dataJSON, "attributedTo").String()
|
|
||||||
|
|
||||||
if actorURL == "" {
|
if actorURL == "" {
|
||||||
fmt.Printf("Could not find attributedTo in object\n")
|
fmt.Printf("Could not find attributedTo in object\n")
|
||||||
// Try to find key in the object itself
|
// Try to find key in the object itself
|
||||||
keyID := gjson.GetBytes(dataJSON, "publicKey.id").String()
|
keyID := gjson.GetBytes(data, "publicKey.id").String()
|
||||||
|
|
||||||
if keyID == "" {
|
if keyID == "" {
|
||||||
return "", fmt.Errorf("could not find public key ID in object")
|
return "", fmt.Errorf("could not find public key ID in object")
|
||||||
}
|
}
|
||||||
return keyID, nil
|
return keyID, nil
|
||||||
} else {
|
} else {
|
||||||
_, actorData, err := r.fetchActorData(actorURL)
|
actorData, err := r.fetchActorData(actorURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("error fetching actor data: %v", err)
|
return "", fmt.Errorf("error fetching actor data: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert actorData to JSON
|
|
||||||
actorJSON, err := json.Marshal(actorData)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("error marshaling actor data: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract key ID
|
// Extract key ID
|
||||||
keyID := gjson.GetBytes(actorJSON, "publicKey.id").String()
|
keyID := gjson.GetBytes(actorData, "publicKey.id").String()
|
||||||
if keyID == "" {
|
if keyID == "" {
|
||||||
// Try alternate formats
|
// Try alternate formats
|
||||||
keyID = gjson.GetBytes(actorJSON, "publicKey.0.id").String()
|
keyID = gjson.GetBytes(actorData, "publicKey.0.id").String()
|
||||||
}
|
}
|
||||||
if keyID == "" {
|
if keyID == "" {
|
||||||
fmt.Printf("could not find public key ID in actor data")
|
fmt.Printf("could not find public key ID in actor data")
|
||||||
|
@ -287,22 +257,22 @@ func signRequest(req *http.Request, keyID string, privateKey *rsa.PrivateKey) er
|
||||||
return signer.SignRequest(privateKey, keyID, req, nil)
|
return signer.SignRequest(privateKey, keyID, req, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetchNodeInfo fetches nodeinfo from the given domain, returning the raw JSON and parsed data
|
// fetchNodeInfo fetches nodeinfo from the given domain, returning the raw JSON
|
||||||
func (r *Resolver) fetchNodeInfo(domain string) ([]byte, map[string]interface{}, error) {
|
func (r *Resolver) fetchNodeInfo(domain string) ([]byte, error) {
|
||||||
nodeinfoURL := "https://" + domain + "/.well-known/nodeinfo"
|
nodeinfoURL := "https://" + domain + "/.well-known/nodeinfo"
|
||||||
fmt.Printf("Fetching nodeinfo discovery from: %s\n", nodeinfoURL)
|
fmt.Printf("Fetching nodeinfo discovery from: %s\n", nodeinfoURL)
|
||||||
|
|
||||||
resp, err := r.client.Get(nodeinfoURL)
|
resp, err := r.client.Get(nodeinfoURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error fetching nodeinfo discovery: %v", err)
|
return nil, fmt.Errorf("error fetching nodeinfo discovery: %v", err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return nil, nil, fmt.Errorf("nodeinfo discovery failed with status: %s", resp.Status)
|
return nil, fmt.Errorf("nodeinfo discovery failed with status: %s", resp.Status)
|
||||||
}
|
}
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error reading nodeinfo discovery: %v", err)
|
return nil, fmt.Errorf("error reading nodeinfo discovery: %v", err)
|
||||||
}
|
}
|
||||||
var discovery struct {
|
var discovery struct {
|
||||||
Links []struct {
|
Links []struct {
|
||||||
|
@ -311,7 +281,7 @@ func (r *Resolver) fetchNodeInfo(domain string) ([]byte, map[string]interface{},
|
||||||
} `json:"links"`
|
} `json:"links"`
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(body, &discovery); err != nil {
|
if err := json.Unmarshal(body, &discovery); err != nil {
|
||||||
return nil, nil, fmt.Errorf("error parsing nodeinfo discovery: %v", err)
|
return nil, fmt.Errorf("error parsing nodeinfo discovery: %v", err)
|
||||||
}
|
}
|
||||||
var nodeinfoHref string
|
var nodeinfoHref string
|
||||||
for _, link := range discovery.Links {
|
for _, link := range discovery.Links {
|
||||||
|
@ -329,53 +299,40 @@ func (r *Resolver) fetchNodeInfo(domain string) ([]byte, map[string]interface{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if nodeinfoHref == "" {
|
if nodeinfoHref == "" {
|
||||||
return nil, nil, fmt.Errorf("no nodeinfo schema 2.1 or 2.0 found")
|
return nil, fmt.Errorf("no nodeinfo schema 2.1 or 2.0 found")
|
||||||
}
|
}
|
||||||
fmt.Printf("Fetching nodeinfo from: %s\n", nodeinfoHref)
|
fmt.Printf("Fetching nodeinfo from: %s\n", nodeinfoHref)
|
||||||
resp2, err := r.client.Get(nodeinfoHref)
|
resp2, err := r.client.Get(nodeinfoHref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error fetching nodeinfo: %v", err)
|
return nil, fmt.Errorf("error fetching nodeinfo: %v", err)
|
||||||
}
|
}
|
||||||
defer resp2.Body.Close()
|
defer resp2.Body.Close()
|
||||||
if resp2.StatusCode != http.StatusOK {
|
if resp2.StatusCode != http.StatusOK {
|
||||||
return nil, nil, fmt.Errorf("nodeinfo fetch failed with status: %s", resp2.Status)
|
return nil, fmt.Errorf("nodeinfo fetch failed with status: %s", resp2.Status)
|
||||||
}
|
}
|
||||||
raw, err := io.ReadAll(resp2.Body)
|
raw, err := io.ReadAll(resp2.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("error reading nodeinfo: %v", err)
|
return nil, fmt.Errorf("error reading nodeinfo: %v", err)
|
||||||
}
|
}
|
||||||
var nodeinfo map[string]interface{}
|
return raw, nil
|
||||||
if err := json.Unmarshal(raw, &nodeinfo); err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("error parsing nodeinfo: %v", err)
|
|
||||||
}
|
|
||||||
return raw, nodeinfo, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to extract actor, else try nodeinfo fallback for top-level domains
|
// Try to extract actor, else try nodeinfo fallback for top-level domains
|
||||||
func (r *Resolver) ResolveObjectOrNodeInfo(objectURL string) ([]byte, map[string]interface{}, string, error) {
|
func (r *Resolver) ResolveObjectOrNodeInfo(objectURL string) ([]byte, error) {
|
||||||
// If actor resolution fails, try nodeinfo
|
// If actor resolution fails, try nodeinfo
|
||||||
parts := strings.Split(objectURL, "/")
|
parts := strings.Split(objectURL, "/")
|
||||||
if len(parts) < 3 {
|
if len(parts) < 3 {
|
||||||
return nil, nil, "", fmt.Errorf("invalid object URL: %s", objectURL)
|
return nil, fmt.Errorf("invalid object URL: %s", objectURL)
|
||||||
}
|
}
|
||||||
domain := parts[2]
|
domain := parts[2]
|
||||||
raw, nodeinfo, err := r.fetchNodeInfo(domain)
|
body, err := r.fetchNodeInfo(domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, "", fmt.Errorf("could not fetch nodeinfo: %v", err)
|
return nil, fmt.Errorf("could not fetch nodeinfo: %v", err)
|
||||||
}
|
}
|
||||||
return raw, nodeinfo, "nodeinfo", nil
|
return body, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormatHelperResult wraps formatter.Format for use by resolver.go, keeping formatter import out of resolver.go
|
// Format result
|
||||||
func FormatHelperResult(raw []byte, nodeinfo map[string]interface{}) (string, error) {
|
func formatResult(raw []byte) (string, error) {
|
||||||
return formatter.Format(nodeinfo)
|
return formatter.Format(raw)
|
||||||
}
|
|
||||||
|
|
||||||
// Try to always format (ideally the body data, or in the worse case the raw data to string)
|
|
||||||
func formatResult(raw []byte, data map[string]interface{}) string {
|
|
||||||
formatted, err := formatter.Format(data)
|
|
||||||
if err != nil {
|
|
||||||
return string(raw)
|
|
||||||
}
|
|
||||||
return formatted
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,11 +41,14 @@ func (r *Resolver) Resolve(input string) (string, error) {
|
||||||
parsedURL, err := url.Parse(inputNorm)
|
parsedURL, err := url.Parse(inputNorm)
|
||||||
if err == nil && parsedURL.Host != "" && (parsedURL.Path == "" || parsedURL.Path == "/") && parsedURL.RawQuery == "" && parsedURL.Fragment == "" {
|
if err == nil && parsedURL.Host != "" && (parsedURL.Path == "" || parsedURL.Path == "/") && parsedURL.RawQuery == "" && parsedURL.Fragment == "" {
|
||||||
// Looks like a root domain (with or without scheme), fetch nodeinfo
|
// Looks like a root domain (with or without scheme), fetch nodeinfo
|
||||||
raw, nodeinfo, _, err := r.ResolveObjectOrNodeInfo(parsedURL.String())
|
raw, err := r.ResolveObjectOrNodeInfo(parsedURL.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", fmt.Errorf("error fetching nodeinfo: %v", err)
|
||||||
|
}
|
||||||
|
formatted, err := formatResult(raw)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error formatting nodeinfo: %v", err)
|
||||||
}
|
}
|
||||||
formatted := formatResult(raw, nodeinfo)
|
|
||||||
return formatted, nil
|
return formatted, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +215,10 @@ func (r *Resolver) resolveCanonicalActivityPub(objectURL string, depth int) (str
|
||||||
return r.resolveCanonicalActivityPub(idVal, depth+1)
|
return r.resolveCanonicalActivityPub(idVal, depth+1)
|
||||||
}
|
}
|
||||||
// If no id or already canonical, format and return using helpers.go
|
// If no id or already canonical, format and return using helpers.go
|
||||||
formatted := formatResult(jsonData, data)
|
formatted, err := formatResult(jsonData)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error formatting ActivityPub object: %v", err)
|
||||||
|
}
|
||||||
return formatted, nil
|
return formatted, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,10 +269,13 @@ func (r *Resolver) fetchActivityPubObject(objectURL string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use our signature-first approach by default
|
// Use our signature-first approach by default
|
||||||
raw, body, err := r.fetchActivityPubObjectWithSignature(objectURL)
|
raw, err := r.fetchActivityPubObjectWithSignature(objectURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("error fetching ActivityPub object: %v", err)
|
return "", fmt.Errorf("error fetching ActivityPub object: %v", err)
|
||||||
}
|
}
|
||||||
formatted := formatResult(raw, body)
|
formatted, err := formatResult(raw)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error formatting ActivityPub object: %v", err)
|
||||||
|
}
|
||||||
return formatted, nil
|
return formatted, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue