diff --git a/rpcserver.go b/rpcserver.go index 1add3136..407b0bf1 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -31,6 +31,10 @@ import ( "time" ) +// rpcAuthTimeoutSeconds is the number of seconds a connection to the RPC server +// is allowed to stay open without authenticating before it is closed. +const rpcAuthTimeoutSeconds = 10 + // Errors var ( // ErrBadParamsField describes an error where the parameters JSON @@ -137,7 +141,13 @@ func (s *rpcServer) Start() { rpcsLog.Trace("Starting RPC server") rpcServeMux := http.NewServeMux() - httpServer := &http.Server{Handler: rpcServeMux} + httpServer := &http.Server{ + Handler: rpcServeMux, + + // Timeout connections which don't complete the initial + // handshake within the allowed timeframe. + ReadTimeout: time.Second * rpcAuthTimeoutSeconds, + } rpcServeMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if err := s.checkAuth(r); err != nil { jsonAuthFail(w, r, s) diff --git a/rpcwebsocket.go b/rpcwebsocket.go index 0bf3550b..1454bab4 100644 --- a/rpcwebsocket.go +++ b/rpcwebsocket.go @@ -18,8 +18,11 @@ import ( "github.com/conformal/btcwire" "github.com/conformal/btcws" "sync" + "time" ) +var timeZeroVal time.Time + type ntfnChan chan btcjson.Cmd type handlerChans struct { @@ -546,6 +549,10 @@ func (s *rpcServer) RemoveWalletListener(n ntfnChan) { // connections from a btcwallet instance. It reads messages from wallet and // sends back replies, as well as notififying wallets of chain updates. func (s *rpcServer) walletReqsNotifications(ws *websocket.Conn) { + // Clear the read deadline that was set before the websocket hijacked + // the connection. + ws.SetReadDeadline(timeZeroVal) + // Add wallet notification channel so this handler receives btcd chain // notifications. n := make(ntfnChan)