Documentation
¶
Overview ¶
Package middleware provides a collection of HTTP middleware components for the SRouter framework.
Package middleware provides a collection of HTTP middleware components for the SRouter framework.
Package middleware provides a collection of HTTP middleware components for the SRouter framework.
Package middleware provides a collection of HTTP middleware components for the SRouter framework. These middleware components can be used to add functionality such as logging, recovery from panics, authentication, request timeouts, and more to your HTTP handlers.
Package middleware provides a collection of HTTP middleware components for the SRouter framework.
Package middleware provides a collection of HTTP middleware components for the SRouter framework.
Index ¶
- Variables
- func AddTraceIDToRequest(r *http.Request, traceID string) *http.Request
- func Authentication[T comparable, U any](authFunc func(*http.Request) (T, bool)) common.Middleware
- func AuthenticationBool[T comparable, U any](authFunc func(*http.Request) bool, flagName string) common.Middleware
- func AuthenticationWithProvider[T comparable, U any](provider AuthProvider[T], logger *zap.Logger) common.Middleware
- func AuthenticationWithUser[T comparable, U any](authFunc func(*http.Request) (*U, error)) common.Middleware
- func AuthenticationWithUserProvider[T comparable, U any](provider UserAuthProvider[U], logger *zap.Logger) common.Middleware
- func ClientIP(r *http.Request) string
- func ClientIPMiddleware(config *IPConfig) func(http.Handler) http.Handler
- func ClientIPMiddlewareGeneric[T comparable, U any](config *IPConfig) func(http.Handler) http.Handler
- func CreateRateLimitMiddleware[T comparable, U any](bucketName string, limit int, window time.Duration, strategy RateLimitStrategy, ...) func(http.Handler) http.Handler
- func GetClientIP[T comparable, U any](ctx context.Context) (string, bool)
- func GetClientIPFromRequest[T comparable, U any](r *http.Request) (string, bool)
- func GetFlag[T comparable, U any](ctx context.Context, name string) (bool, bool)
- func GetFlagFromRequest[T comparable, U any](r *http.Request, name string) (bool, bool)
- func GetTraceID(r *http.Request) string
- func GetTraceIDFromContext(ctx context.Context) string
- func GetUser[T comparable, U any](ctx context.Context) (*U, bool)
- func GetUserFromRequest[T comparable, U any](r *http.Request) (*U, bool)
- func GetUserID[T comparable, U any](ctx context.Context) (T, bool)
- func GetUserIDFromRequest[T comparable, U any](r *http.Request) (T, bool)
- func NewAPIKeyMiddleware[T comparable, U any](validKeys map[string]T, header, query string, logger *zap.Logger) common.Middleware
- func NewAPIKeyWithUserMiddleware[T comparable, U any](getUserFunc func(key string) (*U, error), header, query string, ...) common.Middleware
- func NewBearerTokenMiddleware[T comparable, U any](validTokens map[string]T, logger *zap.Logger) common.Middleware
- func NewBearerTokenValidatorMiddleware[T comparable, U any](validator func(string) (T, bool), logger *zap.Logger) common.Middleware
- func NewBearerTokenWithUserMiddleware[T comparable, U any](getUserFunc func(token string) (*U, error), logger *zap.Logger) common.Middleware
- func RateLimit[T comparable, U any](config *RateLimitConfig[T, U], limiter RateLimiter, logger *zap.Logger) func(http.Handler) http.Handler
- func TraceMiddleware() common.Middleware
- func WithClientIP[T comparable, U any](ctx context.Context, ip string) context.Context
- func WithFlag[T comparable, U any](ctx context.Context, name string, value bool) context.Context
- func WithSRouterContext[T comparable, U any](ctx context.Context, rc *SRouterContext[T, U]) context.Context
- func WithTraceID[T comparable, U any](ctx context.Context, traceID string) context.Context
- func WithUser[T comparable, U any](ctx context.Context, user *U) context.Context
- func WithUserID[T comparable, U any](ctx context.Context, userID T) context.Context
- type APIKeyProvider
- type APIKeyUserAuthProvider
- type AuthProvider
- type BasicUserAuthProvider
- type BearerTokenProvider
- type BearerTokenUserAuthProvider
- type IPConfig
- type IPSourceType
- type Middleware
- func CORS(origins []string, methods []string, headers []string) Middleware
- func Chain(middlewares ...Middleware) Middleware
- func Logging(logger *zap.Logger) Middleware
- func MaxBodySize(maxSize int64) Middleware
- func Recovery(logger *zap.Logger) Middleware
- func Timeout(timeout time.Duration) Middleware
- type RateLimitConfig
- type RateLimitStrategy
- type RateLimiter
- type SRouterContext
- type UberRateLimiter
- type UserAuthProvider
Constants ¶
This section is empty.
Variables ¶
var ClientIPKey = clientIPKey{}
ClientIPKey is the key used to store the client IP in the request context
var TraceIDKey = traceIDKey{}
Functions ¶
func AddTraceIDToRequest ¶ added in v1.0.0
AddTraceIDToRequest adds a trace ID to the request context. This is useful for testing or for manually setting a trace ID.
func Authentication ¶
func Authentication[T comparable, U any]( authFunc func(*http.Request) (T, bool), ) common.Middleware
Authentication is a middleware that checks if a request is authenticated using a simple auth function. T is the User ID type (comparable), U is the User object type (any). It allows for custom authentication logic to be provided as a simple function.
func AuthenticationBool ¶ added in v1.0.0
func AuthenticationBool[T comparable, U any]( authFunc func(*http.Request) bool, flagName string, ) common.Middleware
AuthenticationBool is a middleware that checks if a request is authenticated using a simple auth function. It allows for custom authentication logic to be provided as a simple function that returns a boolean. It adds a boolean flag to the SRouterContext if authentication is successful. T is the User ID type (comparable), U is the User object type (any).
func AuthenticationWithProvider ¶
func AuthenticationWithProvider[T comparable, U any]( provider AuthProvider[T], logger *zap.Logger, ) common.Middleware
AuthenticationWithProvider is a middleware that checks if a request is authenticated using the provided auth provider. If authentication fails, it returns a 401 Unauthorized response. This middleware allows for flexible authentication mechanisms by accepting any AuthProvider implementation. T is the User ID type (comparable), U is the User object type (any).
This implementation uses the SRouterContext approach to store the authenticated user ID, which avoids deep nesting of context values by using a single wrapper structure. The type parameters allow for type-safe access to the user ID without type assertions.
func AuthenticationWithUser ¶ added in v1.0.0
func AuthenticationWithUser[T comparable, U any]( authFunc func(*http.Request) (*U, error), ) common.Middleware
AuthenticationWithUser is a middleware that uses a custom auth function that returns a user object and adds it to the SRouterContext if authentication is successful. T is the User ID type (comparable), U is the User object type (any).
func AuthenticationWithUserProvider ¶ added in v1.0.0
func AuthenticationWithUserProvider[T comparable, U any]( provider UserAuthProvider[U], logger *zap.Logger, ) common.Middleware
AuthenticationWithUserProvider is a middleware that uses an auth provider that returns a user object and adds it to the SRouterContext if authentication is successful. T is the User ID type (comparable), U is the User object type (any).
func ClientIP ¶ added in v1.0.0
ClientIP extracts the client IP from the request context First checks the SRouterContext, then falls back to the legacy context key
func ClientIPMiddleware ¶ added in v1.0.0
ClientIPMiddleware creates a middleware that extracts the client IP from the request and adds it to the request context. This is the standard middleware that works with both the legacy context key and the new SRouterContext.
This implementation uses the SRouterContext approach for storing the IP address, which avoids deep nesting of context values by using a single wrapper structure. For backward compatibility, it also stores the IP address using the legacy context key.
func ClientIPMiddlewareGeneric ¶ added in v1.0.9
func ClientIPMiddlewareGeneric[T comparable, U any](config *IPConfig) func(http.Handler) http.Handler
ClientIPMiddlewareGeneric creates a middleware that extracts the client IP from the request and adds it to the SRouterContext with specific type parameters. T is the User ID type (comparable), U is the User object type (any).
This implementation uses the SRouterContext approach with specific type parameters, making it useful when working with strongly typed middleware chains. It stores the IP address only in the SRouterContext wrapper, avoiding context nesting issues.
func CreateRateLimitMiddleware ¶ added in v1.0.2
func CreateRateLimitMiddleware[T comparable, U any]( bucketName string, limit int, window time.Duration, strategy RateLimitStrategy, userIDFromUser func(U) T, userIDToString func(T) string, logger *zap.Logger, ) func(http.Handler) http.Handler
CreateRateLimitMiddleware is a helper function to create a rate limit middleware with generic type parameters This function is useful when you want to create a rate limit middleware with a specific user ID type and user type The type parameter T represents the user ID type, which can be any comparable type. The type parameter U represents the user type, which can be any type.
func GetClientIP ¶ added in v1.0.9
GetClientIP retrieves a client IP from the router context
func GetClientIPFromRequest ¶ added in v1.0.9
GetClientIPFromRequest is a convenience function to get the client IP from a request
func GetFlagFromRequest ¶ added in v1.0.9
GetFlagFromRequest is a convenience function to get a flag from a request
func GetTraceID ¶ added in v1.0.0
GetTraceID extracts the trace ID from the request context. Returns an empty string if no trace ID is found.
func GetTraceIDFromContext ¶ added in v1.0.0
GetTraceIDFromContext extracts the trace ID from a context. It first tries to find the trace ID in the SRouterContext using the flags map, and falls back to the legacy context key approach for backward compatibility. Returns an empty string if no trace ID is found.
func GetUser ¶ added in v1.0.0
func GetUser[T comparable, U any](ctx context.Context) (*U, bool)
GetUser retrieves a user from the router context
func GetUserFromRequest ¶ added in v1.0.9
func GetUserFromRequest[T comparable, U any](r *http.Request) (*U, bool)
GetUserFromRequest is a convenience function to get the user from a request
func GetUserID ¶ added in v1.0.0
func GetUserID[T comparable, U any](ctx context.Context) (T, bool)
GetUserID retrieves a user ID from the router context
func GetUserIDFromRequest ¶ added in v1.0.9
func GetUserIDFromRequest[T comparable, U any](r *http.Request) (T, bool)
GetUserIDFromRequest is a convenience function to get the user ID from a request
func NewAPIKeyMiddleware ¶
func NewAPIKeyMiddleware[T comparable, U any]( validKeys map[string]T, header, query string, logger *zap.Logger, ) common.Middleware
NewAPIKeyMiddleware creates a middleware that uses API Key Authentication. T is the User ID type (comparable), U is the User object type (any).
func NewAPIKeyWithUserMiddleware ¶ added in v1.0.0
func NewAPIKeyWithUserMiddleware[T comparable, U any]( getUserFunc func(key string) (*U, error), header, query string, logger *zap.Logger, ) common.Middleware
NewAPIKeyWithUserMiddleware creates a middleware that uses API Key Authentication and returns a user object, adding it to the SRouterContext. T is the User ID type (comparable), U is the User object type (any).
func NewBearerTokenMiddleware ¶
func NewBearerTokenMiddleware[T comparable, U any]( validTokens map[string]T, logger *zap.Logger, ) common.Middleware
NewBearerTokenMiddleware creates a middleware that uses Bearer Token Authentication. T is the User ID type (comparable), U is the User object type (any).
func NewBearerTokenValidatorMiddleware ¶
func NewBearerTokenValidatorMiddleware[T comparable, U any]( validator func(string) (T, bool), logger *zap.Logger, ) common.Middleware
NewBearerTokenValidatorMiddleware creates a middleware that uses Bearer Token Authentication with a custom validator function. T is the User ID type (comparable), U is the User object type (any).
func NewBearerTokenWithUserMiddleware ¶ added in v1.0.0
func NewBearerTokenWithUserMiddleware[T comparable, U any]( getUserFunc func(token string) (*U, error), logger *zap.Logger, ) common.Middleware
NewBearerTokenWithUserMiddleware creates a middleware that uses Bearer Token Authentication and returns a user object, adding it to the SRouterContext. T is the User ID type (comparable), U is the User object type (any).
func RateLimit ¶ added in v1.0.0
func RateLimit[T comparable, U any](config *RateLimitConfig[T, U], limiter RateLimiter, logger *zap.Logger) func(http.Handler) http.Handler
RateLimit creates a middleware that enforces rate limits using generic type parameters The type parameter T represents the user ID type, which can be any comparable type. The type parameter U represents the user type, which can be any type.
func TraceMiddleware ¶ added in v1.0.0
func TraceMiddleware() common.Middleware
TraceMiddleware creates a middleware that generates a unique trace ID for each request and adds it to the request context. This allows for request tracing across logs.
func WithClientIP ¶ added in v1.0.9
WithClientIP adds a client IP to the context
func WithSRouterContext ¶ added in v1.0.9
func WithSRouterContext[T comparable, U any](ctx context.Context, rc *SRouterContext[T, U]) context.Context
WithSRouterContext adds or updates the router context in the request context
func WithTraceID ¶ added in v1.0.9
WithTraceID adds a trace ID to the SRouterContext in the provided context. If no SRouterContext exists, one will be created.
This function is part of the SRouterContext approach for storing values in the context, which avoids deep nesting of context values by using a single wrapper structure.
func WithUserID ¶ added in v1.0.9
WithUserID adds a user ID to the context
Types ¶
type APIKeyProvider ¶
type APIKeyProvider[T comparable] struct { ValidKeys map[string]T // key -> user ID Header string // header name (e.g., "X-API-Key") Query string // query parameter name (e.g., "api_key") }
APIKeyProvider provides API Key Authentication. It can validate API keys provided in a header or query parameter. The type parameter T represents the user ID type, which can be any comparable type.
func (*APIKeyProvider[T]) Authenticate ¶
func (p *APIKeyProvider[T]) Authenticate(r *http.Request) (T, bool)
Authenticate authenticates a request using API Key Authentication. It checks for the API key in either the specified header or query parameter and validates it against the stored valid keys. Returns the user ID if authentication is successful, the zero value of T and false otherwise.
type APIKeyUserAuthProvider ¶ added in v1.0.0
type APIKeyUserAuthProvider[T any] struct { GetUserFunc func(key string) (*T, error) Header string // header name (e.g., "X-API-Key") Query string // query parameter name (e.g., "api_key") }
APIKeyUserAuthProvider provides API Key Authentication with user object return.
func (*APIKeyUserAuthProvider[T]) AuthenticateUser ¶ added in v1.0.0
func (p *APIKeyUserAuthProvider[T]) AuthenticateUser(r *http.Request) (*T, error)
AuthenticateUser authenticates a request using API Key Authentication. It checks for the API key in either the specified header or query parameter and validates it using the GetUserFunc. Returns the user object if authentication is successful, nil and an error otherwise.
type AuthProvider ¶
type AuthProvider[T comparable] interface { // Authenticate authenticates a request and returns the user ID if authentication is successful. // It examines the request for authentication credentials (such as headers, cookies, or query parameters) // and validates them according to the provider's implementation. // Returns the user ID if the request is authenticated, the zero value of T otherwise. Authenticate(r *http.Request) (T, bool) }
AuthProvider defines an interface for authentication providers. Different authentication mechanisms can implement this interface to be used with the AuthenticationWithProvider middleware. The framework includes several implementations: BasicAuthProvider, BearerTokenProvider, and APIKeyProvider. The type parameter T represents the user ID type, which can be any comparable type.
type BasicUserAuthProvider ¶ added in v1.0.0
type BasicUserAuthProvider[T any] struct { GetUserFunc func(username, password string) (*T, error) }
BasicUserAuthProvider provides HTTP Basic Authentication with user object return.
func (*BasicUserAuthProvider[T]) AuthenticateUser ¶ added in v1.0.0
func (p *BasicUserAuthProvider[T]) AuthenticateUser(r *http.Request) (*T, error)
AuthenticateUser authenticates a request using HTTP Basic Authentication. It extracts the username and password from the Authorization header and validates them using the GetUserFunc. Returns the user object if authentication is successful, nil and an error otherwise.
type BearerTokenProvider ¶
type BearerTokenProvider[T comparable] struct { ValidTokens map[string]T // token -> user ID Validator func(token string) (T, bool) // optional token validator }
BearerTokenProvider provides Bearer Token Authentication. It can validate tokens against a predefined map or using a custom validator function. The type parameter T represents the user ID type, which can be any comparable type.
func (*BearerTokenProvider[T]) Authenticate ¶
func (p *BearerTokenProvider[T]) Authenticate(r *http.Request) (T, bool)
Authenticate authenticates a request using Bearer Token Authentication. It extracts the token from the Authorization header and validates it using either the validator function (if provided) or the ValidTokens map. Returns the user ID if authentication is successful, the zero value of T and false otherwise.
type BearerTokenUserAuthProvider ¶ added in v1.0.0
BearerTokenUserAuthProvider provides Bearer Token Authentication with user object return.
func (*BearerTokenUserAuthProvider[T]) AuthenticateUser ¶ added in v1.0.0
func (p *BearerTokenUserAuthProvider[T]) AuthenticateUser(r *http.Request) (*T, error)
AuthenticateUser authenticates a request using Bearer Token Authentication. It extracts the token from the Authorization header and validates it using the GetUserFunc. Returns the user object if authentication is successful, nil and an error otherwise.
type IPConfig ¶ added in v1.0.0
type IPConfig struct {
// Source specifies where to extract the client IP from
Source IPSourceType
// CustomHeader is the name of the custom header to use when Source is IPSourceCustomHeader
CustomHeader string
// TrustProxy determines whether to trust proxy headers like X-Forwarded-For
// If false, RemoteAddr will be used as a fallback for all sources
TrustProxy bool
}
IPConfig defines configuration for IP extraction
func DefaultIPConfig ¶ added in v1.0.0
func DefaultIPConfig() *IPConfig
DefaultIPConfig returns the default IP configuration
type IPSourceType ¶ added in v1.0.0
type IPSourceType string
IPSourceType defines the source for client IP addresses
const ( // IPSourceRemoteAddr uses the request's RemoteAddr field IPSourceRemoteAddr IPSourceType = "remote_addr" // IPSourceXForwardedFor uses the X-Forwarded-For header IPSourceXForwardedFor IPSourceType = "x_forwarded_for" // IPSourceXRealIP uses the X-Real-IP header IPSourceXRealIP IPSourceType = "x_real_ip" // IPSourceCustomHeader uses a custom header specified in the configuration IPSourceCustomHeader IPSourceType = "custom_header" )
type Middleware ¶
type Middleware = common.Middleware
Middleware is an alias for the common.Middleware type. It represents a function that wraps an http.Handler to provide additional functionality.
func CORS ¶
func CORS(origins []string, methods []string, headers []string) Middleware
CORS is a middleware that adds Cross-Origin Resource Sharing (CORS) headers to the response. It allows you to specify which origins, methods, and headers are allowed for cross-origin requests. This middleware also handles preflight OPTIONS requests automatically.
func Chain ¶
func Chain(middlewares ...Middleware) Middleware
Chain chains multiple middlewares together into a single middleware. The middlewares are applied in reverse order, so the first middleware in the list will be the outermost wrapper (the first to process the request and the last to process the response).
func Logging ¶
func Logging(logger *zap.Logger) Middleware
Logging is a middleware that logs HTTP requests and responses. It captures the request method, path, status code, and duration. The log level is determined by the status code and duration: - 500+ status codes are logged at Error level - 400-499 status codes are logged at Warn level - Requests taking longer than 1 second are logged at Warn level - All other requests are logged at Debug level
func MaxBodySize ¶
func MaxBodySize(maxSize int64) Middleware
MaxBodySize is a middleware that limits the size of the request body. It prevents clients from sending excessively large requests that could consume too much memory or cause denial of service.
func Recovery ¶
func Recovery(logger *zap.Logger) Middleware
Recovery is a middleware that recovers from panics in HTTP handlers. It logs the panic and stack trace using the provided logger and returns a 500 Internal Server Error response. This prevents the server from crashing when a panic occurs in a handler.
func Timeout ¶
func Timeout(timeout time.Duration) Middleware
Timeout is a middleware that sets a timeout for the request processing. If the handler takes longer than the specified timeout to respond, the middleware will cancel the request context and return a 408 Request Timeout response. This prevents long-running requests from blocking server resources indefinitely.
type RateLimitConfig ¶ added in v1.0.0
type RateLimitConfig[T comparable, U any] struct { // Unique identifier for this rate limit bucket // If multiple routes/subrouters share the same BucketName, they share the same rate limit BucketName string // Maximum number of requests allowed in the time window Limit int // Time window for the rate limit (e.g., 1 minute, 1 hour) Window time.Duration // Strategy for identifying clients (IP, User, Custom) // - "ip": Use client IP address // - "user": Use authenticated user ID // - "custom": Use a custom key extractor Strategy RateLimitStrategy // Function to extract user ID from user object (only used when Strategy is StrategyUser) // This allows for efficient user ID extraction without trying multiple types UserIDFromUser func(U) T // Function to convert user ID to string (only used when Strategy is StrategyUser) // This allows for efficient user ID conversion without type assertions UserIDToString func(T) string // Custom key extractor function (used when Strategy is "custom") // This allows for complex rate limiting scenarios KeyExtractor func(*http.Request) (string, error) // Response to send when rate limit is exceeded // If nil, a default 429 Too Many Requests response is sent ExceededHandler http.Handler }
RateLimitConfig defines configuration for rate limiting with generic type parameters The type parameter T represents the user ID type, which can be any comparable type. The type parameter U represents the user type, which can be any type.
type RateLimitStrategy ¶ added in v1.0.0
type RateLimitStrategy int
const ( // StrategyIP uses the client's IP address as the key for rate limiting StrategyIP RateLimitStrategy = iota // StrategyUser uses the authenticated user's ID as the key for rate limiting StrategyUser // StrategyCustom uses a custom key extractor function for rate limiting StrategyCustom )
type RateLimiter ¶ added in v1.0.0
type RateLimiter interface {
// Allow checks if a request is allowed based on the key and rate limit config
// Returns true if the request is allowed, false otherwise
// Also returns the number of remaining requests and time until reset
Allow(key string, limit int, window time.Duration) (bool, int, time.Duration)
}
RateLimiter defines the interface for rate limiting algorithms
type SRouterContext ¶ added in v1.0.9
type SRouterContext[T comparable, U any] struct { // User ID and User object storage UserID T User *U // Client IP address ClientIP string // Track which fields are set UserIDSet bool UserSet bool ClientIPSet bool // Additional flags Flags map[string]bool }
SRouterContext holds all values that SRouter adds to request contexts. It allows storing multiple types of values with only a single level of context nesting, solving the problem of deep context nesting which occurs when multiple middleware components each add their own values to the context.
T is the User ID type (comparable), U is the User object type (any). This structure centralizes all context values that middleware components need to store or access, providing a cleaner and more efficient approach than using multiple separate context keys.
func EnsureSRouterContext ¶ added in v1.0.9
func EnsureSRouterContext[T comparable, U any](ctx context.Context) (*SRouterContext[T, U], context.Context)
EnsureSRouterContext retrieves or creates a router context
func GetSRouterContext ¶ added in v1.0.9
func GetSRouterContext[T comparable, U any](ctx context.Context) (*SRouterContext[T, U], bool)
GetSRouterContext retrieves the router context from a request context
func NewSRouterContext ¶ added in v1.0.9
func NewSRouterContext[T comparable, U any]() *SRouterContext[T, U]
NewSRouterContext creates a new router context
type UberRateLimiter ¶ added in v1.0.0
type UberRateLimiter struct {
// contains filtered or unexported fields
}
UberRateLimiter implements RateLimiter using Uber's ratelimit library
func NewUberRateLimiter ¶ added in v1.0.0
func NewUberRateLimiter() *UberRateLimiter
NewUberRateLimiter creates a new rate limiter using Uber's ratelimit library
func (*UberRateLimiter) Allow ¶ added in v1.0.0
func (u *UberRateLimiter) Allow(key string, limit int, window time.Duration) (bool, int, time.Duration)
Allow checks if a request is allowed based on the key and rate limit config This implementation uses only the leaky bucket algorithm for simplicity and efficiency
type UserAuthProvider ¶ added in v1.0.0
type UserAuthProvider[T any] interface { // AuthenticateUser authenticates a request and returns the user object if authentication is successful. // It examines the request for authentication credentials (such as headers, cookies, or query parameters) // and validates them according to the provider's implementation. // Returns the user object if the request is authenticated, nil and an error otherwise. AuthenticateUser(r *http.Request) (*T, error) }
UserAuthProvider defines an interface for authentication providers that return a user object. Different authentication mechanisms can implement this interface to be used with the AuthenticationWithUserProvider middleware.