feat(gateway): add custom middleware support with onion model (#5035)

This commit is contained in:
Yi Deng
2025-07-31 21:33:36 +08:00
committed by GitHub
parent 82a937d517
commit b0b31f3993
2 changed files with 72 additions and 2 deletions

View File

@@ -27,12 +27,16 @@ import (
const defaultHttpScheme = "http"
type (
// MiddlewareFunc defines the function signature for middleware.
MiddlewareFunc func(next http.HandlerFunc) http.HandlerFunc
// Server is a gateway server.
Server struct {
*rest.Server
upstreams []Upstream
conns []zrpc.Client
processHeader func(http.Header) []string
middlewares []MiddlewareFunc
dialer func(conf zrpc.RpcClientConf) zrpc.Client
}
@@ -105,7 +109,7 @@ func (s *Server) build() error {
func (s *Server) buildGrpcHandler(source grpcurl.DescriptorSource, resolver jsonpb.AnyResolver,
cli zrpc.Client, rpcPath string) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
handler := func(w http.ResponseWriter, r *http.Request) {
parser, err := internal.NewRequestParser(r, resolver)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
@@ -124,6 +128,8 @@ func (s *Server) buildGrpcHandler(source grpcurl.DescriptorSource, resolver json
httpx.ErrorCtx(r.Context(), w, st.Err())
}
}
return s.buildChainHandler(handler)
}
func (s *Server) buildGrpcRoute(up Upstream, writer mr.Writer[rest.Route], cancel func(error)) {
@@ -177,7 +183,7 @@ func (s *Server) buildGrpcRoute(up Upstream, writer mr.Writer[rest.Route], cance
}
func (s *Server) buildHttpHandler(target *HttpClientConf) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
handler := func(w http.ResponseWriter, r *http.Request) {
w.Header().Set(httpx.ContentType, httpx.JsonContentType)
req, err := buildRequestWithNewTarget(r, target)
if err != nil {
@@ -213,6 +219,8 @@ func (s *Server) buildHttpHandler(target *HttpClientConf) http.HandlerFunc {
logc.Error(r.Context(), err)
}
}
return s.buildChainHandler(handler)
}
func (s *Server) buildHttpRoute(up Upstream, writer mr.Writer[rest.Route]) {
@@ -263,6 +271,21 @@ func WithHeaderProcessor(processHeader func(http.Header) []string) func(*Server)
}
}
// WithMiddleware adds one or more middleware functions to process HTTP requests.
// Multiple middlewares will be executed in the order they were passed (like an onion model).
func WithMiddleware(middlewares ...MiddlewareFunc) func(*Server) {
return func(s *Server) {
s.middlewares = append(s.middlewares, middlewares...)
}
}
func (s *Server) buildChainHandler(handler http.HandlerFunc) http.HandlerFunc {
for i := len(s.middlewares) - 1; i >= 0; i-- {
handler = s.middlewares[i](handler)
}
return handler
}
func buildRequestWithNewTarget(r *http.Request, target *HttpClientConf) (*http.Request, error) {
u := *r.URL
u.Host = target.Target