From 5822758b7c2431f8f952432a4e67cd0c2c6237e1 Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Wed, 24 Sep 2025 19:51:01 +0200 Subject: [PATCH] tiny changes --- sub/sub.go | 50 ++++++++++++++++++++++++++++++++++++-------- sub/subController.go | 15 ++++++++++++- sub/subService.go | 4 ++-- 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/sub/sub.go b/sub/sub.go index c5445339..1a1a7d9e 100644 --- a/sub/sub.go +++ b/sub/sub.go @@ -98,8 +98,14 @@ func (s *Server) initRouter() (*gin.Engine, error) { } // Set base_path based on LinksPath for template rendering + // Ensure LinksPath ends with "/" for proper asset URL generation + basePath := LinksPath + if basePath != "/" && !strings.HasSuffix(basePath, "/") { + basePath += "/" + } + logger.Debug("sub: Setting base_path to:", basePath) engine.Use(func(c *gin.Context) { - c.Set("base_path", LinksPath) + c.Set("base_path", basePath) }) Encrypt, err := s.settingService.GetSubEncrypt() @@ -179,22 +185,48 @@ func (s *Server) initRouter() (*gin.Engine, error) { linksPathForAssets = strings.TrimRight(LinksPath, "/") + "/assets" } + // Mount assets in multiple paths to handle different URL patterns + var assetsFS http.FileSystem if _, err := os.Stat("web/assets"); err == nil { - engine.StaticFS("/assets", http.FS(os.DirFS("web/assets"))) - if linksPathForAssets != "/assets" { - engine.StaticFS(linksPathForAssets, http.FS(os.DirFS("web/assets"))) - } + assetsFS = http.FS(os.DirFS("web/assets")) } else { if subFS, err := fs.Sub(webpkg.EmbeddedAssets(), "assets"); err == nil { - engine.StaticFS("/assets", http.FS(subFS)) - if linksPathForAssets != "/assets" { - engine.StaticFS(linksPathForAssets, http.FS(subFS)) - } + assetsFS = http.FS(subFS) } else { logger.Error("sub: failed to mount embedded assets:", err) } } + if assetsFS != nil { + engine.StaticFS("/assets", assetsFS) + if linksPathForAssets != "/assets" { + engine.StaticFS(linksPathForAssets, assetsFS) + } + + // Add middleware to handle dynamic asset paths with subid + if LinksPath != "/" { + engine.Use(func(c *gin.Context) { + path := c.Request.URL.Path + // Check if this is an asset request with subid pattern: /sub/path/{subid}/assets/... + pathPrefix := strings.TrimRight(LinksPath, "/") + "/" + if strings.HasPrefix(path, pathPrefix) && strings.Contains(path, "/assets/") { + // Extract the asset path after /assets/ + assetsIndex := strings.Index(path, "/assets/") + if assetsIndex != -1 { + assetPath := path[assetsIndex+8:] // +8 to skip "/assets/" + if assetPath != "" { + // Serve the asset file + c.FileFromFS(assetPath, assetsFS) + c.Abort() + return + } + } + } + c.Next() + }) + } + } + g := engine.Group("/") s.sub = NewSUBController( diff --git a/sub/subController.go b/sub/subController.go index 42a33ee6..ec574d6e 100644 --- a/sub/subController.go +++ b/sub/subController.go @@ -87,7 +87,20 @@ func (a *SUBController) subs(c *gin.Context) { if !a.jsonEnabled { subJsonURL = "" } - page := a.subService.BuildPageData(subId, hostHeader, traffic, lastOnline, subs, subURL, subJsonURL) + // Get base_path from context (set by middleware) + basePath, exists := c.Get("base_path") + if !exists { + basePath = "/" + } + // Add subId to base_path for asset URLs + basePathStr := basePath.(string) + if basePathStr == "/" { + basePathStr = "/" + subId + "/" + } else { + // Remove trailing slash if exists, add subId, then add trailing slash + basePathStr = strings.TrimRight(basePathStr, "/") + "/" + subId + "/" + } + page := a.subService.BuildPageData(subId, hostHeader, traffic, lastOnline, subs, subURL, subJsonURL, basePathStr) c.HTML(200, "subpage.html", gin.H{ "title": "subscription.title", "cur_ver": config.GetVersion(), diff --git a/sub/subService.go b/sub/subService.go index 77a60356..55bddf7f 100644 --- a/sub/subService.go +++ b/sub/subService.go @@ -1148,7 +1148,7 @@ func (s *SubService) joinPathWithID(basePath, subId string) string { // BuildPageData parses header and prepares the template view model. // BuildPageData constructs page data for rendering the subscription information page. -func (s *SubService) BuildPageData(subId string, hostHeader string, traffic xray.ClientTraffic, lastOnline int64, subs []string, subURL, subJsonURL string) PageData { +func (s *SubService) BuildPageData(subId string, hostHeader string, traffic xray.ClientTraffic, lastOnline int64, subs []string, subURL, subJsonURL string, basePath string) PageData { download := common.FormatTraffic(traffic.Down) upload := common.FormatTraffic(traffic.Up) total := "∞" @@ -1167,7 +1167,7 @@ func (s *SubService) BuildPageData(subId string, hostHeader string, traffic xray return PageData{ Host: hostHeader, - BasePath: "/", // kept as "/"; templates now use context base_path injected from router + BasePath: basePath, SId: subId, Download: download, Upload: upload,