Matches the startup process of websocket server to that of http server for consistency (#8)

This commit is contained in:
rene 2020-03-30 13:58:34 +02:00 committed by GitHub
parent a08ccfe8e6
commit aab171f8c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 52 deletions

View file

@ -890,13 +890,12 @@ func retesteth(ctx *cli.Context) error {
srv := rpc.NewServer() srv := rpc.NewServer()
err := node.RegisterApisFromWhitelist(rpcAPI, []string{"test", "eth", "debug", "web3"}, srv) err := node.RegisterApisFromWhitelist(rpcAPI, []string{"test", "eth", "debug", "web3"}, srv, false)
if err != nil { if err != nil {
utils.Fatalf("Could not register RPC apis: %w", err) // TODO should this be a fatal error? utils.Fatalf("Could not register RPC apis: %w", err) // TODO should this be a fatal error?
} }
handler := node.NewHTTPHandlerStack(srv, cors, vhosts) handler := node.NewHTTPHandlerStack(srv, cors, vhosts)
handler = node.NewWebsocketUpgradeHandler(handler, nil)
// start http server // start http server
var RetestethHTTPTimeouts = rpc.HTTPTimeouts{ var RetestethHTTPTimeouts = rpc.HTTPTimeouts{

View file

@ -86,7 +86,7 @@ func (s *Service) Start(server *p2p.Server) error {
return nil return nil
} }
func registerTimeouts(timeouts *rpc.HTTPTimeouts){ func registerTimeouts(timeouts *rpc.HTTPTimeouts) {
if timeouts.ReadTimeout < time.Second { if timeouts.ReadTimeout < time.Second {
log.Warn("Sanitizing invalid HTTP read timeout", "provided", timeouts.ReadTimeout, "updated", rpc.DefaultHTTPTimeouts.ReadTimeout) log.Warn("Sanitizing invalid HTTP read timeout", "provided", timeouts.ReadTimeout, "updated", rpc.DefaultHTTPTimeouts.ReadTimeout)
timeouts.ReadTimeout = rpc.DefaultHTTPTimeouts.ReadTimeout timeouts.ReadTimeout = rpc.DefaultHTTPTimeouts.ReadTimeout

View file

@ -371,7 +371,7 @@ func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors
srv := rpc.NewServer() srv := rpc.NewServer()
err := RegisterApisFromWhitelist(apis, modules, srv) err := RegisterApisFromWhitelist(apis, modules, srv, false)
if err != nil { if err != nil {
return err // TODO this should return upon failure, right? return err // TODO this should return upon failure, right?
} }
@ -420,7 +420,13 @@ func (n *Node) startWS(endpoint string, apis []rpc.API, modules []string, wsOrig
if endpoint == "" { if endpoint == "" {
return nil return nil
} }
listener, handler, err := rpc.StartWSEndpoint(endpoint, apis, modules, wsOrigins, exposeAll)
srv := rpc.NewServer()
handler := srv.WebsocketHandler(wsOrigins)
err := RegisterApisFromWhitelist(apis, modules, srv, exposeAll)
listener, err := rpc.StartWSEndpoint(endpoint, handler)
if err != nil { if err != nil {
return err return err
} }
@ -428,7 +434,7 @@ func (n *Node) startWS(endpoint string, apis []rpc.API, modules []string, wsOrig
// All listeners booted successfully // All listeners booted successfully
n.wsEndpoint = endpoint n.wsEndpoint = endpoint
n.wsListener = listener n.wsListener = listener
n.wsHandler = handler n.wsHandler = srv
return nil return nil
} }
@ -688,7 +694,7 @@ func (n *Node) apis() []rpc.API {
// RegisterApisFromWhitelist checks the given modules' availability, generates a whitelist based on the allowed modules, // RegisterApisFromWhitelist checks the given modules' availability, generates a whitelist based on the allowed modules,
// and then registers all of the APIs exposed by the services. // and then registers all of the APIs exposed by the services.
func RegisterApisFromWhitelist(apis []rpc.API, modules []string, srv *rpc.Server) error { func RegisterApisFromWhitelist(apis []rpc.API, modules []string, srv *rpc.Server, exposeAll bool) error {
if bad, available := rpc.CheckModuleAvailability(modules, apis); len(bad) > 0 { if bad, available := rpc.CheckModuleAvailability(modules, apis); len(bad) > 0 {
log.Error("Unavailable modules in HTTP API list", "unavailable", bad, "available", available) log.Error("Unavailable modules in HTTP API list", "unavailable", bad, "available", available)
} }
@ -699,7 +705,7 @@ func RegisterApisFromWhitelist(apis []rpc.API, modules []string, srv *rpc.Server
} }
// Register all the APIs exposed by the services // Register all the APIs exposed by the services
for _, api := range apis { for _, api := range apis {
if whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) { if exposeAll || whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {
if err := srv.RegisterName(api.Namespace, api.Service); err != nil { if err := srv.RegisterName(api.Namespace, api.Service); err != nil {
return err return err
} }

View file

@ -45,7 +45,7 @@ func CheckModuleAvailability(modules []string, apis []API) (bad, available []str
// StartHTTPEndpoint starts the HTTP RPC endpoint, configured with cors/vhosts/modules. // StartHTTPEndpoint starts the HTTP RPC endpoint, configured with cors/vhosts/modules.
func StartHTTPEndpoint(endpoint string, timeouts HTTPTimeouts, handler http.Handler) (net.Listener, error) { func StartHTTPEndpoint(endpoint string, timeouts HTTPTimeouts, handler http.Handler) (net.Listener, error) {
// Start the HTTP listener // start the HTTP listener
var ( var (
listener net.Listener listener net.Listener
err error err error
@ -53,19 +53,8 @@ func StartHTTPEndpoint(endpoint string, timeouts HTTPTimeouts, handler http.Hand
if listener, err = net.Listen("tcp", endpoint); err != nil { if listener, err = net.Listen("tcp", endpoint); err != nil {
return nil, err return nil, err
} }
// Make sure timeout values are meaningful
if timeouts.ReadTimeout < time.Second { CheckTimeouts(&timeouts)
log.Warn("Sanitizing invalid HTTP read timeout", "provided", timeouts.ReadTimeout, "updated", DefaultHTTPTimeouts.ReadTimeout)
timeouts.ReadTimeout = DefaultHTTPTimeouts.ReadTimeout
}
if timeouts.WriteTimeout < time.Second {
log.Warn("Sanitizing invalid HTTP write timeout", "provided", timeouts.WriteTimeout, "updated", DefaultHTTPTimeouts.WriteTimeout)
timeouts.WriteTimeout = DefaultHTTPTimeouts.WriteTimeout
}
if timeouts.IdleTimeout < time.Second {
log.Warn("Sanitizing invalid HTTP idle timeout", "provided", timeouts.IdleTimeout, "updated", DefaultHTTPTimeouts.IdleTimeout)
timeouts.IdleTimeout = DefaultHTTPTimeouts.IdleTimeout
}
// Bundle and start the HTTP server // Bundle and start the HTTP server
httpSrv := &http.Server{ httpSrv := &http.Server{
Handler: handler, Handler: handler,
@ -78,35 +67,18 @@ func StartHTTPEndpoint(endpoint string, timeouts HTTPTimeouts, handler http.Hand
} }
// StartWSEndpoint starts a websocket endpoint. // StartWSEndpoint starts a websocket endpoint.
func StartWSEndpoint(endpoint string, apis []API, modules []string, wsOrigins []string, exposeAll bool) (net.Listener, *Server, error) { func StartWSEndpoint(endpoint string, handler http.Handler) (net.Listener, error) {
if bad, available := CheckModuleAvailability(modules, apis); len(bad) > 0 { // start the HTTP listener
log.Error("Unavailable modules in WS API list", "unavailable", bad, "available", available)
}
// Generate the whitelist based on the allowed modules
whitelist := make(map[string]bool)
for _, module := range modules {
whitelist[module] = true
}
// Register all the APIs exposed by the services
handler := NewServer()
for _, api := range apis {
if exposeAll || whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {
if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
return nil, nil, err
}
log.Debug("WebSocket registered", "service", api.Service, "namespace", api.Namespace)
}
}
// All APIs registered, start the HTTP listener
var ( var (
listener net.Listener listener net.Listener
err error err error
) )
if listener, err = net.Listen("tcp", endpoint); err != nil { if listener, err = net.Listen("tcp", endpoint); err != nil {
return nil, nil, err return nil, err
} }
go NewWSServer(wsOrigins, handler).Serve(listener) wsSrv := &http.Server{Handler: handler}
return listener, handler, err go wsSrv.Serve(listener)
return listener, err
} }
// StartIPCEndpoint starts an IPC endpoint. // StartIPCEndpoint starts an IPC endpoint.
@ -127,3 +99,19 @@ func StartIPCEndpoint(ipcEndpoint string, apis []API) (net.Listener, *Server, er
go handler.ServeListener(listener) go handler.ServeListener(listener)
return listener, handler, nil return listener, handler, nil
} }
// CheckTimeouts ensures that timeout values are meaningful
func CheckTimeouts(timeouts *HTTPTimeouts) {
if timeouts.ReadTimeout < time.Second {
log.Warn("Sanitizing invalid HTTP read timeout", "provided", timeouts.ReadTimeout, "updated", DefaultHTTPTimeouts.ReadTimeout)
timeouts.ReadTimeout = DefaultHTTPTimeouts.ReadTimeout
}
if timeouts.WriteTimeout < time.Second {
log.Warn("Sanitizing invalid HTTP write timeout", "provided", timeouts.WriteTimeout, "updated", DefaultHTTPTimeouts.WriteTimeout)
timeouts.WriteTimeout = DefaultHTTPTimeouts.WriteTimeout
}
if timeouts.IdleTimeout < time.Second {
log.Warn("Sanitizing invalid HTTP idle timeout", "provided", timeouts.IdleTimeout, "updated", DefaultHTTPTimeouts.IdleTimeout)
timeouts.IdleTimeout = DefaultHTTPTimeouts.IdleTimeout
}
}

View file

@ -38,13 +38,6 @@ const (
var wsBufferPool = new(sync.Pool) var wsBufferPool = new(sync.Pool)
// NewWSServer creates a new websocket RPC server around an API provider.
//
// Deprecated: use Server.WebsocketHandler
func NewWSServer(allowedOrigins []string, srv *Server) *http.Server {
return &http.Server{Handler: srv.WebsocketHandler(allowedOrigins)}
}
// WebsocketHandler returns a handler that serves JSON-RPC to WebSocket connections. // WebsocketHandler returns a handler that serves JSON-RPC to WebSocket connections.
// //
// allowedOrigins should be a comma-separated list of allowed origin URLs. // allowedOrigins should be a comma-separated list of allowed origin URLs.