Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

middleware_en.md

maoxiaoyue edited this page May 14, 2026 · 1 revision

Middleware Package (pkg/middleware)

The middleware package provides a series of plug-and-play middleware tailored for HypGo's context.Context. Through the built-in middleware chain and group management features, you can easily add cross-origin request handling, logging, rate limiting, caching, and more to your routes.

Built-in Middleware List

  1. Logger: High-performance request logging, supports recording duration and response size, can exclude specific paths.
  2. Recovery: Automatically catches panics to prevent server crashes, with customizable panic handling logic and HTTP status responses.
  3. CORS: Cross-Origin Resource Sharing handling, supports fine-grained configuration and Preflight request caching.
  4. Security: HTTP security header configuration (HSTS, X-Frame-Options, CSP), all header values pre-computed at initialization with zero GC pressure.
  5. RateLimiter: Simple Token Bucket-based rate limiting, configurable by IP or custom rules.
  6. Timeout: Maximum time limit for HTTP request processing; forces interruption and responds with timeout message when exceeded.
  7. Cache: Caches frequently accessed APIs in memory, with customizable TTL, key generation algorithm, and validation logic.

Core Design Philosophy

HypGo uses Chain and Group patterns for middleware management. You can combine one or more middleware like building blocks, then attach them to the final Handler using Then.

Loading a Single Built-in Middleware

Using Logger as an example, mount with default configuration:

package main
import (
	"github.com/maoxiaoyue/hypgo/pkg/middleware"
	"github.com/maoxiaoyue/hypgo/pkg/router"
	"github.com/maoxiaoyue/hypgo/pkg/context"
)
func main() {
	r := router.New()
	
	// Add Logger middleware with default settings
	r.Use(middleware.Logger(middleware.LoggerConfig{}))
	
	r.GET("/ping", func(c *context.Context) {
		c.String(200, "pong")
	})
}

Chaining Multiple Middleware

You can also bundle middleware into a group via middleware.Chain before applying:

// Create a basic security call chain
apiChain := middleware.NewChain(
 middleware.Recovery(middleware.RecoveryConfig{}), // Prevent crashes
 middleware.Logger(middleware.LoggerConfig{}), // Logging
 middleware.CORS(middleware.CORSConfig{
 AllowOrigins: []string{"https://example.com"},
 }),
)
// Combine with custom function
r.GET("/api/data", apiChain.Then(func(c *context.Context) {
 c.JSON(200, map[string]string{"msg": "secure data"})
}))

Creating Prefix Middleware Groups

If specific route prefixes (e.g., /admin) need specific middleware logic:

// Declare a group starting with `/admin` and attach RateLimiter
adminGroup := middleware.NewGroup("/admin", middleware.RateLimiter(middleware.RateLimiterConfig{
 Rate: 10, // 10 requests per second
 Burst: 20, // Maximum burst capacity of 20
}))
// Apply the group's middleware to specific routes
r.GET("/admin/dashboard", adminGroup.Handle(func(c *context.Context) {
 c.String(200, "Admin View")
}))

Custom Middleware

You can write your own middleware following the func(*hypcontext.Context) type signature. Just make sure to call c.Next() at the end to proceed through the execution chain:

func MyCustomMiddleware() hypcontext.HandlerFunc {
	return func(c *hypcontext.Context) {
		// 1. Logic before request processing
		c.Set("my_key", "my_value")
		// 2. Hand control to the next middleware or Handler
		c.Next()
		// 3. Logic after processing, before response
		status := c.Writer.Status()
		log.Printf("Response Status: %d", status)
	}
}

Additional Middleware

BodyLimit -- Request Size Limiting

Prevents large payload DoS attacks:

r.Use(middleware.BodyLimit(middleware.BodyLimitConfig{
 MaxBytes: 5 << 20, // 5MB
 ErrorMsg: "Payload too large",
}))

MethodOverride -- HTTP Method Override

Supports clients that don't support PUT/DELETE (e.g., HTML forms):

r.Use(middleware.MethodOverride())
// POST /users?_method=DELETE -> becomes DELETE /users
// POST /users (X-HTTP-Method-Override: PUT) -> becomes PUT /users

Security Fix Log

Issue Fix
RateLimiter sync.Map memory leak Added periodic cleanup (clears keys unseen for 10 minutes every 5 minutes)
JWT middleware validation was a stub Changed to require Validator function, rejects all without one (secure default)
Brotli compression sent fake header Removed fake Content-Encoding: br, keeping only gzip
CircuitBreaker race condition Added sync.Mutex to protect state reads/writes
CSRF/RequestID used insecure fastrand Changed to crypto/rand

GC Optimization: Security Header Pre-computation

The Security middleware pre-computes all header values (XSS, nosniff, HSTS, CSP) as immutable strings at initialization, captured by closures. During request processing, strings are set directly without fmt.Sprintf or string concatenation:

// One-time computation at initialization
sec := middleware.Security(middleware.SecurityConfig{
 HSTSMaxAge: 31536000,
 HSTSIncludeSubdomains: true,
})
// -> Pre-computes hstsValue = "max-age=31536000; includeSubDomains"
// -> Each request only executes c.Header("Strict-Transport-Security", hstsValue)
// -> Zero allocation, zero GC pressure

HypGo

繁體中文 | English


中文文件

設計文件

套件

AI 協作工具鏈

CLI 命令


English Docs

Design Docs

Packages

AI Collaboration Toolchain

CLI Commands

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /