-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: use same port for grpc-web and api server #14652
Changes from all commits
55c37fe
f83fc9a
9e4d882
d23d932
bfee71a
20f9881
4fc21e6
abd3683
a9e1cd2
b60d921
2ef1ae1
18b326a
788de29
e0b7ce9
53adc5e
9664ea0
452c002
4fd5cde
30c79a4
94a7e13
d5d504b
87eb48a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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() | ||
|
||
// 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want this to be hardcoded? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have kept the same behavior as before. The API constructor will look a bit weird if we add grpcweb options. |
||
}), | ||
) | ||
} | ||
|
||
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(h), s.logger, tmCfg) | ||
return tmrpcserver.Serve(s.listener, allowAllCORS(s.Router), s.logger, tmCfg) | ||
} | ||
|
||
s.logger.Info("starting API server...") | ||
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 | ||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated but see #14655 (comment)