@@ -31,6 +31,7 @@ import (
3131 "sync"
3232 "time"
3333
34+ "github.com/ethereum/go-ethereum/log"
3435 "github.com/rs/cors"
3536)
3637
@@ -66,6 +67,38 @@ func (hc *httpConn) Close() error {
6667 return nil
6768}
6869
70+ // HTTPTimeouts represents the configuration params for the HTTP RPC server.
71+ type HTTPTimeouts struct {
72+ // ReadTimeout is the maximum duration for reading the entire
73+ // request, including the body.
74+ //
75+ // Because ReadTimeout does not let Handlers make per-request
76+ // decisions on each request body's acceptable deadline or
77+ // upload rate, most users will prefer to use
78+ // ReadHeaderTimeout. It is valid to use them both.
79+ ReadTimeout time.Duration
80+
81+ // WriteTimeout is the maximum duration before timing out
82+ // writes of the response. It is reset whenever a new
83+ // request's header is read. Like ReadTimeout, it does not
84+ // let Handlers make decisions on a per-request basis.
85+ WriteTimeout time.Duration
86+
87+ // IdleTimeout is the maximum amount of time to wait for the
88+ // next request when keep-alives are enabled. If IdleTimeout
89+ // is zero, the value of ReadTimeout is used. If both are
90+ // zero, ReadHeaderTimeout is used.
91+ IdleTimeout time.Duration
92+ }
93+
94+ // DefaultHTTPTimeouts represents the default timeout values used if further
95+ // configuration is not provided.
96+ var DefaultHTTPTimeouts = HTTPTimeouts {
97+ ReadTimeout : 30 * time .Second ,
98+ WriteTimeout : 30 * time .Second ,
99+ IdleTimeout : 120 * time .Second ,
100+ }
101+
69102// DialHTTPWithClient creates a new RPC client that connects to an RPC server over HTTP
70103// using the provided HTTP Client.
71104func DialHTTPWithClient (endpoint string , client * http.Client ) (* Client , error ) {
@@ -161,15 +194,30 @@ func (t *httpReadWriteNopCloser) Close() error {
161194// NewHTTPServer creates a new HTTP RPC server around an API provider.
162195//
163196// Deprecated: Server implements http.Handler
164- func NewHTTPServer (cors []string , vhosts []string , srv * Server ) * http.Server {
197+ func NewHTTPServer (cors []string , vhosts []string , timeouts HTTPTimeouts , srv * Server ) * http.Server {
165198 // Wrap the CORS-handler within a host-handler
166199 handler := newCorsHandler (srv , cors )
167200 handler = newVHostHandler (vhosts , handler )
201+
202+ // Make sure timeout values are meaningful
203+ if timeouts .ReadTimeout < time .Second {
204+ log .Warn ("Sanitizing invalid HTTP read timeout" , "provided" , timeouts .ReadTimeout , "updated" , DefaultHTTPTimeouts .ReadTimeout )
205+ timeouts .ReadTimeout = DefaultHTTPTimeouts .ReadTimeout
206+ }
207+ if timeouts .WriteTimeout < time .Second {
208+ log .Warn ("Sanitizing invalid HTTP write timeout" , "provided" , timeouts .WriteTimeout , "updated" , DefaultHTTPTimeouts .WriteTimeout )
209+ timeouts .WriteTimeout = DefaultHTTPTimeouts .WriteTimeout
210+ }
211+ if timeouts .IdleTimeout < time .Second {
212+ log .Warn ("Sanitizing invalid HTTP idle timeout" , "provided" , timeouts .IdleTimeout , "updated" , DefaultHTTPTimeouts .IdleTimeout )
213+ timeouts .IdleTimeout = DefaultHTTPTimeouts .IdleTimeout
214+ }
215+ // Bundle and start the HTTP server
168216 return & http.Server {
169217 Handler : handler ,
170- ReadTimeout : 5 * time . Second ,
171- WriteTimeout : 10 * time . Second ,
172- IdleTimeout : 120 * time . Second ,
218+ ReadTimeout : timeouts . ReadTimeout ,
219+ WriteTimeout : timeouts . WriteTimeout ,
220+ IdleTimeout : timeouts . IdleTimeout ,
173221 }
174222}
175223
0 commit comments