rpc: support https

Allow to start TLS RPC server on a separate port.
Closes #702.
This commit is contained in:
Evgenii Stratonikov 2020-03-10 14:56:18 +03:00
parent 93236e0cfa
commit dfbb84ef38
5 changed files with 62 additions and 2 deletions

View file

@ -111,6 +111,16 @@ type (
// MaxGasInvoke is a maximum amount of gas which // MaxGasInvoke is a maximum amount of gas which
// can be spent during RPC call. // can be spent during RPC call.
MaxGasInvoke util.Fixed8 `yaml:"MaxGasInvoke"` MaxGasInvoke util.Fixed8 `yaml:"MaxGasInvoke"`
TLSConfig TLSConfig `yaml:"TLSConfig"`
}
// TLSConfig describes SSL/TLS configuration.
TLSConfig struct {
Enabled bool `yaml:"Enabled"`
Address string `yaml:"Address"`
Port uint16 `yaml:"Port"`
CertFile string `yaml:"CertFile"`
KeyFile string `yaml:"KeyFile"`
} }
// NetMode describes the mode the blockchain will operate on. // NetMode describes the mode the blockchain will operate on.

View file

@ -65,6 +65,11 @@ ApplicationConfiguration:
Enabled: true Enabled: true
EnableCORSWorkaround: false EnableCORSWorkaround: false
Port: 10332 Port: 10332
TLSConfig:
Enabled: false
Port: 10331
CertFile: serv.crt
KeyFile: serv.key
Prometheus: Prometheus:
Enabled: true Enabled: true
Port: 2112 Port: 2112

View file

@ -51,6 +51,11 @@ ApplicationConfiguration:
Enabled: true Enabled: true
EnableCORSWorkaround: false EnableCORSWorkaround: false
Port: 20331 Port: 20331
TLSConfig:
Enabled: false
Port: 20330
CertFile: serv.crt
KeyFile: serv.key
Prometheus: Prometheus:
Enabled: true Enabled: true
Port: 2112 Port: 2112

View file

@ -65,6 +65,11 @@ ApplicationConfiguration:
Enabled: true Enabled: true
EnableCORSWorkaround: false EnableCORSWorkaround: false
Port: 20332 Port: 20332
TLSConfig:
Enabled: false
Port: 20331
CertFile: serv.crt
KeyFile: serv.key
Prometheus: Prometheus:
Enabled: true Enabled: true
Port: 2112 Port: 2112

View file

@ -6,6 +6,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"math" "math"
"net"
"net/http" "net/http"
"strconv" "strconv"
@ -37,6 +38,7 @@ type (
config config.RPCConfig config config.RPCConfig
coreServer *network.Server coreServer *network.Server
log *zap.Logger log *zap.Logger
https *http.Server
} }
) )
@ -50,12 +52,20 @@ func New(chain core.Blockchainer, conf config.RPCConfig, coreServer *network.Ser
Addr: conf.Address + ":" + strconv.FormatUint(uint64(conf.Port), 10), Addr: conf.Address + ":" + strconv.FormatUint(uint64(conf.Port), 10),
} }
var tlsServer *http.Server
if cfg := conf.TLSConfig; cfg.Enabled {
tlsServer = &http.Server{
Addr: net.JoinHostPort(cfg.Address, strconv.FormatUint(uint64(cfg.Port), 10)),
}
}
return Server{ return Server{
Server: httpServer, Server: httpServer,
chain: chain, chain: chain,
config: conf, config: conf,
coreServer: coreServer, coreServer: coreServer,
log: log, log: log,
https: tlsServer,
} }
} }
@ -69,14 +79,39 @@ func (s *Server) Start(errChan chan error) {
s.Handler = http.HandlerFunc(s.requestHandler) s.Handler = http.HandlerFunc(s.requestHandler)
s.log.Info("starting rpc-server", zap.String("endpoint", s.Addr)) s.log.Info("starting rpc-server", zap.String("endpoint", s.Addr))
errChan <- s.ListenAndServe() if cfg := s.config.TLSConfig; cfg.Enabled {
s.https.Handler = http.HandlerFunc(s.requestHandler)
s.log.Info("starting rpc-server (https)", zap.String("endpoint", s.https.Addr))
go func() {
err := s.https.ListenAndServeTLS(cfg.CertFile, cfg.KeyFile)
if err != nil {
s.log.Error("failed to start TLS RPC server", zap.Error(err))
}
errChan <- err
}()
}
err := s.ListenAndServe()
if err != nil {
s.log.Error("failed to start RPC server", zap.Error(err))
}
errChan <- err
} }
// Shutdown overrides the http.Server Shutdown // Shutdown overrides the http.Server Shutdown
// method. // method.
func (s *Server) Shutdown() error { func (s *Server) Shutdown() error {
var httpsErr error
if s.config.TLSConfig.Enabled {
s.log.Info("shutting down rpc-server (https)", zap.String("endpoint", s.https.Addr))
httpsErr = s.https.Shutdown(context.Background())
}
s.log.Info("shutting down rpc-server", zap.String("endpoint", s.Addr)) s.log.Info("shutting down rpc-server", zap.String("endpoint", s.Addr))
return s.Server.Shutdown(context.Background()) err := s.Server.Shutdown(context.Background())
if err == nil {
return httpsErr
}
return err
} }
func (s *Server) requestHandler(w http.ResponseWriter, httpRequest *http.Request) { func (s *Server) requestHandler(w http.ResponseWriter, httpRequest *http.Request) {