MCPcopy Index your code
hub / github.com/PatchMon/PatchMon / Middleware

Function Middleware

server-source-code/internal/context/middleware.go:45–110  ·  view source on GitHub ↗

Middleware returns a middleware that resolves the host from X-Forwarded-Host, injects the host's database and Redis client into context, and returns 503 if the host is not found. When X-Forwarded-Host is absent (e.g. health checks, direct connections), defaultDB and defaultRDB are injected if non-ni

(registry *Registry, poolCache *PoolCache, redisCache *RedisCache, defaultDB *database.DB, defaultRDB *redis.Client, reloadSecret string)

Source from the content-addressed store, hash-verified

43// injects the host's database and Redis client into context, and returns 503 if the host is not found.
44// When X-Forwarded-Host is absent (e.g. health checks, direct connections), defaultDB and defaultRDB are injected if non-nil.
45func Middleware(registry *Registry, poolCache *PoolCache, redisCache *RedisCache, defaultDB *database.DB, defaultRDB *redis.Client, reloadSecret string) func(http.Handler) http.Handler {
46 return func(next http.Handler) http.Handler {
47 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
48 host := strings.TrimSpace(r.Header.Get("X-Forwarded-Host"))
49 if host == "" {
50 ctx := r.Context()
51 if defaultDB != nil {
52 ctx = WithDB(ctx, defaultDB)
53 }
54 if defaultRDB != nil {
55 ctx = WithRedis(ctx, defaultRDB)
56 }
57 next.ServeHTTP(w, r.WithContext(ctx))
58 return
59 }
60
61 if registry == nil || poolCache == nil {
62 next.ServeHTTP(w, r)
63 return
64 }
65
66 db, err := poolCache.GetOrCreate(r.Context(), host)
67 if err != nil {
68 w.Header().Set("Content-Type", "application/json")
69 w.WriteHeader(http.StatusServiceUnavailable)
70 _ = json.NewEncoder(w).Encode(map[string]string{
71 "error": "service temporarily unavailable",
72 "code": "db_error",
73 })
74 return
75 }
76 if db == nil {
77 w.Header().Set("Content-Type", "application/json")
78 w.WriteHeader(http.StatusServiceUnavailable)
79 _ = json.NewEncoder(w).Encode(map[string]string{
80 "error": "host not found or suspended",
81 "code": "host_not_found",
82 })
83 return
84 }
85
86 ctx := WithDB(r.Context(), db)
87
88 // Inject host registry entry so handlers can check package limits (MaxUsers, MaxHosts, Modules).
89 if entry := registry.GetByHost(host); entry != nil {
90 ctx = WithEntry(ctx, entry)
91 }
92
93 // Resolve per-host Redis; falls back to defaultRDB if no Redis credentials in registry.
94 if redisCache != nil {
95 rdb, rdbErr := redisCache.GetOrCreate(r.Context(), host)
96 if rdbErr != nil {
97 // Log but don't block - fall back to default Redis rather than returning 503.
98 rdb = redisCache.Default()
99 }
100 if rdb != nil {
101 ctx = WithRedis(ctx, rdb)
102 }

Callers

nothing calls this directly

Calls 8

WithDBFunction · 0.85
WithRedisFunction · 0.85
WithEntryFunction · 0.85
DefaultMethod · 0.80
GetMethod · 0.45
GetOrCreateMethod · 0.45
SetMethod · 0.45
GetByHostMethod · 0.45

Tested by

no test coverage detected