From 011efe0dd23d7e380e178f96b87e98fd7dcb23cc Mon Sep 17 00:00:00 2001 From: Anthony Accioly <1591739+aaccioly@users.noreply.github.com> Date: Mon, 12 May 2025 21:42:02 +0100 Subject: [PATCH] feat(server): add functional options for BlossomServer configuration Introduce `ServerOption` to configure `BlossomServer` with functional options. Add `WithRedirectURL` to enable flexible redirect URL handling with placeholders. Update `New` constructor to accept optional configurations. --- blossom/server.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/blossom/server.go b/blossom/server.go index 848c9ab..5bc7cf7 100644 --- a/blossom/server.go +++ b/blossom/server.go @@ -26,11 +26,29 @@ type BlossomServer struct { RejectDelete []func(ctx context.Context, auth *nostr.Event, sha256 string) (bool, string, int) } -func New(rl *khatru.Relay, serviceURL string) *BlossomServer { +// ServerOption represents a functional option for configuring a BlossomServer +type ServerOption func(*BlossomServer) + +// WithRedirectURL configures a redirect URL for the RedirectGet function +func WithRedirectURL(urlTemplate string, statusCode int) ServerOption { + return func(bs *BlossomServer) { + redirectFn := redirectGet(urlTemplate, statusCode) + bs.RedirectGet = append(bs.RedirectGet, redirectFn) + } +} + +// New creates a new BlossomServer with the given relay and service URL +// Optional configuration can be provided via functional options +func New(rl *khatru.Relay, serviceURL string, opts ...ServerOption) *BlossomServer { bs := &BlossomServer{ ServiceURL: serviceURL, } + // Apply any provided options + for _, opt := range opts { + opt(bs) + } + base := rl.Router() mux := http.NewServeMux() @@ -85,3 +103,40 @@ func New(rl *khatru.Relay, serviceURL string) *BlossomServer { return bs } + +// redirectGet returns a function that redirects to a specified URL template with the given status code. +// The URL template can include {sha256} and/or {extension} placeholders that will be replaced +// with the actual values. If neither placeholder is present, {sha256}.{extension} will be +// appended to the URL with proper forward slash handling. +func redirectGet(urlTemplate string, statusCode int) func(context.Context, string, string) (url string, code int, err error) { + return func(ctx context.Context, sha256 string, extension string) (string, int, error) { + finalURL := urlTemplate + + // Replace placeholders if they exist + hasSHA256Placeholder := strings.Contains(finalURL, "{sha256}") + hasExtensionPlaceholder := strings.Contains(finalURL, "{extension}") + + if hasSHA256Placeholder { + finalURL = strings.Replace(finalURL, "{sha256}", sha256, -1) + } + + if hasExtensionPlaceholder { + finalURL = strings.Replace(finalURL, "{extension}", extension, -1) + } + + // If neither placeholder is present, append sha256.extension + if !hasSHA256Placeholder && !hasExtensionPlaceholder { + // Ensure URL ends with a forward slash + if !strings.HasSuffix(finalURL, "/") { + finalURL += "/" + } + + finalURL += sha256 + if extension != "" { + finalURL += "." + extension + } + } + + return finalURL, statusCode, nil + } +}