diff --git a/cmd/XDC/main.go b/cmd/XDC/main.go index 93fff4f05..0eb0b03a8 100644 --- a/cmd/XDC/main.go +++ b/cmd/XDC/main.go @@ -136,6 +136,7 @@ var ( utils.RPCEnabledFlag, utils.RPCListenAddrFlag, utils.RPCPortFlag, + utils.RPCHttpWriteTimeoutFlag, utils.RPCApiFlag, utils.WSEnabledFlag, utils.WSListenAddrFlag, diff --git a/cmd/XDC/usage.go b/cmd/XDC/usage.go index e2bf4d334..e07f9703d 100644 --- a/cmd/XDC/usage.go +++ b/cmd/XDC/usage.go @@ -144,6 +144,7 @@ var AppHelpFlagGroups = []flagGroup{ utils.RPCEnabledFlag, utils.RPCListenAddrFlag, utils.RPCPortFlag, + utils.RPCHttpWriteTimeoutFlag, utils.RPCApiFlag, utils.WSEnabledFlag, utils.WSListenAddrFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 287e7d250..ea4e7158e 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -398,6 +398,11 @@ var ( Usage: "HTTP-RPC server listening port", Value: node.DefaultHTTPPort, } + RPCHttpWriteTimeoutFlag = cli.DurationFlag{ + Name: "rpcwritetimeout", + Usage: "HTTP-RPC server write timeout (default = 10s)", + Value: node.DefaultHTTPWriteTimeOut, + } RPCCORSDomainFlag = cli.StringFlag{ Name: "rpccorsdomain", Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)", @@ -720,6 +725,9 @@ func setHTTP(ctx *cli.Context, cfg *node.Config) { if ctx.GlobalIsSet(RPCPortFlag.Name) { cfg.HTTPPort = ctx.GlobalInt(RPCPortFlag.Name) } + if ctx.GlobalIsSet(RPCHttpWriteTimeoutFlag.Name) { + cfg.HTTPWriteTimeout = ctx.GlobalDuration(RPCHttpWriteTimeoutFlag.Name) + } if ctx.GlobalIsSet(RPCCORSDomainFlag.Name) { cfg.HTTPCors = splitAndTrim(ctx.GlobalString(RPCCORSDomainFlag.Name)) } diff --git a/node/config.go b/node/config.go index b89781874..c7fab0489 100644 --- a/node/config.go +++ b/node/config.go @@ -24,6 +24,7 @@ import ( "path/filepath" "runtime" "strings" + "time" "github.com/XinFinOrg/XDC-Subnet/accounts" "github.com/XinFinOrg/XDC-Subnet/accounts/keystore" @@ -100,6 +101,9 @@ type Config struct { // for ephemeral nodes). HTTPPort int `toml:",omitempty"` + // HTTPWriteTimeout is the write timeout for the HTTP RPC server. + HTTPWriteTimeout time.Duration `toml:",omitempty"` + // HTTPCors is the Cross-Origin Resource Sharing header to send to requesting // clients. Please be aware that CORS is a browser enforced security, it's fully // useless for custom HTTP clients. diff --git a/node/defaults.go b/node/defaults.go index 7ab05fba8..fbf77bf59 100644 --- a/node/defaults.go +++ b/node/defaults.go @@ -21,22 +21,25 @@ import ( "os/user" "path/filepath" "runtime" + "time" "github.com/XinFinOrg/XDC-Subnet/p2p" "github.com/XinFinOrg/XDC-Subnet/p2p/nat" ) const ( - DefaultHTTPHost = "localhost" // Default host interface for the HTTP RPC server - DefaultHTTPPort = 8545 // Default TCP port for the HTTP RPC server - DefaultWSHost = "localhost" // Default host interface for the websocket RPC server - DefaultWSPort = 8546 // Default TCP port for the websocket RPC server + DefaultHTTPHost = "localhost" // Default host interface for the HTTP RPC server + DefaultHTTPPort = 8545 // Default TCP port for the HTTP RPC server + DefaultHTTPWriteTimeOut = 10 * time.Second // Default write timeout for the HTTP RPC server + DefaultWSHost = "localhost" // Default host interface for the websocket RPC server + DefaultWSPort = 8546 // Default TCP port for the websocket RPC server ) // DefaultConfig contains reasonable default settings. var DefaultConfig = Config{ DataDir: DefaultDataDir(), HTTPPort: DefaultHTTPPort, + HTTPWriteTimeout: DefaultHTTPWriteTimeOut, HTTPModules: []string{"net", "web3"}, HTTPVirtualHosts: []string{"localhost"}, WSPort: DefaultWSPort, diff --git a/node/node.go b/node/node.go index 7dd21dc96..f73025897 100644 --- a/node/node.go +++ b/node/node.go @@ -396,7 +396,7 @@ func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors if listener, err = net.Listen("tcp", endpoint); err != nil { return err } - go rpc.NewHTTPServer(cors, vhosts, handler).Serve(listener) + go rpc.NewHTTPServer(cors, vhosts, handler, n.config.HTTPWriteTimeout).Serve(listener) n.log.Info("HTTP endpoint opened", "url", fmt.Sprintf("http://%s", endpoint), "cors", strings.Join(cors, ","), "vhosts", strings.Join(vhosts, ",")) // All listeners booted successfully n.httpEndpoint = endpoint diff --git a/rpc/http.go b/rpc/http.go index a68b4dfe8..de988c221 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -32,6 +32,7 @@ import ( "sync" "time" + "github.com/XinFinOrg/XDPoSChain/log" "github.com/rs/cors" ) @@ -230,14 +231,15 @@ func (t *httpServerConn) SetWriteDeadline(time.Time) error { return nil } // 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, srv *Server, writeTimeout time.Duration) *http.Server { // Wrap the CORS-handler within a host-handler handler := newCorsHandler(srv, cors) handler = newVHostHandler(vhosts, handler) + log.Info("NewHTTPServer", "writeTimeout", writeTimeout) return &http.Server{ Handler: handler, ReadTimeout: 5 * time.Second, - WriteTimeout: 10 * time.Second, + WriteTimeout: writeTimeout, IdleTimeout: 120 * time.Second, } }