2018-02-23 02:25:25 -08:00
|
|
|
package lcd
|
|
|
|
|
|
|
|
import (
|
2018-11-08 16:41:57 -08:00
|
|
|
"fmt"
|
|
|
|
"net"
|
2019-05-28 06:46:26 -07:00
|
|
|
"net/http"
|
2018-11-08 16:41:57 -08:00
|
|
|
"os"
|
2019-05-07 10:04:48 -07:00
|
|
|
"time"
|
2018-11-08 16:41:57 -08:00
|
|
|
|
2020-02-21 03:17:27 -08:00
|
|
|
"github.com/gorilla/handlers"
|
2018-07-09 11:52:24 -07:00
|
|
|
"github.com/gorilla/mux"
|
2019-05-28 06:46:26 -07:00
|
|
|
"github.com/rakyll/statik/fs"
|
2018-07-09 11:52:24 -07:00
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/spf13/viper"
|
|
|
|
"github.com/tendermint/tendermint/libs/log"
|
2020-05-28 07:46:28 -07:00
|
|
|
tmrpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server"
|
2018-11-19 09:02:34 -08:00
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/client"
|
2019-05-28 01:44:04 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
2018-12-10 06:27:25 -08:00
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
|
|
"github.com/cosmos/cosmos-sdk/server"
|
2019-05-28 06:46:26 -07:00
|
|
|
|
|
|
|
// unnamed import of statik for swagger UI support
|
|
|
|
_ "github.com/cosmos/cosmos-sdk/client/lcd/statik"
|
2018-02-23 02:25:25 -08:00
|
|
|
)
|
|
|
|
|
2018-11-16 14:21:36 -08:00
|
|
|
// RestServer represents the Light Client Rest server
|
|
|
|
type RestServer struct {
|
2020-06-01 05:46:03 -07:00
|
|
|
Mux *mux.Router
|
|
|
|
ClientCtx client.Context
|
2018-02-23 02:25:25 -08:00
|
|
|
|
2019-06-21 08:18:01 -07:00
|
|
|
log log.Logger
|
|
|
|
listener net.Listener
|
2018-11-16 14:21:36 -08:00
|
|
|
}
|
2018-06-11 18:12:37 -07:00
|
|
|
|
2018-11-16 14:21:36 -08:00
|
|
|
// NewRestServer creates a new rest server instance
|
|
|
|
func NewRestServer(cdc *codec.Codec) *RestServer {
|
|
|
|
r := mux.NewRouter()
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx := client.NewContext().WithCodec(cdc)
|
2018-11-16 14:21:36 -08:00
|
|
|
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "rest-server")
|
2018-07-09 11:52:24 -07:00
|
|
|
|
2018-11-16 14:21:36 -08:00
|
|
|
return &RestServer{
|
2020-06-01 05:46:03 -07:00
|
|
|
Mux: r,
|
|
|
|
ClientCtx: clientCtx,
|
|
|
|
log: logger,
|
2018-11-16 14:21:36 -08:00
|
|
|
}
|
2018-02-23 02:25:25 -08:00
|
|
|
}
|
2018-02-28 23:16:54 -08:00
|
|
|
|
2020-05-07 10:49:08 -07:00
|
|
|
// StartWithConfig starts the REST server that listens on the provided listenAddr.
|
|
|
|
// It will use the provided RPC configuration.
|
2020-05-28 07:46:28 -07:00
|
|
|
func (rs *RestServer) StartWithConfig(listenAddr string, cors bool, cfg *tmrpcserver.Config) error {
|
2018-11-16 14:21:36 -08:00
|
|
|
server.TrapSignal(func() {
|
|
|
|
err := rs.listener.Close()
|
|
|
|
rs.log.Error("error closing listener", "err", err)
|
|
|
|
})
|
|
|
|
|
2020-05-28 07:46:28 -07:00
|
|
|
listener, err := tmrpcserver.Listen(listenAddr, cfg)
|
2019-01-17 05:06:33 -08:00
|
|
|
if err != nil {
|
2020-05-07 10:49:08 -07:00
|
|
|
return err
|
2019-01-17 05:06:33 -08:00
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2020-05-07 10:49:08 -07:00
|
|
|
rs.listener = listener
|
|
|
|
|
2019-03-29 10:13:45 -07:00
|
|
|
rs.log.Info(
|
2020-05-07 10:49:08 -07:00
|
|
|
fmt.Sprintf("Starting application REST service (chain-id: %q)...", viper.GetString(flags.FlagChainID)),
|
2019-03-29 10:13:45 -07:00
|
|
|
)
|
2019-01-17 05:06:33 -08:00
|
|
|
|
2020-02-21 03:17:27 -08:00
|
|
|
var h http.Handler = rs.Mux
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2020-02-21 03:17:27 -08:00
|
|
|
if cors {
|
2020-05-28 07:46:28 -07:00
|
|
|
return tmrpcserver.Serve(rs.listener, handlers.CORS()(h), rs.log, cfg)
|
2020-02-21 03:17:27 -08:00
|
|
|
}
|
|
|
|
|
2020-05-28 07:46:28 -07:00
|
|
|
return tmrpcserver.Serve(rs.listener, rs.Mux, rs.log, cfg)
|
2018-11-16 14:21:36 -08:00
|
|
|
}
|
2018-09-13 05:30:24 -07:00
|
|
|
|
2020-05-07 10:49:08 -07:00
|
|
|
// Start starts the REST server that listens on the provided listenAddr. The REST
|
|
|
|
// service will use Tendermint's default RPC configuration, where the R/W timeout
|
|
|
|
// and max open connections are overridden.
|
|
|
|
func (rs *RestServer) Start(listenAddr string, maxOpen int, readTimeout, writeTimeout uint, cors bool) error {
|
2020-05-28 07:46:28 -07:00
|
|
|
cfg := tmrpcserver.DefaultConfig()
|
2020-05-07 10:49:08 -07:00
|
|
|
cfg.MaxOpenConnections = maxOpen
|
|
|
|
cfg.ReadTimeout = time.Duration(readTimeout) * time.Second
|
|
|
|
cfg.WriteTimeout = time.Duration(writeTimeout) * time.Second
|
|
|
|
|
|
|
|
return rs.StartWithConfig(listenAddr, cors, cfg)
|
|
|
|
}
|
|
|
|
|
2019-05-18 01:42:24 -07:00
|
|
|
// ServeCommand will start the application REST service as a blocking process. It
|
2018-11-27 13:03:53 -08:00
|
|
|
// takes a codec to create a RestServer object and a function to register all
|
|
|
|
// necessary routes.
|
|
|
|
func ServeCommand(cdc *codec.Codec, registerRoutesFn func(*RestServer)) *cobra.Command {
|
2018-11-16 14:21:36 -08:00
|
|
|
cmd := &cobra.Command{
|
|
|
|
Use: "rest-server",
|
|
|
|
Short: "Start LCD (light-client daemon), a local REST server",
|
|
|
|
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
2018-11-27 13:03:53 -08:00
|
|
|
rs := NewRestServer(cdc)
|
|
|
|
|
|
|
|
registerRoutesFn(rs)
|
2019-05-28 06:46:26 -07:00
|
|
|
rs.registerSwaggerUI()
|
2018-11-27 13:03:53 -08:00
|
|
|
|
2020-05-28 07:46:28 -07:00
|
|
|
cfg := tmrpcserver.DefaultConfig()
|
2020-05-07 10:49:08 -07:00
|
|
|
cfg.MaxOpenConnections = viper.GetInt(flags.FlagMaxOpenConnections)
|
|
|
|
cfg.ReadTimeout = time.Duration(viper.GetInt64(flags.FlagRPCReadTimeout)) * time.Second
|
|
|
|
cfg.WriteTimeout = time.Duration(viper.GetInt64(flags.FlagRPCWriteTimeout)) * time.Second
|
|
|
|
cfg.MaxBodyBytes = viper.GetInt64(flags.FlagRPCMaxBodyBytes)
|
|
|
|
|
|
|
|
// start the rest server and return error if one exists
|
|
|
|
return rs.StartWithConfig(
|
2019-05-28 01:44:04 -07:00
|
|
|
viper.GetString(flags.FlagListenAddr),
|
2020-02-21 03:17:27 -08:00
|
|
|
viper.GetBool(flags.FlagUnsafeCORS),
|
2020-05-07 10:49:08 -07:00
|
|
|
cfg,
|
2019-05-07 10:04:48 -07:00
|
|
|
)
|
2018-11-16 14:21:36 -08:00
|
|
|
},
|
|
|
|
}
|
2018-09-13 05:30:24 -07:00
|
|
|
|
2019-05-28 01:44:04 -07:00
|
|
|
return flags.RegisterRestServerFlags(cmd)
|
2018-09-13 23:14:16 -07:00
|
|
|
}
|
2019-05-28 06:46:26 -07:00
|
|
|
|
|
|
|
func (rs *RestServer) registerSwaggerUI() {
|
|
|
|
statikFS, err := fs.New()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2019-05-28 06:46:26 -07:00
|
|
|
staticServer := http.FileServer(statikFS)
|
2020-02-13 09:08:34 -08:00
|
|
|
rs.Mux.PathPrefix("/").Handler(staticServer)
|
2019-05-28 06:46:26 -07:00
|
|
|
}
|