package server import ( "math/rand" "sync" "time" "github.com/gorilla/websocket" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" ) type Options struct { BindAddr string Timeout time.Duration } type messageSinkStore struct { sinks map[*websocket.Conn]*MessageSink mu sync.Mutex } func (ss *messageSinkStore) Put(conn *websocket.Conn, s *MessageSink) { ss.mu.Lock() defer ss.mu.Unlock() ss.sinks[conn] = s } func (ss *messageSinkStore) Get(conn *websocket.Conn) (*MessageSink, bool) { ss.mu.Lock() defer ss.mu.Unlock() s, ok := ss.sinks[conn] return s, ok } var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") func randSeq(n int) string { b := make([]rune, n) for i := range b { b[i] = letters[rand.Intn(len(letters))] } return string(b) } func Start(opts Options) error { e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) h := handler{ messageSinks: &messageSinkStore{ sinks: make(map[*websocket.Conn]*MessageSink), }, } // websockets provide their own custom CORS handler, so don't add further // middleware here. e.GET("/api/websocket", h.upgradeWebsocket) api := e.Group("/api") api.Use(middleware.TimeoutWithConfig(middleware.TimeoutConfig{Timeout: opts.Timeout})) api.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{"http://localhost:3000"}, AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept}, })) api.GET("/media_sets/:id", h.getMediaSet) api.GET("/media_sets/:id/peaks", h.getPeaks) api.GET("/media_sets/:id/thumbnails", h.getThumbnails) api.GET("/media_sets/:id/video", h.getVideo) return e.Start(opts.BindAddr) }