Some checks are pending
Go / build-and-release (push) Waiting to run
- Add token-bucket bandwidth rate limiting for Blossom uploads - ORLY_BLOSSOM_RATE_LIMIT enables limiting (default: false) - ORLY_BLOSSOM_DAILY_LIMIT_MB sets daily limit (default: 10MB) - ORLY_BLOSSOM_BURST_LIMIT_MB sets burst cap (default: 50MB) - Followed users, admins, owners are exempt (unlimited) - Change emergency mode throttling from exponential to linear scaling - Old: 16x multiplier at emergency threshold entry - New: 1x at threshold, +1x per 20% excess pressure - Reduce follows ACL throttle increment from 200ms to 25ms per event - Update dependencies Files modified: - app/blossom.go: Pass rate limit config to blossom server - app/config/config.go: Add Blossom rate limit config options - pkg/blossom/ratelimit.go: New bandwidth limiter implementation - pkg/blossom/server.go: Add rate limiter integration - pkg/blossom/handlers.go: Check rate limits on upload/mirror/media - pkg/ratelimit/limiter.go: Linear emergency throttling - pkg/acl/follows.go: Reduce default throttle increment Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
74 lines
2.6 KiB
Go
74 lines
2.6 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"lol.mleku.dev/log"
|
|
"next.orly.dev/app/config"
|
|
"next.orly.dev/pkg/acl"
|
|
"next.orly.dev/pkg/database"
|
|
blossom "next.orly.dev/pkg/blossom"
|
|
)
|
|
|
|
// initializeBlossomServer creates and configures the Blossom blob storage server
|
|
func initializeBlossomServer(
|
|
ctx context.Context, cfg *config.C, db *database.D,
|
|
) (*blossom.Server, error) {
|
|
// Create blossom server configuration
|
|
blossomCfg := &blossom.Config{
|
|
BaseURL: "", // Will be set dynamically per request
|
|
MaxBlobSize: 100 * 1024 * 1024, // 100MB default
|
|
AllowedMimeTypes: nil, // Allow all MIME types by default
|
|
RequireAuth: cfg.AuthRequired || cfg.AuthToWrite,
|
|
// Rate limiting for non-followed users
|
|
RateLimitEnabled: cfg.BlossomRateLimitEnabled,
|
|
DailyLimitMB: cfg.BlossomDailyLimitMB,
|
|
BurstLimitMB: cfg.BlossomBurstLimitMB,
|
|
}
|
|
|
|
// Create blossom server with relay's ACL registry
|
|
bs := blossom.NewServer(db, acl.Registry, blossomCfg)
|
|
|
|
// Override baseURL getter to use request-based URL
|
|
// We'll need to modify the handler to inject the baseURL per request
|
|
// For now, we'll use a middleware approach
|
|
|
|
if cfg.BlossomRateLimitEnabled {
|
|
log.I.F("blossom server initialized with ACL mode: %s, rate limit: %dMB/day (burst: %dMB)",
|
|
cfg.ACLMode, cfg.BlossomDailyLimitMB, cfg.BlossomBurstLimitMB)
|
|
} else {
|
|
log.I.F("blossom server initialized with ACL mode: %s", cfg.ACLMode)
|
|
}
|
|
return bs, nil
|
|
}
|
|
|
|
// blossomHandler wraps the blossom server handler to inject baseURL per request
|
|
func (s *Server) blossomHandler(w http.ResponseWriter, r *http.Request) {
|
|
// Strip /blossom prefix and pass to blossom handler
|
|
r.URL.Path = strings.TrimPrefix(r.URL.Path, "/blossom")
|
|
if !strings.HasPrefix(r.URL.Path, "/") {
|
|
r.URL.Path = "/" + r.URL.Path
|
|
}
|
|
|
|
// Set baseURL in request context for blossom server to use
|
|
// Use the exported key type from the blossom package
|
|
baseURL := s.ServiceURL(r) + "/blossom"
|
|
r = r.WithContext(context.WithValue(r.Context(), blossom.BaseURLKey{}, baseURL))
|
|
|
|
s.blossomServer.Handler().ServeHTTP(w, r)
|
|
}
|
|
|
|
// blossomRootHandler handles blossom requests at root level (for clients like Jumble)
|
|
// Note: Even though requests come to root-level paths like /upload, we return URLs
|
|
// with /blossom prefix because that's where the blob download handlers are registered.
|
|
func (s *Server) blossomRootHandler(w http.ResponseWriter, r *http.Request) {
|
|
// Set baseURL with /blossom prefix so returned blob URLs point to working handlers
|
|
baseURL := s.ServiceURL(r) + "/blossom"
|
|
r = r.WithContext(context.WithValue(r.Context(), blossom.BaseURLKey{}, baseURL))
|
|
|
|
s.blossomServer.Handler().ServeHTTP(w, r)
|
|
}
|
|
|