Documentation
¶
Overview ¶
Package httpserver provides HTTP server helpers for graceful shutdown, JSON responses, strict JSON decoding, pagination, trusted-proxy client IP detection, rate limiting, built-in metrics routes, and embedded UI assets.
Index ¶
- Constants
- func ClientIP(r *http.Request) string
- func DecodeJSON[T any](r *http.Request) (T, error)
- func Heartbeat(ctx context.Context, w http.ResponseWriter, flusher http.Flusher, ...)
- func IsTrustedPeer(r *http.Request) bool
- func ParsePaginationParams(r *http.Request) (offset int64, perPage int64, page int64)
- func Serve(ctx context.Context, addr string, handler http.Handler) error
- func ServeSveltekitStaticFiles(sub fs.FS, fileServer http.Handler) http.HandlerFunc
- func ServeWithListener(ctx context.Context, ln net.Listener, handler http.Handler) error
- func SetTrustedProxyCIDRs(spec string) error
- func WriteData(w http.ResponseWriter, flusher http.Flusher, payload any) error
- func WriteError(w http.ResponseWriter, r *http.Request, status int, err error)
- func WriteJSON(w http.ResponseWriter, r *http.Request, status int, v any)
- type ErrResponse
- type IPRateLimiter
Constants ¶
const DefaultHeartbeatInterval = 15 * time.Second
Variables ¶
This section is empty.
Functions ¶
func ClientIP ¶
ClientIP returns the best-guess client IP address for the request.
Security model:
- X-Forwarded-For is trusted only when the direct peer is in the configured trusted-proxy CIDRs.
- otherwise we ignore forwarded headers and use RemoteAddr directly.
When X-Forwarded-For is trusted, we strip trusted-proxy hops from the right and return the rightmost remaining (untrusted) address — i.e. the leftmost address not appended by a known proxy. This prevents both spoofed leftmost entries and intermediate-proxy IPs from being mistaken for the real client.
func DecodeJSON ¶
DecodeJSON decodes a JSON request body into the specified type T. It ensures that no unknown fields are present and validates the input.
func IsTrustedPeer ¶
IsTrustedPeer reports whether the direct peer of r is in the configured trusted-proxy set.
func ParsePaginationParams ¶
ParsePaginationParams extracts offset, perPage, and page from query parameters.
func Serve ¶
Serve starts HTTP servers on the given addresses with the provided handler. It listens for context cancellation to initiate a graceful shutdown. It returns an error if any server fails to start or if shutdown is problematic.
func ServeSveltekitStaticFiles ¶
ServeSveltekitStaticFiles serves sveltekit static files from the given fs.FS with SPA fallback logic
func ServeWithListener ¶
ServeWithListener starts an HTTP server using a provided net.Listener. Useful for tests: you can create a listener to retrieve the address and control the server's lifecycle from the test.
func SetTrustedProxyCIDRs ¶
SetTrustedProxyCIDRs configures which direct peers are allowed to supply trusted forwarded headers (X-Forwarded-For).
Input format:
- comma-separated CIDRs ("10.0.0.0/8,192.168.1.0/24")
- or comma-separated IPs ("127.0.0.1,::1")
- empty string resets to loopback defaults
- "none" disables forwarded-header trust entirely
func WriteError ¶
WriteError writes an error response with the given status code and error message.
Types ¶
type ErrResponse ¶
type ErrResponse struct {
Error string `json:"error"`
}
ErrResponse is the JSON shape written by WriteError.
type IPRateLimiter ¶
type IPRateLimiter struct {
// contains filtered or unexported fields
}
IPRateLimiter implements a fixed-window rate limiter keyed by client IP.
Design (VictoriaMetrics style):
- No goroutines: cleanup is lazy, triggered inside Allow.
- Single mutex over a plain map: predictable, no lock-free magic.
- Metrics via VictoriaMetrics counters: one label per endpoint.
func NewIPRateLimiter ¶
func NewIPRateLimiter(maxReqs int, window time.Duration) *IPRateLimiter
NewIPRateLimiter returns a limiter that allows maxReqs requests per IP within window.
func (*IPRateLimiter) Allow ¶
func (l *IPRateLimiter) Allow(ip string) bool
Allow reports whether the given IP is within the rate limit. Expired entries are swept lazily every cleanupInterval to keep memory bounded.
func (*IPRateLimiter) Check ¶
func (l *IPRateLimiter) Check(w http.ResponseWriter, r *http.Request) bool
Check reports whether the caller's IP is within the rate limit. On rejection it writes a 429 response with a Retry-After header and returns false; the caller must return immediately (mirrors the CheckSession helper).