github.com/ethereum/go-ethereum@v1.14.3/node/endpoints.go (about)

     1  // Copyright 2020 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/ethereum/go-ethereum/log"
    25  	"github.com/ethereum/go-ethereum/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  		ReadHeaderTimeout: timeouts.ReadHeaderTimeout,
    45  		WriteTimeout:      timeouts.WriteTimeout,
    46  		IdleTimeout:       timeouts.IdleTimeout,
    47  	}
    48  	go httpSrv.Serve(listener)
    49  	return httpSrv, listener.Addr(), err
    50  }
    51  
    52  // checkModuleAvailability checks that all names given in modules are actually
    53  // available API services. It assumes that the MetadataApi module ("rpc") is always available;
    54  // the registration of this "rpc" module happens in NewServer() and is thus common to all endpoints.
    55  func checkModuleAvailability(modules []string, apis []rpc.API) (bad, available []string) {
    56  	availableSet := make(map[string]struct{})
    57  	for _, api := range apis {
    58  		if _, ok := availableSet[api.Namespace]; !ok {
    59  			availableSet[api.Namespace] = struct{}{}
    60  			available = append(available, api.Namespace)
    61  		}
    62  	}
    63  	for _, name := range modules {
    64  		if _, ok := availableSet[name]; !ok {
    65  			if name != rpc.MetadataApi && name != rpc.EngineApi {
    66  				bad = append(bad, name)
    67  			}
    68  		}
    69  	}
    70  	return bad, available
    71  }
    72  
    73  // CheckTimeouts ensures that timeout values are meaningful
    74  func CheckTimeouts(timeouts *rpc.HTTPTimeouts) {
    75  	if timeouts.ReadTimeout < time.Second {
    76  		log.Warn("Sanitizing invalid HTTP read timeout", "provided", timeouts.ReadTimeout, "updated", rpc.DefaultHTTPTimeouts.ReadTimeout)
    77  		timeouts.ReadTimeout = rpc.DefaultHTTPTimeouts.ReadTimeout
    78  	}
    79  	if timeouts.ReadHeaderTimeout < time.Second {
    80  		log.Warn("Sanitizing invalid HTTP read header timeout", "provided", timeouts.ReadHeaderTimeout, "updated", rpc.DefaultHTTPTimeouts.ReadHeaderTimeout)
    81  		timeouts.ReadHeaderTimeout = rpc.DefaultHTTPTimeouts.ReadHeaderTimeout
    82  	}
    83  	if timeouts.WriteTimeout < time.Second {
    84  		log.Warn("Sanitizing invalid HTTP write timeout", "provided", timeouts.WriteTimeout, "updated", rpc.DefaultHTTPTimeouts.WriteTimeout)
    85  		timeouts.WriteTimeout = rpc.DefaultHTTPTimeouts.WriteTimeout
    86  	}
    87  	if timeouts.IdleTimeout < time.Second {
    88  		log.Warn("Sanitizing invalid HTTP idle timeout", "provided", timeouts.IdleTimeout, "updated", rpc.DefaultHTTPTimeouts.IdleTimeout)
    89  		timeouts.IdleTimeout = rpc.DefaultHTTPTimeouts.IdleTimeout
    90  	}
    91  }