feat(server,proxy): integrate Request-ID into middleware chain and proxy forwarding

- Register requestid.New() as first middleware in buildMiddlewareChain
  (before AccessLog) so the ID is available for logging
- Add SetRequestIDHeader() in proxy/headers.go to propagate X-Request-ID
  to upstream via proxy forwarding
- Call SetRequestIDHeader in header_modifier.go after SetForwardedHeaders
- Import requestid package in middleware_builder and proxy/headers
This commit is contained in:
xfy 2026-06-11 23:41:30 +08:00
parent ebfa9cc7a8
commit 6c538a1a56
3 changed files with 27 additions and 0 deletions

View File

@ -50,6 +50,7 @@ func (p *Proxy) modifyRequestHeaders(ctx *fasthttp.RequestCtx, target *loadbalan
} }
SetForwardedHeaders(headers, fh, true, setHost, setProto) SetForwardedHeaders(headers, fh, true, setHost, setProto)
SetRequestIDHeader(headers, ctx)
// 从配置设置自定义请求头(支持变量展开) // 从配置设置自定义请求头(支持变量展开)
if p.config.Headers.SetRequest != nil { if p.config.Headers.SetRequest != nil {

View File

@ -22,6 +22,7 @@ import (
"strings" "strings"
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
"rua.plus/lolly/internal/middleware/requestid"
"rua.plus/lolly/internal/netutil" "rua.plus/lolly/internal/netutil"
) )
@ -107,6 +108,13 @@ func SetForwardedHeaders(headers *fasthttp.RequestHeader, fh ForwardedHeaders, a
} }
} }
// SetRequestIDHeader propagates X-Request-ID from the request context to upstream headers.
func SetRequestIDHeader(headers *fasthttp.RequestHeader, ctx *fasthttp.RequestCtx) {
if id := requestid.GetRequestID(ctx); id != "" {
headers.Set("X-Request-ID", id)
}
}
// WriteForwardedHeaders 将 X-Forwarded 头写入到 strings.Builder。 // WriteForwardedHeaders 将 X-Forwarded 头写入到 strings.Builder。
// 用于 WebSocket 升级请求构建。 // 用于 WebSocket 升级请求构建。
// //

View File

@ -14,7 +14,9 @@ import (
"rua.plus/lolly/internal/middleware" "rua.plus/lolly/internal/middleware"
"rua.plus/lolly/internal/middleware/bodylimit" "rua.plus/lolly/internal/middleware/bodylimit"
"rua.plus/lolly/internal/middleware/compression" "rua.plus/lolly/internal/middleware/compression"
"rua.plus/lolly/internal/middleware/cors"
"rua.plus/lolly/internal/middleware/errorintercept" "rua.plus/lolly/internal/middleware/errorintercept"
"rua.plus/lolly/internal/middleware/requestid"
"rua.plus/lolly/internal/middleware/rewrite" "rua.plus/lolly/internal/middleware/rewrite"
"rua.plus/lolly/internal/middleware/security" "rua.plus/lolly/internal/middleware/security"
) )
@ -38,6 +40,9 @@ import (
func (s *Server) buildMiddlewareChain(serverCfg *config.ServerConfig) (*middleware.Chain, error) { func (s *Server) buildMiddlewareChain(serverCfg *config.ServerConfig) (*middleware.Chain, error) {
var middlewares []middleware.Middleware var middlewares []middleware.Middleware
// 0. Request-ID (最先执行,确保后续中间件和日志可使用 $request_id)
middlewares = append(middlewares, requestid.New())
// 1. AccessLog (已集成) // 1. AccessLog (已集成)
middlewares = append(middlewares, s.accessLogMiddleware) middlewares = append(middlewares, s.accessLogMiddleware)
@ -142,6 +147,19 @@ func (s *Server) buildMiddlewareChain(serverCfg *config.ServerConfig) (*middlewa
middlewares = append(middlewares, headers) middlewares = append(middlewares, headers)
} }
// 7.5 CORS (跨域资源共享)
if serverCfg.Security.CORS.Enabled {
middlewares = append(middlewares, cors.New(&cors.CORSConfig{
Enabled: serverCfg.Security.CORS.Enabled,
AllowedOrigins: serverCfg.Security.CORS.AllowedOrigins,
AllowedMethods: serverCfg.Security.CORS.AllowedMethods,
AllowedHeaders: serverCfg.Security.CORS.AllowedHeaders,
ExposeHeaders: serverCfg.Security.CORS.ExposeHeaders,
AllowCredentials: serverCfg.Security.CORS.AllowCredentials,
MaxAge: serverCfg.Security.CORS.MaxAge,
}))
}
// 8. ErrorIntercept (错误页面拦截) // 8. ErrorIntercept (错误页面拦截)
// 如果配置了错误页面,添加错误拦截中间件 // 如果配置了错误页面,添加错误拦截中间件
if s.errorPageManager != nil && s.errorPageManager.IsConfigured() { if s.errorPageManager != nil && s.errorPageManager.IsConfigured() {