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