github.com/vipernet-xyz/tendermint-core@v0.32.0/lite2/proxy/proxy.go (about) 1 package proxy 2 3 import ( 4 "context" 5 "net" 6 "net/http" 7 8 "github.com/pkg/errors" 9 10 amino "github.com/tendermint/go-amino" 11 12 "github.com/tendermint/tendermint/libs/log" 13 tmpubsub "github.com/tendermint/tendermint/libs/pubsub" 14 lrpc "github.com/tendermint/tendermint/lite2/rpc" 15 ctypes "github.com/tendermint/tendermint/rpc/core/types" 16 rpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server" 17 ) 18 19 // A Proxy defines parameters for running an HTTP server proxy. 20 type Proxy struct { 21 Addr string // TCP address to listen on, ":http" if empty 22 Config *rpcserver.Config 23 Codec *amino.Codec 24 Client *lrpc.Client 25 Logger log.Logger 26 Listener net.Listener 27 } 28 29 // ListenAndServe configures the rpcserver.WebsocketManager, sets up the RPC 30 // routes to proxy via Client, and starts up an HTTP server on the TCP network 31 // address p.Addr. 32 // See http#Server#ListenAndServe. 33 func (p *Proxy) ListenAndServe() error { 34 listener, mux, err := p.listen() 35 if err != nil { 36 return err 37 } 38 p.Listener = listener 39 40 return rpcserver.Serve( 41 listener, 42 mux, 43 p.Logger, 44 p.Config, 45 ) 46 } 47 48 // ListenAndServeTLS acts identically to ListenAndServe, except that it expects 49 // HTTPS connections. 50 // See http#Server#ListenAndServeTLS. 51 func (p *Proxy) ListenAndServeTLS(certFile, keyFile string) error { 52 listener, mux, err := p.listen() 53 if err != nil { 54 return err 55 } 56 p.Listener = listener 57 58 return rpcserver.ServeTLS( 59 listener, 60 mux, 61 certFile, 62 keyFile, 63 p.Logger, 64 p.Config, 65 ) 66 } 67 68 func (p *Proxy) listen() (net.Listener, *http.ServeMux, error) { 69 ctypes.RegisterAmino(p.Codec) 70 71 mux := http.NewServeMux() 72 73 // 1) Register regular routes. 74 r := RPCRoutes(p.Client) 75 rpcserver.RegisterRPCFuncs(mux, r, p.Codec, p.Logger) 76 77 // 2) Allow websocket connections. 78 wmLogger := p.Logger.With("protocol", "websocket") 79 wm := rpcserver.NewWebsocketManager(r, p.Codec, 80 rpcserver.OnDisconnect(func(remoteAddr string) { 81 err := p.Client.UnsubscribeAll(context.Background(), remoteAddr) 82 if err != nil && err != tmpubsub.ErrSubscriptionNotFound { 83 wmLogger.Error("Failed to unsubscribe addr from events", "addr", remoteAddr, "err", err) 84 } 85 }), 86 rpcserver.ReadLimit(p.Config.MaxBodyBytes), 87 ) 88 wm.SetLogger(wmLogger) 89 mux.HandleFunc("/websocket", wm.WebsocketHandler) 90 91 // 3) Start a client. 92 if !p.Client.IsRunning() { 93 if err := p.Client.Start(); err != nil { 94 return nil, mux, errors.Wrap(err, "Client#Start") 95 } 96 } 97 98 // 4) Start listening for new connections. 99 listener, err := rpcserver.Listen(p.Addr, p.Config) 100 if err != nil { 101 return nil, mux, err 102 } 103 104 return listener, mux, nil 105 }