github.com/Evanesco-Labs/go-evanesco@v1.0.1/node/endpoints.go (about)

     1  // Copyright 2018 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package node
    18  
    19  import (
    20  	"net"
    21  	"net/http"
    22  	"time"
    23  
    24  	"github.com/Evanesco-Labs/go-evanesco/log"
    25  	"github.com/Evanesco-Labs/go-evanesco/rpc"
    26  )
    27  
    28  // StartHTTPEndpoint starts the HTTP RPC endpoint.
    29  func StartHTTPEndpoint(endpoint string, timeouts rpc.HTTPTimeouts, handler http.Handler) (*http.Server, net.Addr, error) {
    30  	// start the HTTP listener
    31  	var (
    32  		listener net.Listener
    33  		err      error
    34  	)
    35  	if listener, err = net.Listen("tcp", endpoint); err != nil {
    36  		return nil, nil, err
    37  	}
    38  	// make sure timeout values are meaningful
    39  	CheckTimeouts(&timeouts)
    40  	// Bundle and start the HTTP server
    41  	httpSrv := &http.Server{
    42  		Handler:      handler,
    43  		ReadTimeout:  timeouts.ReadTimeout,
    44  		WriteTimeout: timeouts.WriteTimeout,
    45  		IdleTimeout:  timeouts.IdleTimeout,
    46  	}
    47  	go httpSrv.Serve(listener)
    48  	return httpSrv, listener.Addr(), err
    49  }
    50  
    51  // checkModuleAvailability checks that all names given in modules are actually
    52  // available API services. It assumes that the MetadataApi module ("rpc") is always available;
    53  // the registration of this "rpc" module happens in NewServer() and is thus common to all endpoints.
    54  func checkModuleAvailability(modules []string, apis []rpc.API) (bad, available []string) {
    55  	availableSet := make(map[string]struct{})
    56  	for _, api := range apis {
    57  		if _, ok := availableSet[api.Namespace]; !ok {
    58  			availableSet[api.Namespace] = struct{}{}
    59  			available = append(available, api.Namespace)
    60  		}
    61  	}
    62  	for _, name := range modules {
    63  		if _, ok := availableSet[name]; !ok && name != rpc.MetadataApi {
    64  			bad = append(bad, name)
    65  		}
    66  	}
    67  	return bad, available
    68  }
    69  
    70  // CheckTimeouts ensures that timeout values are meaningful
    71  func CheckTimeouts(timeouts *rpc.HTTPTimeouts) {
    72  	if timeouts.ReadTimeout < time.Second {
    73  		log.Warn("Sanitizing invalid HTTP read timeout", "provided", timeouts.ReadTimeout, "updated", rpc.DefaultHTTPTimeouts.ReadTimeout)
    74  		timeouts.ReadTimeout = rpc.DefaultHTTPTimeouts.ReadTimeout
    75  	}
    76  	if timeouts.WriteTimeout < time.Second {
    77  		log.Warn("Sanitizing invalid HTTP write timeout", "provided", timeouts.WriteTimeout, "updated", rpc.DefaultHTTPTimeouts.WriteTimeout)
    78  		timeouts.WriteTimeout = rpc.DefaultHTTPTimeouts.WriteTimeout
    79  	}
    80  	if timeouts.IdleTimeout < time.Second {
    81  		log.Warn("Sanitizing invalid HTTP idle timeout", "provided", timeouts.IdleTimeout, "updated", rpc.DefaultHTTPTimeouts.IdleTimeout)
    82  		timeouts.IdleTimeout = rpc.DefaultHTTPTimeouts.IdleTimeout
    83  	}
    84  }