middleware

package
v0.0.0-...-8c930d8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 11, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Overview

Package middleware is the HTTP middleware a project mounts: Register adds middleware to every API route, RegisterAuth to the routes of the authenticated group, and the constructors here build the middleware the framework ships for either. IAMSession and Authz are the middleware of the iam and authz modules, whose source files gg module copy copies into a project.

The chain the framework mounts ahead of every route itself, and the machinery that mounts registered middleware onto the routes, are the framework's own.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Authz

func Authz() gin.HandlerFunc

Authz authorizes requests using RBAC, through rbac.Enforce, the one decision path the gRPC interceptor of the module takes as well: the subject is read off the gin context, the object and action are the request path and method, and a refusal is answered in the API envelope with the status and message the service error carries. Authz must be called before config.Init so config.Init can read AUTH_RBAC_ENABLED from the environment and enable RBAC initialization.

Authz must run after an authentication middleware that populates requestctx.KeyUserID. When using built-in IAM sessions, register IAMSession before Authz; otherwise a valid session cookie is rejected as "permission denied" because Authz cannot find the authenticated subject yet.

The request tenant has exactly one source: requestctx.KeyTenantID, read as it stands when this middleware runs, defaulted to tenant.Default when empty. Whatever trusted middleware wrote it last decides. IAMSession writes the session's tenant; a deployment whose tenant arrives another way — a header a trusted gateway injects, a subdomain — installs its own middleware after IAMSession and before Authz and overwrites it. The value must only ever be written from something the deployment vouches for, never from client input passed through as it stands; rbac.Enforce says why.

func CircuitBreaker

func CircuitBreaker() gin.HandlerFunc

CircuitBreaker returns a middleware that runs each request through the circuit breaker configured under server.circuit_breaker, which the framework builds as it bootstraps. A request counts as failed when its handler writes a response with a 5xx status, or writes nothing and records an error. Once enough requests have been counted and the configured share of them failed, the breaker opens: requests are refused with 503 until its timeout has passed and trial requests succeed again. A request the breaker lets through keeps the answer its handlers gave, failed or not. Requests to streaming routes bypass the breaker.

func Delay

func Delay(duration time.Duration) gin.HandlerFunc

Delay returns a middleware that adds a fixed delay before processing the request. This is primarily used for testing purposes to simulate network latency or slow responses.

Parameters:

  • duration: The delay duration to add before processing the request

Returns:

  • A gin.HandlerFunc that adds the specified delay

Example, from an init function (see Register):

// Add a 100ms delay to every API route
middleware.Register(middleware.Delay(100 * time.Millisecond))

// Add a 1 second delay
middleware.Register(middleware.Delay(1 * time.Second))

func DelayRandom

func DelayRandom(minDuration, maxDuration time.Duration) gin.HandlerFunc

DelayRandom returns a middleware that adds a random delay within the specified range before processing the request. This is primarily used for testing purposes to simulate variable network latency or slow responses.

Parameters:

  • minDuration: The minimum delay duration
  • maxDuration: The maximum delay duration

Returns:

  • A gin.HandlerFunc that adds a random delay between minDuration and maxDuration

Example, from an init function (see Register):

// Add a random delay between 0 and 3000ms
middleware.Register(middleware.DelayRandom(0, 3000*time.Millisecond))

// Add a random delay between 100ms and 500ms
short, long := 100*time.Millisecond, 500*time.Millisecond
middleware.Register(middleware.DelayRandom(short, long))

func DelayWithConfig

func DelayWithConfig(delayFunc func(*gin.Context) time.Duration) gin.HandlerFunc

DelayWithConfig returns a middleware that adds a configurable delay based on request properties. This allows for more flexible testing scenarios, such as different delays for different paths or methods.

Parameters:

  • delayFunc: A function that determines the delay duration based on the request context

Returns:

  • A gin.HandlerFunc that adds the delay determined by delayFunc

Example, from an init function (see Register):

// Add a delay based on the path
byPath := func(c *gin.Context) time.Duration {
	if strings.HasPrefix(c.Request.URL.Path, "/api/slow") {
		return 2 * time.Second
	}
	return 100 * time.Millisecond
}
middleware.Register(middleware.DelayWithConfig(byPath))

func IAMSession

func IAMSession() gin.HandlerFunc

IAMSession authenticates a request from the IAM session its cookie names, through serviceiamsession.Authenticate, the one path the gRPC interceptor of the module takes as well: the session is admitted or refused the same way over both listeners, and what differs here is only where the session id comes from, the cookie, and how a refusal is answered, in the API envelope with the status and message the service error carries. Building the middleware declares the cookie to the OpenAPI document as the cookieAuth scheme.

func IPBlacklist

func IPBlacklist(blacklist []string) gin.HandlerFunc

IPBlacklist returns a middleware that blocks requests from IP addresses in the blacklist.

Parameters:

  • blacklist: List of blocked IP addresses or CIDR ranges (e.g., "192.168.1.100", "10.0.0.0/8")

Returns:

  • A gin.HandlerFunc that enforces IP blacklist

Example, from an init function (see Register):

// Block specific IPs
blocked := []string{"192.168.1.100", "10.0.0.0/8"}
middleware.Register(middleware.IPBlacklist(blocked))

// Block known malicious IPs
known := []string{"1.2.3.4", "5.6.7.8"}
middleware.Register(middleware.IPBlacklist(known))

func IPFilter

func IPFilter(config *IPFilterConfig) gin.HandlerFunc

IPFilter returns a middleware that filters requests based on IP whitelist and blacklist. Blacklist takes precedence over whitelist.

The address filtered on is the one the engine reports: the peer of the connection, or the address a trusted proxy forwarded. Which proxies count is server.trusted_proxies, applied to the engine at startup — behind a proxy that is not named there, every request filters as the proxy's own address.

Entries match the way net.IP compares addresses: an IPv4-mapped IPv6 address, such as ::ffff:10.1.2.3, matches the IPv4 entries, while every other IPv6 address, the loopback ::1 among them, matches IPv6 entries alone, so letting local callers in over both families takes 127.0.0.1 and ::1.

Parameters:

  • config: Configuration for IP filtering

Returns:

  • A gin.HandlerFunc that enforces IP filtering rules

Example, from an init function (see Register):

// Use both whitelist and blacklist
middleware.Register(middleware.IPFilter(&middleware.IPFilterConfig{
	Whitelist: []string{"192.168.0.0/16"},
	Blacklist: []string{"192.168.1.100"},
}))

func IPWhitelist

func IPWhitelist(whitelist []string) gin.HandlerFunc

IPWhitelist returns a middleware that only allows requests from IP addresses in the whitelist.

Parameters:

  • whitelist: List of allowed IP addresses or CIDR ranges (e.g., "192.168.1.1", "10.0.0.0/8")

Returns:

  • A gin.HandlerFunc that enforces IP whitelist

Example, from an init function (see Register):

// Allow only specific IPs
allowed := []string{"192.168.1.1", "10.0.0.0/8"}
middleware.Register(middleware.IPWhitelist(allowed))

// Allow only localhost
middleware.Register(middleware.IPWhitelist([]string{"127.0.0.1", "::1"}))

func JwtAuth

func JwtAuth() gin.HandlerFunc

JwtAuth authenticates a request from the bearer token in its Authorization header.

The token answers for itself: it is verified from its signature and claims, with nothing read from storage. Revoking one before it expires therefore is not something this middleware can do, which is the trade a stateless token makes and the reason IAM's own sessions are not built on it. Building the middleware declares the token to the OpenAPI document as the bearerAuth scheme.

func Register

func Register(middlewares ...gin.HandlerFunc)

Register adds middlewares that run on every API route. Call it from an init function: gin fixes the chain of a route as the route registers, so a call once a route is registered, or once the server runs, panics rather than leave the routes registered before it without the middleware. Registered that way, they run in registration order, and on the routes of router.Auth ahead of every middleware RegisterAuth adds. When tracing is enabled, each middleware runs in a span of its own.

func RegisterAuth

func RegisterAuth(middlewares ...gin.HandlerFunc)

RegisterAuth adds middlewares that run only on the routes registered on router.Auth: the place for authentication and authorization. Call it from an init function: like Register, a call once a route is registered, or once the server runs, panics rather than leave the routes registered before it without the middleware. Registered that way, they run in registration order, after every middleware Register adds. When tracing is enabled, each middleware runs in a span of its own.

func RequestSizeLimit

func RequestSizeLimit(maxSize int64) gin.HandlerFunc

RequestSizeLimit returns a middleware that limits the size of incoming request bodies. This helps prevent DoS attacks by limiting the amount of data that can be sent in a single request.

Parameters:

  • maxSize: Maximum allowed size in bytes for the request body

Returns:

  • A gin.HandlerFunc that enforces the request size limit

Example, from an init function (see Register):

// Limit request body to 10MB
middleware.Register(middleware.RequestSizeLimit(10 * 1024 * 1024))

// Limit request body to 1MB
middleware.Register(middleware.RequestSizeLimit(1024 * 1024))

func SecurityHeaders

func SecurityHeaders(config *SecurityHeadersConfig) gin.HandlerFunc

SecurityHeaders returns a middleware that sets security-related HTTP headers. This helps protect against various web vulnerabilities.

Parameters:

  • config: Configuration for security headers. If nil, default secure headers will be used.

Returns:

  • A gin.HandlerFunc that sets security headers

Example, from an init function (see Register):

// Use default secure headers
middleware.Register(middleware.SecurityHeaders(nil))

// Use custom configuration
headers := &middleware.SecurityHeadersConfig{
	XFrameOptions:           "DENY",
	XContentTypeOptions:     "nosniff",
	XXSSProtection:          "1; mode=block",
	StrictTransportSecurity: "max-age=31536000; includeSubDomains",
	ContentSecurityPolicy:   "default-src 'self'",
	ReferrerPolicy:          "strict-origin-when-cross-origin",
}
middleware.Register(middleware.SecurityHeaders(headers))

func Timeout

func Timeout(timeout time.Duration) gin.HandlerFunc

Timeout returns a middleware that puts a deadline on the request context and answers 504 when the rest of the chain has not started its response by then.

The deadline is cooperative. The chain runs to completion on the request goroutine, and code that honors the request context (database, cache and outbound calls) stops once the deadline passes. A response the chain starts writing before the deadline goes out as written; one it would only start after the deadline is dropped, together with the headers the chain set, and the 504 envelope is written in its place once the chain returns, so a handler that ignores the context delays the 504 until it returns. The chain never runs on a goroutine of its own: gin takes the context back for the next request as soon as this one returns, and a chain still running on it would read and write another request.

Streaming routes are left alone, since a stream legitimately outlives any request timeout.

Example, from an init function (see Register):

// Set a 30 second timeout on every API route
middleware.Register(middleware.Timeout(30 * time.Second))

// Set a 5 second timeout
middleware.Register(middleware.Timeout(5 * time.Second))

Types

type IPFilterConfig

type IPFilterConfig struct {
	// Whitelist contains allowed IP addresses or CIDR ranges
	// If non-empty, only IPs in this list will be allowed
	Whitelist []string

	// Blacklist contains blocked IP addresses or CIDR ranges
	// IPs in this list will always be blocked
	Blacklist []string
}

IPFilterConfig holds configuration for IP filtering middleware

type SecurityHeadersConfig

type SecurityHeadersConfig struct {
	// XFrameOptions controls the X-Frame-Options header
	// Options: "DENY", "SAMEORIGIN", or empty string to disable
	XFrameOptions string

	// XContentTypeOptions controls the X-Content-Type-Options header
	// Set to "nosniff" to enable, or empty string to disable
	XContentTypeOptions string

	// XXSSProtection controls the X-XSS-Protection header
	// Set to "1; mode=block" to enable, or empty string to disable
	XXSSProtection string

	// StrictTransportSecurity controls the Strict-Transport-Security header
	// Set to a value like "max-age=31536000; includeSubDomains" to enable, or empty string to disable
	StrictTransportSecurity string

	// ContentSecurityPolicy controls the Content-Security-Policy header
	// Set to a CSP policy string to enable, or empty string to disable
	ContentSecurityPolicy string

	// ReferrerPolicy controls the Referrer-Policy header
	// Options: "no-referrer", "no-referrer-when-downgrade", "origin", etc., or empty string to disable
	ReferrerPolicy string

	// PermissionsPolicy controls the Permissions-Policy header
	// Set to a permissions policy string to enable, or empty string to disable
	PermissionsPolicy string
}

SecurityHeadersConfig holds configuration for security headers middleware

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址