gitlab.com/jokerrs1/Sia@v1.3.2/node/api/server/server.go (about)

     1  // Package server provides a server that can wrap a node and serve an http api
     2  // for interacting with the node.
     3  package server
     4  
     5  import (
     6  	"net"
     7  	"net/http"
     8  	"strings"
     9  
    10  	"github.com/NebulousLabs/Sia/modules"
    11  	"github.com/NebulousLabs/Sia/node"
    12  	"github.com/NebulousLabs/Sia/node/api"
    13  
    14  	"github.com/NebulousLabs/errors"
    15  )
    16  
    17  // A Server is a collection of siad modules that can be communicated with over
    18  // an http api.
    19  type Server struct {
    20  	api               *api.API
    21  	apiServer         *http.Server
    22  	done              chan struct{}
    23  	listener          net.Listener
    24  	node              *node.Node
    25  	requiredUserAgent string
    26  	serveErr          error
    27  	Dir               string
    28  }
    29  
    30  // serve listens for and handles API calls. It is a blocking function.
    31  func (srv *Server) serve() error {
    32  	// The server will run until an error is encountered or the listener is
    33  	// closed, via either the Close method or by signal handling.  Closing the
    34  	// listener will result in the benign error handled below.
    35  	err := srv.apiServer.Serve(srv.listener)
    36  	if err != nil && !strings.HasSuffix(err.Error(), "use of closed network connection") {
    37  		return err
    38  	}
    39  	return nil
    40  }
    41  
    42  // Close closes the Server's listener, causing the HTTP server to shut down.
    43  func (srv *Server) Close() error {
    44  	// Stop accepting API requests.
    45  	err := srv.listener.Close()
    46  	// Wait for serve() to return and capture its error.
    47  	<-srv.done
    48  	err = errors.Compose(err, srv.serveErr)
    49  	// Shutdown modules.
    50  	err = errors.Compose(err, srv.node.Close())
    51  	return errors.AddContext(err, "error while closing server")
    52  }
    53  
    54  // APIAddress returns the underlying node's api address
    55  func (srv *Server) APIAddress() string {
    56  	return srv.listener.Addr().String()
    57  }
    58  
    59  // GatewayAddress returns the underlying node's gateway address
    60  func (srv *Server) GatewayAddress() modules.NetAddress {
    61  	return srv.node.Gateway.Address()
    62  }
    63  
    64  // New creates a new API server from the provided modules. The API will
    65  // require authentication using HTTP basic auth if the supplied password is not
    66  // the empty string. Usernames are ignored for authentication. This type of
    67  // authentication sends passwords in plaintext and should therefore only be
    68  // used if the APIaddr is localhost.
    69  func New(APIaddr string, requiredUserAgent string, requiredPassword string, nodeParams node.NodeParams) (*Server, error) {
    70  	// Create the server listener.
    71  	listener, err := net.Listen("tcp", APIaddr)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	// Create the Sia node for the server.
    77  	node, err := node.New(nodeParams)
    78  	if err != nil {
    79  		return nil, errors.AddContext(err, "server is unable to create the Sia node")
    80  	}
    81  
    82  	// Create the api for the server.
    83  	api := api.New(requiredUserAgent, requiredPassword, node.ConsensusSet, node.Explorer, node.Gateway, node.Host, node.Miner, node.Renter, node.TransactionPool, node.Wallet)
    84  	srv := &Server{
    85  		api: api,
    86  		apiServer: &http.Server{
    87  			Handler: api,
    88  		},
    89  		done:              make(chan struct{}),
    90  		listener:          listener,
    91  		node:              node,
    92  		requiredUserAgent: requiredUserAgent,
    93  		Dir:               nodeParams.Dir,
    94  	}
    95  
    96  	// Spin up a goroutine that serves the API and closes srv.done when
    97  	// finished.
    98  	go func() {
    99  		srv.serveErr = srv.serve()
   100  		close(srv.done)
   101  	}()
   102  
   103  	return srv, nil
   104  }