rpc: make max_body_bytes and max_header_bytes configurable (#3818)

* rpc: make max_body_bytes and max_header_bytes configurable

* update changelog pending
This commit is contained in:
Jun Kimura
2019-07-20 16:44:42 +09:00
committed by Jack Zampolin
parent 073cd1125e
commit 5d7e22a53c
7 changed files with 65 additions and 25 deletions

View File

@ -448,6 +448,9 @@ type wsConnection struct {
// Send pings to server with this period. Must be less than readWait, but greater than zero.
pingPeriod time.Duration
// Maximum message size.
readLimit int64
// callback which is called upon disconnect
onDisconnect func(remoteAddr string)
@ -467,7 +470,6 @@ func NewWSConnection(
cdc *amino.Codec,
options ...func(*wsConnection),
) *wsConnection {
baseConn.SetReadLimit(maxBodyBytes)
wsc := &wsConnection{
remoteAddr: baseConn.RemoteAddr().String(),
baseConn: baseConn,
@ -481,6 +483,7 @@ func NewWSConnection(
for _, option := range options {
option(wsc)
}
wsc.baseConn.SetReadLimit(wsc.readLimit)
wsc.BaseService = *cmn.NewBaseService(nil, "wsConnection", wsc)
return wsc
}
@ -525,6 +528,14 @@ func PingPeriod(pingPeriod time.Duration) func(*wsConnection) {
}
}
// ReadLimit sets the maximum size for reading message.
// It should only be used in the constructor - not Goroutine-safe.
func ReadLimit(readLimit int64) func(*wsConnection) {
return func(wsc *wsConnection) {
wsc.readLimit = readLimit
}
}
// OnStart implements cmn.Service by starting the read and write routines. It
// blocks until the connection closes.
func (wsc *wsConnection) OnStart() error {

View File

@ -26,6 +26,11 @@ type Config struct {
ReadTimeout time.Duration
// mirrors http.Server#WriteTimeout
WriteTimeout time.Duration
// MaxBodyBytes controls the maximum number of bytes the
// server will read parsing the request body.
MaxBodyBytes int64
// mirrors http.Server#MaxHeaderBytes
MaxHeaderBytes int
}
// DefaultConfig returns a default configuration.
@ -34,28 +39,21 @@ func DefaultConfig() *Config {
MaxOpenConnections: 0, // unlimited
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxBodyBytes: int64(1000000), // 1MB
MaxHeaderBytes: 1 << 20, // same as the net/http default
}
}
const (
// maxBodyBytes controls the maximum number of bytes the
// server will read parsing the request body.
maxBodyBytes = int64(1000000) // 1MB
// same as the net/http default
maxHeaderBytes = 1 << 20
)
// StartHTTPServer takes a listener and starts an HTTP server with the given handler.
// It wraps handler with RecoverAndLogHandler.
// NOTE: This function blocks - you may want to call it in a go-routine.
func StartHTTPServer(listener net.Listener, handler http.Handler, logger log.Logger, config *Config) error {
logger.Info(fmt.Sprintf("Starting RPC HTTP server on %s", listener.Addr()))
s := &http.Server{
Handler: RecoverAndLogHandler(maxBytesHandler{h: handler, n: maxBodyBytes}, logger),
Handler: RecoverAndLogHandler(maxBytesHandler{h: handler, n: config.MaxBodyBytes}, logger),
ReadTimeout: config.ReadTimeout,
WriteTimeout: config.WriteTimeout,
MaxHeaderBytes: maxHeaderBytes,
MaxHeaderBytes: config.MaxHeaderBytes,
}
err := s.Serve(listener)
logger.Info("RPC HTTP server stopped", "err", err)
@ -75,10 +73,10 @@ func StartHTTPAndTLSServer(
logger.Info(fmt.Sprintf("Starting RPC HTTPS server on %s (cert: %q, key: %q)",
listener.Addr(), certFile, keyFile))
s := &http.Server{
Handler: RecoverAndLogHandler(maxBytesHandler{h: handler, n: maxBodyBytes}, logger),
Handler: RecoverAndLogHandler(maxBytesHandler{h: handler, n: config.MaxBodyBytes}, logger),
ReadTimeout: config.ReadTimeout,
WriteTimeout: config.WriteTimeout,
MaxHeaderBytes: maxHeaderBytes,
MaxHeaderBytes: config.MaxHeaderBytes,
}
err := s.ServeTLS(listener, certFile, keyFile)