feat: use same port for grpc-web and api server (#14652)
This commit is contained in:
+36
-12
@@ -12,8 +12,10 @@ import (
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/improbable-eng/grpc-web/go/grpcweb"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmrpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
@@ -28,6 +30,8 @@ type Server struct {
|
||||
GRPCGatewayRouter *runtime.ServeMux
|
||||
ClientCtx client.Context
|
||||
|
||||
GRPCSrv *grpc.Server
|
||||
|
||||
logger log.Logger
|
||||
metrics *telemetry.Metrics
|
||||
// Start() is blocking and generally called from a separate goroutine.
|
||||
@@ -52,7 +56,7 @@ func CustomGRPCHeaderMatcher(key string) (string, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func New(clientCtx client.Context, logger log.Logger) *Server {
|
||||
func New(clientCtx client.Context, logger log.Logger, grpcSrv *grpc.Server) *Server {
|
||||
// The default JSON marshaller used by the gRPC-Gateway is unable to marshal non-nullable non-scalar fields.
|
||||
// Using the gogo/gateway package with the gRPC-Gateway WithMarshaler option fixes the scalar field marshalling issue.
|
||||
marshalerOption := &gateway.JSONPb{
|
||||
@@ -63,9 +67,9 @@ func New(clientCtx client.Context, logger log.Logger) *Server {
|
||||
}
|
||||
|
||||
return &Server{
|
||||
logger: logger,
|
||||
Router: mux.NewRouter(),
|
||||
ClientCtx: clientCtx,
|
||||
logger: logger,
|
||||
GRPCGatewayRouter: runtime.NewServeMux(
|
||||
// Custom marshaler option is required for gogo proto
|
||||
runtime.WithMarshalerOption(runtime.MIMEWildcard, marshalerOption),
|
||||
@@ -78,6 +82,7 @@ func New(clientCtx client.Context, logger log.Logger) *Server {
|
||||
// GRPC metadata
|
||||
runtime.WithIncomingHeaderMatcher(CustomGRPCHeaderMatcher),
|
||||
),
|
||||
GRPCSrv: grpcSrv,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,18 +105,41 @@ func (s *Server) Start(cfg config.Config) error {
|
||||
return err
|
||||
}
|
||||
|
||||
s.registerGRPCGatewayRoutes()
|
||||
s.listener = listener
|
||||
var h http.Handler = s.Router
|
||||
|
||||
s.mtx.Unlock()
|
||||
|
||||
if cfg.API.EnableUnsafeCORS {
|
||||
allowAllCORS := handlers.CORS(handlers.AllowedHeaders([]string{"Content-Type"}))
|
||||
return tmrpcserver.Serve(s.listener, allowAllCORS(h), s.logger, tmCfg)
|
||||
// configure grpc-web server
|
||||
if cfg.GRPC.Enable && cfg.GRPCWeb.Enable {
|
||||
var options []grpcweb.Option
|
||||
if cfg.API.EnableUnsafeCORS {
|
||||
options = append(options,
|
||||
grpcweb.WithOriginFunc(func(origin string) bool {
|
||||
return true
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
wrappedGrpc := grpcweb.WrapServer(s.GRPCSrv, options...)
|
||||
s.Router.PathPrefix("/").Handler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
if wrappedGrpc.IsGrpcWebRequest(req) {
|
||||
wrappedGrpc.ServeHTTP(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
// Fall back to grpc gateway server.
|
||||
s.GRPCGatewayRouter.ServeHTTP(w, req)
|
||||
}))
|
||||
}
|
||||
|
||||
// register grpc-gateway routes (after grpc-web server as the first match is used)
|
||||
s.Router.PathPrefix("/").Handler(s.GRPCGatewayRouter)
|
||||
|
||||
s.logger.Info("starting API server...")
|
||||
if cfg.API.EnableUnsafeCORS {
|
||||
allowAllCORS := handlers.CORS(handlers.AllowedHeaders([]string{"Content-Type"}))
|
||||
return tmrpcserver.Serve(s.listener, allowAllCORS(s.Router), s.logger, tmCfg)
|
||||
}
|
||||
|
||||
return tmrpcserver.Serve(s.listener, s.Router, s.logger, tmCfg)
|
||||
}
|
||||
|
||||
@@ -122,10 +150,6 @@ func (s *Server) Close() error {
|
||||
return s.listener.Close()
|
||||
}
|
||||
|
||||
func (s *Server) registerGRPCGatewayRoutes() {
|
||||
s.Router.PathPrefix("/").Handler(s.GRPCGatewayRouter)
|
||||
}
|
||||
|
||||
func (s *Server) SetTelemetry(m *telemetry.Metrics) {
|
||||
s.mtx.Lock()
|
||||
s.metrics = m
|
||||
|
||||
Reference in New Issue
Block a user