blossom.go raw
1 package app
2
3 import (
4 "context"
5 "net/http"
6 "strings"
7
8 "next.orly.dev/pkg/lol/log"
9 "next.orly.dev/app/config"
10 "next.orly.dev/pkg/acl"
11 "next.orly.dev/pkg/database"
12 blossom "next.orly.dev/pkg/blossom"
13 )
14
15 // initializeBlossomServer creates and configures the Blossom blob storage server
16 func initializeBlossomServer(
17 ctx context.Context, cfg *config.C, db database.Database,
18 ) (*blossom.Server, error) {
19 // Create blossom server configuration
20 blossomCfg := &blossom.Config{
21 BaseURL: "", // Will be set dynamically per request
22 MaxBlobSize: 100 * 1024 * 1024, // 100MB default
23 AllowedMimeTypes: nil, // Allow all MIME types by default
24 RequireAuth: cfg.AuthRequired || cfg.AuthToWrite,
25 // Rate limiting for non-followed users
26 RateLimitEnabled: cfg.BlossomRateLimitEnabled,
27 DailyLimitMB: cfg.BlossomDailyLimitMB,
28 BurstLimitMB: cfg.BlossomBurstLimitMB,
29 // Delete replay protection (proposed BUD enhancement)
30 DeleteRequireServerTag: cfg.BlossomDeleteRequireServerTag,
31 }
32
33 // Create blossom server with relay's ACL registry
34 bs := blossom.NewServer(db, acl.Registry, blossomCfg)
35
36 // Override baseURL getter to use request-based URL
37 // We'll need to modify the handler to inject the baseURL per request
38 // For now, we'll use a middleware approach
39
40 if cfg.BlossomRateLimitEnabled {
41 log.I.F("blossom server initialized with ACL mode: %s, rate limit: %dMB/day (burst: %dMB)",
42 cfg.ACLMode, cfg.BlossomDailyLimitMB, cfg.BlossomBurstLimitMB)
43 } else {
44 log.I.F("blossom server initialized with ACL mode: %s", cfg.ACLMode)
45 }
46 return bs, nil
47 }
48
49 // blossomHandler wraps the blossom server handler to inject baseURL per request
50 func (s *Server) blossomHandler(w http.ResponseWriter, r *http.Request) {
51 // Strip /blossom prefix and pass to blossom handler
52 r.URL.Path = strings.TrimPrefix(r.URL.Path, "/blossom")
53 if !strings.HasPrefix(r.URL.Path, "/") {
54 r.URL.Path = "/" + r.URL.Path
55 }
56
57 // Set baseURL in request context for blossom server to use
58 // Use the exported key type from the blossom package
59 baseURL := s.ServiceURL(r) + "/blossom"
60 r = r.WithContext(context.WithValue(r.Context(), blossom.BaseURLKey{}, baseURL))
61
62 s.blossomServer.Handler().ServeHTTP(w, r)
63 }
64
65 // blossomRootHandler handles blossom requests at root level (for clients like Jumble)
66 // Note: Even though requests come to root-level paths like /upload, we return URLs
67 // with /blossom prefix because that's where the blob download handlers are registered.
68 func (s *Server) blossomRootHandler(w http.ResponseWriter, r *http.Request) {
69 // Set baseURL with /blossom prefix so returned blob URLs point to working handlers
70 baseURL := s.ServiceURL(r) + "/blossom"
71 r = r.WithContext(context.WithValue(r.Context(), blossom.BaseURLKey{}, baseURL))
72
73 s.blossomServer.Handler().ServeHTTP(w, r)
74 }
75
76