package server import ( "net/http" "time" "agent-system-backend/internal/ratelimit" ) // 限流中间件(阶段 3):按租户 owner 固定窗口;limit<=0(默认)直接放行。 // 位于认证之后(key=owner);Limiter/LimitLookup 由组合根注入。 func (s *Server) withRateLimit(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if s.Limiter != nil && s.LimitLookup != nil { if limit := s.LimitLookup(); limit > 0 { if !s.Limiter.Allow(r.Context(), "owner:"+s.owner(r), limit, time.Minute) { http.Error(w, "rate limit exceeded(runtime.rateLimitPerMin)", http.StatusTooManyRequests) return } } } next.ServeHTTP(w, r) }) } var _ = ratelimit.Memory{} // 接口形状锚点(Limiter 注入自组合根)