Browse Source

sub page: improved

mhsanaei 23 hours ago
parent
commit
c4871ef8fe
2 changed files with 25 additions and 6 deletions
  1. 24 5
      sub/sub.go
  2. 1 1
      sub/subService.go

+ 24 - 5
sub/sub.go

@@ -11,6 +11,7 @@ import (
 	"os"
 	"os"
 	"path/filepath"
 	"path/filepath"
 	"strconv"
 	"strconv"
+	"strings"
 
 
 	"x-ui/logger"
 	"x-ui/logger"
 	"x-ui/util/common"
 	"x-ui/util/common"
@@ -74,11 +75,6 @@ func (s *Server) initRouter() (*gin.Engine, error) {
 		engine.Use(middleware.DomainValidatorMiddleware(subDomain))
 		engine.Use(middleware.DomainValidatorMiddleware(subDomain))
 	}
 	}
 
 
-	// Provide base_path in context for templates
-	engine.Use(func(c *gin.Context) {
-		c.Set("base_path", "/")
-	})
-
 	LinksPath, err := s.settingService.GetSubPath()
 	LinksPath, err := s.settingService.GetSubPath()
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -89,6 +85,11 @@ func (s *Server) initRouter() (*gin.Engine, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
+	// Set base_path based on LinksPath for template rendering
+	engine.Use(func(c *gin.Context) {
+		c.Set("base_path", LinksPath)
+	})
+
 	Encrypt, err := s.settingService.GetSubEncrypt()
 	Encrypt, err := s.settingService.GetSubEncrypt()
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -154,11 +155,29 @@ func (s *Server) initRouter() (*gin.Engine, error) {
 	}
 	}
 
 
 	// Assets: use disk if present, fallback to embedded
 	// Assets: use disk if present, fallback to embedded
+	// Serve under both root (/assets) and under the subscription path prefix (LinksPath + "assets")
+	// so reverse proxies with a URI prefix can load assets correctly.
+	// Determine LinksPath earlier to compute prefixed assets mount.
+	// Note: LinksPath always starts and ends with "/" (validated in settings).
+	var linksPathForAssets string
+	if LinksPath == "/" {
+		linksPathForAssets = "/assets"
+	} else {
+		// ensure single slash join
+		linksPathForAssets = strings.TrimRight(LinksPath, "/") + "/assets"
+	}
+
 	if _, err := os.Stat("web/assets"); err == nil {
 	if _, err := os.Stat("web/assets"); err == nil {
 		engine.StaticFS("/assets", http.FS(os.DirFS("web/assets")))
 		engine.StaticFS("/assets", http.FS(os.DirFS("web/assets")))
+		if linksPathForAssets != "/assets" {
+			engine.StaticFS(linksPathForAssets, http.FS(os.DirFS("web/assets")))
+		}
 	} else {
 	} else {
 		if subFS, err := fs.Sub(webpkg.EmbeddedAssets(), "assets"); err == nil {
 		if subFS, err := fs.Sub(webpkg.EmbeddedAssets(), "assets"); err == nil {
 			engine.StaticFS("/assets", http.FS(subFS))
 			engine.StaticFS("/assets", http.FS(subFS))
+			if linksPathForAssets != "/assets" {
+				engine.StaticFS(linksPathForAssets, http.FS(subFS))
+			}
 		} else {
 		} else {
 			logger.Error("sub: failed to mount embedded assets:", err)
 			logger.Error("sub: failed to mount embedded assets:", err)
 		}
 		}

+ 1 - 1
sub/subService.go

@@ -1109,7 +1109,7 @@ func (s *SubService) BuildPageData(subId string, hostHeader string, traffic xray
 
 
 	return PageData{
 	return PageData{
 		Host:         hostHeader,
 		Host:         hostHeader,
-		BasePath:     "/",
+		BasePath:     "/", // kept as "/"; templates now use context base_path injected from router
 		SId:          subId,
 		SId:          subId,
 		Download:     download,
 		Download:     download,
 		Upload:       upload,
 		Upload:       upload,