mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
bind-ipc (#8590)
This commit is contained in:
parent
216f20d5f8
commit
60b3f1e7f0
@ -117,7 +117,7 @@ If the healthcheck is successful it will return a 200 status code.
|
||||
If the healthcheck fails for any reason a status 500 will be returned. This is true if one of the criteria requested
|
||||
fails its check.
|
||||
|
||||
You can set any number of values on the `X-ERIGON-HEALTHCHECK` header. Ones that are not included are skipped in the
|
||||
You can set any number of values on the `X-ERIGON-HEALTHCHECK` header. Ones that are not included are skipped in the
|
||||
checks.
|
||||
|
||||
Available Options:
|
||||
@ -186,6 +186,24 @@ By default data pruned after 90K blocks, can change it by flags like `--prune.hi
|
||||
|
||||
Some methods, if not found historical data in DB, can fallback to old blocks re-execution - but it requires `h`.
|
||||
|
||||
### The --http.url flag
|
||||
|
||||
the `--http.url` flag is an optional flag which allows one to bind the HTTP server to a socket, for example, `tcp6://:8545` or `unix:///erigon_http.socket`
|
||||
|
||||
If the `--http.url` flag is set, then `--http.addr` and `--http.port` with both be ignored.
|
||||
|
||||
note that this is NOT geth-style IPC. for that, read the next section, IPC endpoint(geth-compatible)
|
||||
|
||||
### IPC endpoint (geth compatible)
|
||||
|
||||
erigon supports the geth-style unix socket IPC. you can enable this with `--socket.enabled` flag,
|
||||
and setting the `--socket.url` flag. For instance, if you wanted the socket to exist at `/var/run/erigon.ipc`,
|
||||
you would do `--socket.url=unix:///var/run/erigon.ipc`
|
||||
|
||||
you can also use `--socket.url=tcp://<addr>:<port>` to serve the raw jsonrpc2 protocol over tcp
|
||||
|
||||
the socket will inherit the namespaces from `http.api`
|
||||
|
||||
### RPC Implementation Status
|
||||
|
||||
Label "remote" means: `--private.api.addr` flag is required.
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@ -92,15 +93,9 @@ func RootCommand() (*cobra.Command, *httpcfg.HttpCfg) {
|
||||
rootCmd.PersistentFlags().StringVar(&cfg.TLSCertfile, "tls.cert", "", "certificate for client side TLS handshake")
|
||||
rootCmd.PersistentFlags().StringVar(&cfg.TLSKeyFile, "tls.key", "", "key file for client side TLS handshake")
|
||||
rootCmd.PersistentFlags().StringVar(&cfg.TLSCACert, "tls.cacert", "", "CA certificate for client side TLS handshake")
|
||||
rootCmd.PersistentFlags().IntVar(&cfg.HttpPort, "http.port", nodecfg.DefaultHTTPPort, "HTTP-RPC server listening port")
|
||||
rootCmd.PersistentFlags().StringSliceVar(&cfg.HttpCORSDomain, "http.corsdomain", []string{}, "Comma separated list of domains from which to accept cross origin requests (browser enforced)")
|
||||
rootCmd.PersistentFlags().StringSliceVar(&cfg.HttpVirtualHost, "http.vhosts", nodecfg.DefaultConfig.HTTPVirtualHosts, "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.")
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.HttpCompression, "http.compression", true, "Disable http compression")
|
||||
rootCmd.PersistentFlags().StringSliceVar(&cfg.API, "http.api", []string{"eth", "erigon"}, "API's offered over the HTTP-RPC interface: eth,erigon,web3,net,debug,trace,txpool,db. Supported methods: https://github.com/ledgerwatch/erigon/tree/devel/cmd/rpcdaemon")
|
||||
rootCmd.PersistentFlags().Uint64Var(&cfg.Gascap, "rpc.gascap", 50_000_000, "Sets a cap on gas that can be used in eth_call/estimateGas")
|
||||
rootCmd.PersistentFlags().Uint64Var(&cfg.MaxTraces, "trace.maxtraces", 200, "Sets a limit on traces that can be returned in trace_filter")
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.WebsocketEnabled, "ws", false, "Enable Websockets - Same port as HTTP")
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.WebsocketCompression, "ws.compression", false, "Enable Websocket compression (RFC 7692)")
|
||||
|
||||
rootCmd.PersistentFlags().StringVar(&cfg.RpcAllowListFilePath, utils.RpcAccessListFlag.Name, "", "Specify granular (method-by-method) API allowlist")
|
||||
rootCmd.PersistentFlags().UintVar(&cfg.RpcBatchConcurrency, utils.RpcBatchConcurrencyFlag.Name, 2, utils.RpcBatchConcurrencyFlag.Usage)
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.RpcStreamingDisable, utils.RpcStreamingDisableFlag.Name, false, utils.RpcStreamingDisableFlag.Usage)
|
||||
@ -108,6 +103,7 @@ func RootCommand() (*cobra.Command, *httpcfg.HttpCfg) {
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.TraceCompatibility, "trace.compat", false, "Bug for bug compatibility with OE for trace_ routines")
|
||||
rootCmd.PersistentFlags().StringVar(&cfg.TxPoolApiAddr, "txpool.api.addr", "", "txpool api network address, for example: 127.0.0.1:9090 (default: use value of --private.api.addr)")
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.Sync.UseSnapshots, "snapshot", true, utils.SnapshotFlag.Usage)
|
||||
|
||||
rootCmd.PersistentFlags().StringVar(&stateCacheStr, "state.cache", "0MB", "Amount of data to store in StateCache (enabled if no --datadir set). Set 0 to disable StateCache. Defaults to 0MB RAM")
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.GRPCServerEnabled, "grpc", false, "Enable GRPC server")
|
||||
rootCmd.PersistentFlags().StringVar(&cfg.GRPCListenAddress, "grpc.addr", nodecfg.DefaultGRPCHost, "GRPC server listening interface")
|
||||
@ -115,9 +111,18 @@ func RootCommand() (*cobra.Command, *httpcfg.HttpCfg) {
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.GRPCHealthCheckEnabled, "grpc.healthcheck", false, "Enable GRPC health check")
|
||||
rootCmd.PersistentFlags().Float64Var(ðconfig.Defaults.RPCTxFeeCap, utils.RPCGlobalTxFeeCapFlag.Name, utils.RPCGlobalTxFeeCapFlag.Value, utils.RPCGlobalTxFeeCapFlag.Usage)
|
||||
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.TCPServerEnabled, "tcp", false, "Enable TCP server")
|
||||
rootCmd.PersistentFlags().StringVar(&cfg.TCPListenAddress, "tcp.addr", nodecfg.DefaultTCPHost, "TCP server listening interface")
|
||||
rootCmd.PersistentFlags().IntVar(&cfg.TCPPort, "tcp.port", nodecfg.DefaultTCPPort, "TCP server listening port")
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.HttpServerEnabled, "http.enabled", true, "enable http server")
|
||||
rootCmd.PersistentFlags().StringVar(&cfg.HttpURL, "http.url", "", "HTTP server listening url. will OVERRIDE http.addr and http.port. will NOT respect http paths. prefix supported are tcp, unix")
|
||||
rootCmd.PersistentFlags().IntVar(&cfg.HttpPort, "http.port", nodecfg.DefaultHTTPPort, "HTTP-RPC server listening port")
|
||||
rootCmd.PersistentFlags().StringSliceVar(&cfg.HttpCORSDomain, "http.corsdomain", []string{}, "Comma separated list of domains from which to accept cross origin requests (browser enforced)")
|
||||
rootCmd.PersistentFlags().StringSliceVar(&cfg.HttpVirtualHost, "http.vhosts", nodecfg.DefaultConfig.HTTPVirtualHosts, "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.")
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.HttpCompression, "http.compression", true, "Disable http compression")
|
||||
rootCmd.PersistentFlags().StringSliceVar(&cfg.API, "http.api", []string{"eth", "erigon"}, "API's offered over the HTTP-RPC interface: eth,erigon,web3,net,debug,trace,txpool,db. Supported methods: https://github.com/ledgerwatch/erigon/tree/devel/cmd/rpcdaemon")
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.WebsocketEnabled, "ws", false, "Enable Websockets - Same port as HTTP")
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.WebsocketCompression, "ws.compression", false, "Enable Websocket compression (RFC 7692)")
|
||||
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.SocketServerEnabled, "socket.enabled", false, "Enable IPC server")
|
||||
rootCmd.PersistentFlags().StringVar(&cfg.SocketListenUrl, "socket.url", "unix:///var/run/erigon.sock", "IPC server listening url. prefix supported are tcp, unix")
|
||||
|
||||
rootCmd.PersistentFlags().BoolVar(&cfg.TraceRequests, utils.HTTPTraceFlag.Name, false, "Trace HTTP requests with INFO level")
|
||||
rootCmd.PersistentFlags().DurationVar(&cfg.HTTPTimeouts.ReadTimeout, "http.timeouts.read", rpccfg.DefaultHTTPTimeouts.ReadTimeout, "Maximum duration for reading the entire request, including the body.")
|
||||
@ -546,7 +551,6 @@ func StartRpcServerWithJwtAuthentication(ctx context.Context, cfg httpcfg.HttpCf
|
||||
|
||||
func startRegularRpcServer(ctx context.Context, cfg httpcfg.HttpCfg, rpcAPI []rpc.API, logger log.Logger) error {
|
||||
// register apis and create handler stack
|
||||
httpEndpoint := fmt.Sprintf("%s:%d", cfg.HttpListenAddress, cfg.HttpPort)
|
||||
|
||||
srv := rpc.NewServer(cfg.RpcBatchConcurrency, cfg.TraceRequests, cfg.RpcStreamingDisable, logger)
|
||||
|
||||
@ -558,6 +562,8 @@ func startRegularRpcServer(ctx context.Context, cfg httpcfg.HttpCfg, rpcAPI []rp
|
||||
|
||||
srv.SetBatchLimit(cfg.BatchLimit)
|
||||
|
||||
defer srv.Stop()
|
||||
|
||||
var defaultAPIList []rpc.API
|
||||
|
||||
for _, api := range rpcAPI {
|
||||
@ -577,43 +583,61 @@ func startRegularRpcServer(ctx context.Context, cfg httpcfg.HttpCfg, rpcAPI []rp
|
||||
return fmt.Errorf("could not start register RPC apis: %w", err)
|
||||
}
|
||||
|
||||
httpHandler := node.NewHTTPHandlerStack(srv, cfg.HttpCORSDomain, cfg.HttpVirtualHost, cfg.HttpCompression)
|
||||
var wsHandler http.Handler
|
||||
if cfg.WebsocketEnabled {
|
||||
wsHandler = srv.WebsocketHandler([]string{"*"}, nil, cfg.WebsocketCompression, logger)
|
||||
info := []interface{}{
|
||||
"ws", cfg.WebsocketEnabled,
|
||||
"ws.compression", cfg.WebsocketCompression, "grpc", cfg.GRPCServerEnabled,
|
||||
}
|
||||
|
||||
graphQLHandler := graphql.CreateHandler(defaultAPIList)
|
||||
|
||||
apiHandler, err := createHandler(cfg, defaultAPIList, httpHandler, wsHandler, graphQLHandler, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
listener, httpAddr, err := node.StartHTTPEndpoint(httpEndpoint, cfg.HTTPTimeouts, apiHandler)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not start RPC api: %w", err)
|
||||
}
|
||||
|
||||
if cfg.TCPServerEnabled {
|
||||
tcpEndpoint := fmt.Sprintf("%s:%d", cfg.TCPListenAddress, cfg.TCPPort)
|
||||
tcpListener, err := net.Listen("tcp", tcpEndpoint)
|
||||
if cfg.SocketServerEnabled {
|
||||
socketUrl, err := url.Parse(cfg.SocketListenUrl)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not start TCP Listener: %w", err)
|
||||
return fmt.Errorf("malformatted socket url %s: %w", cfg.SocketListenUrl, err)
|
||||
}
|
||||
tcpListener, err := net.Listen(socketUrl.Scheme, socketUrl.Host+socketUrl.EscapedPath())
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not start Socket Listener: %w", err)
|
||||
}
|
||||
defer tcpListener.Close()
|
||||
go func() {
|
||||
defer tcpListener.Close()
|
||||
err := srv.ServeListener(tcpListener)
|
||||
if err != nil {
|
||||
logger.Error("TCP Listener Fatal Error", "err", err)
|
||||
if !errors.Is(err, net.ErrClosed) {
|
||||
logger.Error("Socket Listener Fatal Error", "err", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
logger.Info("TCP Endpoint opened", "url", tcpEndpoint)
|
||||
info = append(info, "socket.url", socketUrl)
|
||||
logger.Info("Socket Endpoint opened", "url", socketUrl)
|
||||
}
|
||||
|
||||
info := []interface{}{
|
||||
"url", httpAddr, "ws", cfg.WebsocketEnabled,
|
||||
"ws.compression", cfg.WebsocketCompression, "grpc", cfg.GRPCServerEnabled,
|
||||
if cfg.HttpServerEnabled {
|
||||
httpHandler := node.NewHTTPHandlerStack(srv, cfg.HttpCORSDomain, cfg.HttpVirtualHost, cfg.HttpCompression)
|
||||
var wsHandler http.Handler
|
||||
if cfg.WebsocketEnabled {
|
||||
wsHandler = srv.WebsocketHandler([]string{"*"}, nil, cfg.WebsocketCompression, logger)
|
||||
}
|
||||
|
||||
graphQLHandler := graphql.CreateHandler(defaultAPIList)
|
||||
|
||||
apiHandler, err := createHandler(cfg, defaultAPIList, httpHandler, wsHandler, graphQLHandler, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
httpEndpoint := fmt.Sprintf("tcp://%s:%d", cfg.HttpListenAddress, cfg.HttpPort)
|
||||
if cfg.HttpURL != "" {
|
||||
httpEndpoint = cfg.HttpURL
|
||||
}
|
||||
listener, httpAddr, err := node.StartHTTPEndpoint(httpEndpoint, cfg.HTTPTimeouts, apiHandler)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not start RPC api: %w", err)
|
||||
}
|
||||
info = append(info, "http.url", httpAddr)
|
||||
defer func() {
|
||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
_ = listener.Shutdown(shutdownCtx)
|
||||
logger.Info("HTTP endpoint closed", "url", httpAddr)
|
||||
}()
|
||||
}
|
||||
|
||||
var (
|
||||
@ -634,26 +658,20 @@ func startRegularRpcServer(ctx context.Context, cfg httpcfg.HttpCfg, rpcAPI []rp
|
||||
}
|
||||
go grpcServer.Serve(grpcListener)
|
||||
info = append(info, "grpc.port", cfg.GRPCPort)
|
||||
|
||||
defer func() {
|
||||
if cfg.GRPCServerEnabled {
|
||||
if cfg.GRPCHealthCheckEnabled {
|
||||
healthServer.Shutdown()
|
||||
}
|
||||
grpcServer.GracefulStop()
|
||||
_ = grpcListener.Close()
|
||||
logger.Info("GRPC endpoint closed", "url", grpcEndpoint)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
logger.Info("HTTP endpoint opened", info...)
|
||||
|
||||
defer func() {
|
||||
srv.Stop()
|
||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
_ = listener.Shutdown(shutdownCtx)
|
||||
logger.Info("HTTP endpoint closed", "url", httpAddr)
|
||||
|
||||
if cfg.GRPCServerEnabled {
|
||||
if cfg.GRPCHealthCheckEnabled {
|
||||
healthServer.Shutdown()
|
||||
}
|
||||
grpcServer.GracefulStop()
|
||||
_ = grpcListener.Close()
|
||||
logger.Info("GRPC endpoint closed", "url", grpcEndpoint)
|
||||
}
|
||||
}()
|
||||
logger.Info("JsonRpc endpoint opened", info...)
|
||||
<-ctx.Done()
|
||||
logger.Info("Exiting...")
|
||||
return nil
|
||||
@ -755,7 +773,7 @@ func createHandler(cfg httpcfg.HttpCfg, apiList []rpc.API, httpHandler http.Hand
|
||||
}
|
||||
|
||||
func createEngineListener(cfg httpcfg.HttpCfg, engineApi []rpc.API, logger log.Logger) (*http.Server, *rpc.Server, string, error) {
|
||||
engineHttpEndpoint := fmt.Sprintf("%s:%d", cfg.AuthRpcHTTPListenAddress, cfg.AuthRpcPort)
|
||||
engineHttpEndpoint := fmt.Sprintf("tcp://%s:%d", cfg.AuthRpcHTTPListenAddress, cfg.AuthRpcPort)
|
||||
|
||||
engineSrv := rpc.NewServer(cfg.RpcBatchConcurrency, cfg.TraceRequests, true, logger)
|
||||
|
||||
|
21
cmd/rpcdaemon/cli/config_test.go
Normal file
21
cmd/rpcdaemon/cli/config_test.go
Normal file
@ -0,0 +1,21 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestParseSocketUrl(t *testing.T) {
|
||||
t.Run("sock", func(t *testing.T) {
|
||||
socketUrl, err := url.Parse("unix:///some/file/path.sock")
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, "/some/file/path.sock", socketUrl.Host+socketUrl.EscapedPath())
|
||||
})
|
||||
t.Run("sock", func(t *testing.T) {
|
||||
socketUrl, err := url.Parse("tcp://localhost:1234")
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, "localhost:1234", socketUrl.Host+socketUrl.EscapedPath())
|
||||
})
|
||||
}
|
@ -10,37 +10,43 @@ import (
|
||||
)
|
||||
|
||||
type HttpCfg struct {
|
||||
Enabled bool
|
||||
PrivateApiAddr string
|
||||
Enabled bool
|
||||
|
||||
GraphQLEnabled bool
|
||||
WithDatadir bool // Erigon's database can be read by separated processes on same machine - in read-only mode - with full support of transactions. It will share same "OS PageCache" with Erigon process.
|
||||
DataDir string
|
||||
Dirs datadir.Dirs
|
||||
HttpListenAddress string
|
||||
AuthRpcHTTPListenAddress string
|
||||
TLSCertfile string
|
||||
TLSCACert string
|
||||
TLSKeyFile string
|
||||
HttpPort int
|
||||
AuthRpcPort int
|
||||
HttpCORSDomain []string
|
||||
HttpVirtualHost []string
|
||||
AuthRpcVirtualHost []string
|
||||
HttpCompression bool
|
||||
API []string
|
||||
Gascap uint64
|
||||
MaxTraces uint64
|
||||
WebsocketEnabled bool
|
||||
WebsocketCompression bool
|
||||
RpcAllowListFilePath string
|
||||
RpcBatchConcurrency uint
|
||||
RpcStreamingDisable bool
|
||||
DBReadConcurrency int
|
||||
TraceCompatibility bool // Bug for bug compatibility for trace_ routines with OpenEthereum
|
||||
TxPoolApiAddr string
|
||||
StateCache kvcache.CoherentConfig
|
||||
Snap ethconfig.BlocksFreezing
|
||||
Sync ethconfig.Sync
|
||||
|
||||
HttpServerEnabled bool
|
||||
HttpURL string
|
||||
HttpListenAddress string
|
||||
HttpPort int
|
||||
HttpCORSDomain []string
|
||||
HttpVirtualHost []string
|
||||
AuthRpcVirtualHost []string
|
||||
HttpCompression bool
|
||||
|
||||
AuthRpcPort int
|
||||
PrivateApiAddr string
|
||||
|
||||
API []string
|
||||
Gascap uint64
|
||||
MaxTraces uint64
|
||||
WebsocketEnabled bool
|
||||
WebsocketCompression bool
|
||||
RpcAllowListFilePath string
|
||||
RpcBatchConcurrency uint
|
||||
RpcStreamingDisable bool
|
||||
DBReadConcurrency int
|
||||
TraceCompatibility bool // Bug for bug compatibility for trace_ routines with OpenEthereum
|
||||
TxPoolApiAddr string
|
||||
StateCache kvcache.CoherentConfig
|
||||
Snap ethconfig.BlocksFreezing
|
||||
Sync ethconfig.Sync
|
||||
|
||||
// GRPC server
|
||||
GRPCServerEnabled bool
|
||||
@ -48,10 +54,9 @@ type HttpCfg struct {
|
||||
GRPCPort int
|
||||
GRPCHealthCheckEnabled bool
|
||||
|
||||
// Raw TCP Server
|
||||
TCPServerEnabled bool
|
||||
TCPListenAddress string
|
||||
TCPPort int
|
||||
// Socket Server
|
||||
SocketServerEnabled bool
|
||||
SocketListenUrl string
|
||||
|
||||
JWTSecretPath string // Engine API Authentication
|
||||
TraceRequests bool // Always trace requests in INFO level
|
||||
|
@ -20,13 +20,14 @@ package utils
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"fmt"
|
||||
"github.com/ledgerwatch/erigon/cl/clparams"
|
||||
"math/big"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/ledgerwatch/erigon/cl/clparams"
|
||||
|
||||
"github.com/c2h5oh/datasize"
|
||||
"github.com/ledgerwatch/erigon-lib/chain/networkname"
|
||||
"github.com/ledgerwatch/erigon-lib/chain/snapcfg"
|
||||
|
@ -19,8 +19,10 @@ package node
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
@ -30,13 +32,17 @@ import (
|
||||
)
|
||||
|
||||
// StartHTTPEndpoint starts the HTTP RPC endpoint.
|
||||
func StartHTTPEndpoint(endpoint string, timeouts rpccfg.HTTPTimeouts, handler http.Handler) (*http.Server, net.Addr, error) {
|
||||
func StartHTTPEndpoint(urlEndpoint string, timeouts rpccfg.HTTPTimeouts, handler http.Handler) (*http.Server, net.Addr, error) {
|
||||
// start the HTTP listener
|
||||
var (
|
||||
listener net.Listener
|
||||
err error
|
||||
)
|
||||
if listener, err = net.Listen("tcp", endpoint); err != nil {
|
||||
socketUrl, err := url.Parse(urlEndpoint)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("malformatted http listen url %s: %w", urlEndpoint, err)
|
||||
}
|
||||
if listener, err = net.Listen(socketUrl.Scheme, socketUrl.Host+socketUrl.EscapedPath()); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// make sure timeout values are meaningful
|
||||
|
Loading…
Reference in New Issue
Block a user