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