1717package node
1818
1919import (
20+ "context"
2021 "errors"
2122 "fmt"
2223 "net"
24+ "net/http"
2325 "os"
2426 "path/filepath"
2527 "reflect"
@@ -59,14 +61,16 @@ type Node struct {
5961 ipcListener net.Listener // IPC RPC listener socket to serve API requests
6062 ipcHandler * rpc.Server // IPC RPC request handler to process the API requests
6163
62- httpEndpoint string // HTTP endpoint (interface + port) to listen at (empty = HTTP disabled)
63- httpWhitelist []string // HTTP RPC modules to allow through this endpoint
64- httpListener net.Listener // HTTP RPC listener socket to server API requests
65- httpHandler * rpc.Server // HTTP RPC request handler to process the API requests
64+ httpEndpoint string // HTTP endpoint (interface + port) to listen at (empty = HTTP disabled)
65+ httpWhitelist []string // HTTP RPC modules to allow through this endpoint
66+ httpListenerAddr net.Addr // Address of HTTP RPC listener socket serving API requests
67+ httpServer * http.Server // HTTP RPC HTTP server
68+ httpHandler * rpc.Server // HTTP RPC request handler to process the API requests
6669
67- wsEndpoint string // Websocket endpoint (interface + port) to listen at (empty = websocket disabled)
68- wsListener net.Listener // Websocket RPC listener socket to server API requests
69- wsHandler * rpc.Server // Websocket RPC request handler to process the API requests
70+ wsEndpoint string // WebSocket endpoint (interface + port) to listen at (empty = WebSocket disabled)
71+ wsListenerAddr net.Addr // Address of WebSocket RPC listener socket serving API requests
72+ wsHTTPServer * http.Server // WebSocket RPC HTTP server
73+ wsHandler * rpc.Server // WebSocket RPC request handler to process the API requests
7074
7175 stop chan struct {} // Channel to wait for termination notifications
7276 lock sync.RWMutex
@@ -375,43 +379,43 @@ func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors
375379 return err
376380 }
377381 handler := NewHTTPHandlerStack (srv , cors , vhosts )
378- // wrap handler in websocket handler only if websocket port is the same as http rpc
382+ // wrap handler in WebSocket handler only if WebSocket port is the same as http rpc
379383 if n .httpEndpoint == n .wsEndpoint {
380384 handler = NewWebsocketUpgradeHandler (handler , srv .WebsocketHandler (wsOrigins ))
381385 }
382- listener , err := StartHTTPEndpoint (endpoint , timeouts , handler )
386+ httpServer , addr , err := StartHTTPEndpoint (endpoint , timeouts , handler )
383387 if err != nil {
384388 return err
385389 }
386- n .log .Info ("HTTP endpoint opened" , "url" , fmt .Sprintf ("http://%v/" , listener . Addr () ),
390+ n .log .Info ("HTTP endpoint opened" , "url" , fmt .Sprintf ("http://%v/" , addr ),
387391 "cors" , strings .Join (cors , "," ),
388392 "vhosts" , strings .Join (vhosts , "," ))
389393 if n .httpEndpoint == n .wsEndpoint {
390- n .log .Info ("WebSocket endpoint opened" , "url" , fmt .Sprintf ("ws://%v" , listener . Addr () ))
394+ n .log .Info ("WebSocket endpoint opened" , "url" , fmt .Sprintf ("ws://%v" , addr ))
391395 }
392396 // All listeners booted successfully
393397 n .httpEndpoint = endpoint
394- n .httpListener = listener
398+ n .httpListenerAddr = addr
399+ n .httpServer = httpServer
395400 n .httpHandler = srv
396401
397402 return nil
398403}
399404
400405// stopHTTP terminates the HTTP RPC endpoint.
401406func (n * Node ) stopHTTP () {
402- if n .httpListener != nil {
403- url := fmt .Sprintf ("http://%v/" , n .httpListener .Addr ())
404- n .httpListener .Close ()
405- n .httpListener = nil
406- n .log .Info ("HTTP endpoint closed" , "url" , url )
407+ if n .httpServer != nil {
408+ // Don't bother imposing a timeout here.
409+ n .httpServer .Shutdown (context .Background ())
410+ n .log .Info ("HTTP endpoint closed" , "url" , fmt .Sprintf ("http://%v/" , n .httpListenerAddr ))
407411 }
408412 if n .httpHandler != nil {
409413 n .httpHandler .Stop ()
410414 n .httpHandler = nil
411415 }
412416}
413417
414- // startWS initializes and starts the websocket RPC endpoint.
418+ // startWS initializes and starts the WebSocket RPC endpoint.
415419func (n * Node ) startWS (endpoint string , apis []rpc.API , modules []string , wsOrigins []string , exposeAll bool ) error {
416420 // Short circuit if the WS endpoint isn't being exposed
417421 if endpoint == "" {
@@ -424,26 +428,26 @@ func (n *Node) startWS(endpoint string, apis []rpc.API, modules []string, wsOrig
424428 if err != nil {
425429 return err
426430 }
427- listener , err := startWSEndpoint (endpoint , handler )
431+ httpServer , addr , err := startWSEndpoint (endpoint , handler )
428432 if err != nil {
429433 return err
430434 }
431- n .log .Info ("WebSocket endpoint opened" , "url" , fmt .Sprintf ("ws://%s " , listener . Addr () ))
435+ n .log .Info ("WebSocket endpoint opened" , "url" , fmt .Sprintf ("ws://%v " , addr ))
432436 // All listeners booted successfully
433437 n .wsEndpoint = endpoint
434- n .wsListener = listener
438+ n .wsListenerAddr = addr
439+ n .wsHTTPServer = httpServer
435440 n .wsHandler = srv
436441
437442 return nil
438443}
439444
440- // stopWS terminates the websocket RPC endpoint.
445+ // stopWS terminates the WebSocket RPC endpoint.
441446func (n * Node ) stopWS () {
442- if n .wsListener != nil {
443- n .wsListener .Close ()
444- n .wsListener = nil
445-
446- n .log .Info ("WebSocket endpoint closed" , "url" , fmt .Sprintf ("ws://%s" , n .wsEndpoint ))
447+ if n .wsHTTPServer != nil {
448+ // Don't bother imposing a timeout here.
449+ n .wsHTTPServer .Shutdown (context .Background ())
450+ n .log .Info ("WebSocket endpoint closed" , "url" , fmt .Sprintf ("ws://%v" , n .wsListenerAddr ))
447451 }
448452 if n .wsHandler != nil {
449453 n .wsHandler .Stop ()
@@ -607,8 +611,8 @@ func (n *Node) HTTPEndpoint() string {
607611 n .lock .Lock ()
608612 defer n .lock .Unlock ()
609613
610- if n .httpListener != nil {
611- return n .httpListener . Addr () .String ()
614+ if n .httpListenerAddr != nil {
615+ return n .httpListenerAddr .String ()
612616 }
613617 return n .httpEndpoint
614618}
@@ -618,8 +622,8 @@ func (n *Node) WSEndpoint() string {
618622 n .lock .Lock ()
619623 defer n .lock .Unlock ()
620624
621- if n .wsListener != nil {
622- return n .wsListener . Addr () .String ()
625+ if n .wsListenerAddr != nil {
626+ return n .wsListenerAddr .String ()
623627 }
624628 return n .wsEndpoint
625629}
0 commit comments