@ -31,6 +31,7 @@ import (
"sync"
"time"
"github.com/ethereum/go-ethereum/log"
"github.com/rs/cors"
)
@ -66,6 +67,38 @@ func (hc *httpConn) Close() error {
return nil
}
// HTTPTimeouts represents the configuration params for the HTTP RPC server.
type HTTPTimeouts struct {
// ReadTimeout is the maximum duration for reading the entire
// request, including the body.
//
// Because ReadTimeout does not let Handlers make per-request
// decisions on each request body's acceptable deadline or
// upload rate, most users will prefer to use
// ReadHeaderTimeout. It is valid to use them both.
ReadTimeout time . Duration
// WriteTimeout is the maximum duration before timing out
// writes of the response. It is reset whenever a new
// request's header is read. Like ReadTimeout, it does not
// let Handlers make decisions on a per-request basis.
WriteTimeout time . Duration
// IdleTimeout is the maximum amount of time to wait for the
// next request when keep-alives are enabled. If IdleTimeout
// is zero, the value of ReadTimeout is used. If both are
// zero, ReadHeaderTimeout is used.
IdleTimeout time . Duration
}
// DefaultHTTPTimeouts represents the default timeout values used if further
// configuration is not provided.
var DefaultHTTPTimeouts = HTTPTimeouts {
ReadTimeout : 30 * time . Second ,
WriteTimeout : 30 * time . Second ,
IdleTimeout : 120 * time . Second ,
}
// DialHTTPWithClient creates a new RPC client that connects to an RPC server over HTTP
// using the provided HTTP Client.
func DialHTTPWithClient ( endpoint string , client * http . Client ) ( * Client , error ) {
@ -161,15 +194,30 @@ func (t *httpReadWriteNopCloser) Close() error {
// NewHTTPServer creates a new HTTP RPC server around an API provider.
//
// Deprecated: Server implements http.Handler
func NewHTTPServer ( cors [ ] string , vhosts [ ] string , srv * Server ) * http . Server {
func NewHTTPServer ( cors [ ] string , vhosts [ ] string , timeouts HTTPTimeouts , srv * Server ) * http . Server {
// Wrap the CORS-handler within a host-handler
handler := newCorsHandler ( srv , cors )
handler = newVHostHandler ( vhosts , handler )
// Make sure timeout values are meaningful
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
}
// Bundle and start the HTTP server
return & http . Server {
Handler : handler ,
ReadTimeout : 5 * time . Second ,
WriteTimeout : 10 * time . Second ,
IdleTimeout : 120 * time . Second ,
ReadTimeout : timeouts . ReadTimeout ,
WriteTimeout : timeouts . WriteTimeout ,
IdleTimeout : timeouts . IdleTimeout ,
}
}