From 8e0623ee4564c9e40c6cee79553d0719005ea990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Sun, 27 Feb 2022 13:57:11 +0100 Subject: [PATCH] add optional path prefix. --- docs/README.md | 8 ++++++++ internal/config/room.go | 11 +++++++++-- internal/http/manager.go | 7 ++++--- internal/room/manager.go | 25 +++++++++++++------------ neko.go | 1 + 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/docs/README.md b/docs/README.md index 04fdd09..b7815fa 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,3 +11,11 @@ All clients visit `https://neko-rooms/room-name/`. Once they logged in, they get ## Connection timeout Neko room loads but you don't see the screen and it gives you `connection timeout` or `disconnected error`? [Validate](https://neko.m1k1o.net/#/getting-started/troubleshooting?id=validate-udp-ports-reachability) that your UDP ports are reachable. + +## path prefix + +Room names are by default put to root directory. If you want to have custom path prefix, you can specify it using evn variable: + +``` +NEKO_ROOMS_INSTANCE_PATH_PREFIX=/test/ +``` diff --git a/internal/config/room.go b/internal/config/room.go index 404ae5a..f07b415 100644 --- a/internal/config/room.go +++ b/internal/config/room.go @@ -24,8 +24,9 @@ type Room struct { MountsWhitelist []string - InstanceName string - InstanceUrl string + InstanceName string + InstanceUrl string + InstancePathPrefix string TraefikDomain string TraefikEntrypoint string @@ -95,6 +96,11 @@ func (Room) Init(cmd *cobra.Command) error { return err } + cmd.PersistentFlags().String("instance.path_prefix", "", "path prefix that is added to a room path") + if err := viper.BindPFlag("instance.path_prefix", cmd.PersistentFlags().Lookup("instance.path_prefix")); err != nil { + return err + } + // Traefik cmd.PersistentFlags().String("traefik.domain", "", "traefik: domain on which will be container hosted (if empty or '*', match all; for neko-rooms as subdomain use '*.domain.tld')") @@ -184,6 +190,7 @@ func (s *Room) Set() { } s.InstanceUrl = viper.GetString("instance.url") + s.InstancePathPrefix = viper.GetString("instance.path_prefix") s.TraefikDomain = viper.GetString("traefik.domain") s.TraefikEntrypoint = viper.GetString("traefik.entrypoint") diff --git a/internal/http/manager.go b/internal/http/manager.go index d0090a9..12a544f 100644 --- a/internal/http/manager.go +++ b/internal/http/manager.go @@ -4,6 +4,7 @@ import ( "context" "net/http" "os" + "path" "github.com/go-chi/chi" "github.com/go-chi/chi/middleware" @@ -22,7 +23,7 @@ type HttpManagerCtx struct { conf *config.Server } -func New(ApiManager types.ApiManager, conf *config.Server) *HttpManagerCtx { +func New(ApiManager types.ApiManager, pathPrefix string, conf *config.Server) *HttpManagerCtx { logger := log.With().Str("module", "http").Logger() router := chi.NewRouter() @@ -54,8 +55,8 @@ func New(ApiManager types.ApiManager, conf *config.Server) *HttpManagerCtx { } // add simple lobby room - router.Get("/{roomName}", ApiManager.RoomLobby) - router.Get("/{roomName}/", ApiManager.RoomLobby) + router.Get(path.Join("/", pathPrefix, "{roomName}"), ApiManager.RoomLobby) + router.Get(path.Join("/", pathPrefix, "{roomName}")+"/", ApiManager.RoomLobby) router.NotFound(http.HandlerFunc(http.NotFound)) diff --git a/internal/room/manager.go b/internal/room/manager.go index 33cb5b0..2eb4735 100644 --- a/internal/room/manager.go +++ b/internal/room/manager.go @@ -149,9 +149,10 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro // containerName := manager.config.InstanceName + "-" + roomName + pathPrefix := path.Join("/", manager.config.InstancePathPrefix, roomName) // create traefik rule - traefikRule := "PathPrefix(`/" + roomName + "`)" + traefikRule := "PathPrefix(`" + pathPrefix + "`)" if manager.config.TraefikDomain != "" && manager.config.TraefikDomain != "*" { // match *.domain.tld as subdomain if strings.HasPrefix(manager.config.TraefikDomain, "*.") { @@ -172,9 +173,9 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro "traefik.http.services." + containerName + "-frontend.loadbalancer.server.port": fmt.Sprintf("%d", frontendPort), "traefik.http.routers." + containerName + ".entrypoints": manager.config.TraefikEntrypoint, "traefik.http.routers." + containerName + ".rule": traefikRule, - "traefik.http.middlewares." + containerName + "-rdr.redirectregex.regex": "/" + roomName + "$$", - "traefik.http.middlewares." + containerName + "-rdr.redirectregex.replacement": "/" + roomName + "/", - "traefik.http.middlewares." + containerName + "-prf.stripprefix.prefixes": "/" + roomName + "/", + "traefik.http.middlewares." + containerName + "-rdr.redirectregex.regex": pathPrefix + "$$", + "traefik.http.middlewares." + containerName + "-rdr.redirectregex.replacement": pathPrefix + "/", + "traefik.http.middlewares." + containerName + "-prf.stripprefix.prefixes": pathPrefix + "/", "traefik.http.routers." + containerName + ".middlewares": containerName + "-rdr," + containerName + "-prf", } @@ -189,7 +190,6 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro // instanceUrl := manager.config.InstanceUrl - instanceSuffix := roomName + "/" if instanceUrl == "" { urlProto := "http" if manager.config.TraefikCertresolver != "" { @@ -205,19 +205,20 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro if manager.config.TraefikDomain != "" && manager.config.TraefikDomain != "*" { // match *.domain.tld as subdomain if strings.HasPrefix(manager.config.TraefikDomain, "*.") { - instanceUrl = urlProto + "://" + roomName + "." + strings.TrimPrefix(manager.config.TraefikDomain, "*.") + port + "/" - instanceSuffix = "" + instanceUrl = urlProto + "://" + roomName + "." + strings.TrimPrefix(manager.config.TraefikDomain, "*.") + port + pathPrefix = "" } else { - instanceUrl = urlProto + "://" + manager.config.TraefikDomain + port + "/" + instanceUrl = urlProto + "://" + manager.config.TraefikDomain + port } } else { // domain is not known - instanceUrl = urlProto + "://127.0.0.1" + port + "/" + instanceUrl = urlProto + "://127.0.0.1" + port } - } else if !strings.HasSuffix(instanceUrl, "/") { - instanceUrl = instanceUrl + "/" } + // remove last slash + instanceUrl = strings.TrimSuffix(instanceUrl, "/") + var browserPolicyLabels *BrowserPolicyLabels if settings.BrowserPolicy != nil { browserPolicyLabels = &BrowserPolicyLabels{ @@ -228,7 +229,7 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro labels := manager.serializeLabels(RoomLabels{ Name: roomName, - URL: instanceUrl + instanceSuffix, + URL: instanceUrl + pathPrefix + "/", Epr: epr, NekoImage: settings.NekoImage, diff --git a/neko.go b/neko.go index aab1045..51f1e75 100644 --- a/neko.go +++ b/neko.go @@ -128,6 +128,7 @@ func (main *MainCtx) Start() { main.httpManager = http.New( main.apiManager, + main.Configs.Room.InstancePathPrefix, main.Configs.Server, ) main.httpManager.Start()