package server import ( "fmt" "net" echologrus "github.com/cemkiy/echo-logrus" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" "github.com/sirupsen/logrus" "git.maze.io/ham/hamview/schema" ) const DefaultServerListen = ":8073" // Config holds the server configuration type Config struct { Listen string `yaml:"listen"` } // DatabaseConfig holds database configuration type DatabaseConfig struct { Type string `yaml:"type"` Conf string `yaml:"conf"` } // Server represents the HTTP server type Server struct { listen string listenAddr *net.TCPAddr logger *logrus.Logger } // New creates a new Server instance func New(serverConfig *Config, databaseConfig *DatabaseConfig, logger *logrus.Logger) (*Server, error) { if serverConfig.Listen == "" { serverConfig.Listen = DefaultServerListen } listenAddr, err := net.ResolveTCPAddr("tcp", serverConfig.Listen) if err != nil { return nil, fmt.Errorf("hamview: invalid listen address %q: %v", serverConfig.Listen, err) } if err = schema.Open(databaseConfig.Type, databaseConfig.Conf); err != nil { return nil, err } return &Server{ listen: serverConfig.Listen, listenAddr: listenAddr, logger: logger, }, nil } // Run starts the HTTP server func (s *Server) Run() error { echologrus.Logger = s.logger e := echo.New() e.HideBanner = true e.Logger = echologrus.GetEchoLogger() e.Use(echologrus.Hook()) e.Use(middleware.RequestLogger()) e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{"*"}, AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept}, })) // Static files e.File("/", "./dashboard/dist/index.html") e.Static("/asset/", "./asset") e.Static("/assets/", "./dashboard/dist/assets") // Setup API routes setupRoutes(s, e) if s.listenAddr.IP == nil || s.listenAddr.IP.Equal(net.ParseIP("0.0.0.0")) || s.listenAddr.IP.Equal(net.ParseIP("::")) { s.logger.Infof("server: listening on http://127.0.0.1:%d", s.listenAddr.Port) } else { s.logger.Infof("server: listening on http://%s:%d", s.listenAddr.IP, s.listenAddr.Port) } return e.Start(s.listen) } // NewTestServer creates a server for testing with an in-memory SQLite database func NewTestServer(logger *logrus.Logger) (*Server, error) { serverConfig := &Config{ Listen: "127.0.0.1:0", } databaseConfig := &DatabaseConfig{ Type: "sqlite3", Conf: ":memory:", } return New(serverConfig, databaseConfig, logger) }