Why: Allow consumers to download an immutable module revision without nested source checkouts or local path replacements. Evidence: SELF package tests and the prior canonical-path rejection are recorded in the Dev dependency-workspace task card; remote consumption is replayed against the committed candidate. Impact: Change the module identity and its Go imports while preserving API behavior. Existing historical submodule revisions remain buildable. Refs: Versioned dependencies U1/U3; feature/dependency-workspace
27 lines
859 B
Go
27 lines
859 B
Go
package server
|
||
|
||
import (
|
||
"net/http"
|
||
"time"
|
||
|
||
"git-ssh.u1680832.nyat.app/weichen/Agent-System-Backend.git/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 注入自组合根)
|