mcp connection
Some checks failed
CI / fixture (push) Has been cancelled
CI / test (push) Has been cancelled

This commit is contained in:
2026-09-22 10:58:02 +05:30
parent 4e1f746b22
commit f2aa3b3ad8
53 changed files with 12515 additions and 37 deletions

View File

@@ -1,9 +1,6 @@
package httpserver
import (
"net"
"net/http"
"strings"
"sync"
"time"
)
@@ -23,12 +20,13 @@ import (
// one instance needs shared state — Redis, or the database — and this
// package is the seam where that goes: attemptLimiter is an implementation
// detail behind Allow/Fail/Reset.
// - It trusts net/http's RemoteAddr for the client address. Behind a reverse
// proxy every request appears to come from the proxy, so the per-address
// budget becomes global. Reading X-Forwarded-For instead would be worse,
// not better, until there is a trusted-proxy list to validate it against —
// a client can send that header itself and mint a fresh budget per request.
// Deploying behind a proxy means adding that list first.
// - The per-address budget is only as good as the address. That used to be
// net/http's RemoteAddr, which behind a reverse proxy is the proxy on
// every request and makes this budget global. It is now resolved by
// proxyTrust.clientAddr (clientip.go), which reads a forwarded address
// when — and only when — the immediate peer is a configured trusted
// proxy. An unconfigured deployment still gets RemoteAddr, so a proxied
// deployment must set HTTP_TRUSTED_PROXIES for this limit to be per-user.
// - It is memory-bounded by pruning, not by a hard cap, so a flood from many
// distinct addresses grows the map until the next prune.
//
@@ -139,16 +137,3 @@ func (l *attemptLimiter) pruneLocked(now time.Time) {
}
}
}
// clientAddr is the key for per-address limiting.
//
// The port is stripped: a browser uses a new source port for every connection,
// so keying on host:port would give each attempt its own budget and limit
// nothing at all.
func clientAddr(r *http.Request) string {
host, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr))
if err != nil {
return strings.TrimSpace(r.RemoteAddr)
}
return host
}