From bf134ab52bb5bae2bdf8033e9217d881359efefc Mon Sep 17 00:00:00 2001
From: Hassan Dashtizadeh <101067119+Wolf6470@users.noreply.github.com>
Date: Wed, 5 Mar 2025 22:14:51 +0330
Subject: [PATCH 1/6] Add files via upload
---
sub/sub.html | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
create mode 100644 sub/sub.html
diff --git a/sub/sub.html b/sub/sub.html
new file mode 100644
index 00000000..aeae5b21
--- /dev/null
+++ b/sub/sub.html
@@ -0,0 +1,85 @@
+
+
+
+
+
+
اطلاعات سابسکریپشن
+
+
شناسه اشتراک : {{ .sId }}
+
دانلود : {{ .download }}
+
آپلود : {{ .upload }}
+
تاریخ پایان :
+
حجم کلی : {{ .total }}
+
+ {{ range .result }}
+
+
+ {{ . }}
+
+ {{ end }}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From 590567bfa03a8c26576cddf7d5479ec2c4759c50 Mon Sep 17 00:00:00 2001
From: Hassan Dashtizadeh <101067119+Wolf6470@users.noreply.github.com>
Date: Wed, 5 Mar 2025 23:15:23 +0400
Subject: [PATCH 2/6] Update subController.go
---
sub/subController.go | 63 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 60 insertions(+), 3 deletions(-)
diff --git a/sub/subController.go b/sub/subController.go
index 9afbc8da..110357dc 100644
--- a/sub/subController.go
+++ b/sub/subController.go
@@ -2,7 +2,10 @@ package sub
import (
"encoding/base64"
+ "fmt"
+ "math"
"net"
+ "strconv"
"strings"
"github.com/gin-gonic/gin"
@@ -78,16 +81,42 @@ func (a *SUBController) subs(c *gin.Context) {
for _, sub := range subs {
result += sub + "\n"
}
+ resultSlice := strings.Split(strings.TrimSpace(result), "\n")
// Add headers
c.Writer.Header().Set("Subscription-Userinfo", header)
c.Writer.Header().Set("Profile-Update-Interval", a.updateInterval)
c.Writer.Header().Set("Profile-Title", subId)
- if a.subEncrypt {
- c.String(200, base64.StdEncoding.EncodeToString([]byte(result)))
+ acceptHeader := c.GetHeader("Accept")
+ headerMap := parseHeaderString(header)
+ expireValue := headerMap["expire"]
+ upValue := formatBytes(headerMap["upload"], 2)
+ downValue := formatBytes(headerMap["download"], 2)
+ totalValue := formatBytes(headerMap["total"], 2)
+
+ currentURL := "https://" + c.Request.Host + c.Request.RequestURI
+
+ if strings.Contains(acceptHeader, "text/html") {
+ if a.subEncrypt {
+ c.String(200, base64.StdEncoding.EncodeToString([]byte(result)))
+ } else {
+ c.HTML(200, "sub.html", gin.H{
+ "result": resultSlice,
+ "total": totalValue,
+ "expire": expireValue,
+ "upload": upValue,
+ "download": downValue,
+ "sId": subId,
+ "subUrl": currentURL,
+ })
+ }
} else {
- c.String(200, result)
+ if a.subEncrypt {
+ c.String(200, base64.StdEncoding.EncodeToString([]byte(result)))
+ } else {
+ c.String(200, result)
+ }
}
}
}
@@ -132,3 +161,31 @@ func getHostFromXFH(s string) (string, error) {
}
return s, nil
}
+
+func parseHeaderString(header string) map[string]string {
+ headerMap := make(map[string]string)
+ pairs := strings.Split(header, ";")
+ for _, pair := range pairs {
+ kv := strings.Split(strings.TrimSpace(pair), "=")
+ if len(kv) == 2 {
+ headerMap[kv[0]] = kv[1]
+ }
+ }
+ return headerMap
+}
+
+func formatBytes(sizeStr string, precision int) string {
+ // Convert the string input to a float64
+ size, _ := strconv.ParseFloat(sizeStr, 64)
+
+ if size == 0 {
+ return "0 B"
+ }
+
+ // Calculate base and suffix
+ base := math.Log(size) / math.Log(1024)
+ suffixes := []string{"B", "K", "M", "G", "T"}
+
+ value := math.Pow(1024, base-math.Floor(base))
+ return fmt.Sprintf("%.*f %s", precision, value, suffixes[int(math.Floor(base))])
+}
From c7ec62def139be19366cd4855c7e92162351c09d Mon Sep 17 00:00:00 2001
From: Hassan Dashtizadeh <101067119+Wolf6470@users.noreply.github.com>
Date: Wed, 5 Mar 2025 23:16:48 +0400
Subject: [PATCH 3/6] Update sub.go
---
sub/sub.go | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 77 insertions(+), 1 deletion(-)
diff --git a/sub/sub.go b/sub/sub.go
index db582e8d..4ff7b8da 100644
--- a/sub/sub.go
+++ b/sub/sub.go
@@ -3,11 +3,14 @@ package sub
import (
"context"
"crypto/tls"
+ "embed"
+ "html/template"
"io"
+ "io/fs"
"net"
"net/http"
+ "os"
"strconv"
-
"x-ui/config"
"x-ui/logger"
"x-ui/util/common"
@@ -15,9 +18,13 @@ import (
"x-ui/web/network"
"x-ui/web/service"
+ "github.com/gin-contrib/gzip"
"github.com/gin-gonic/gin"
)
+//go:embed html/*
+var htmlFS embed.FS
+
type Server struct {
httpServer *http.Server
listener net.Listener
@@ -37,6 +44,48 @@ func NewServer() *Server {
}
}
+func (s *Server) getHtmlFiles() ([]string, error) {
+ files := make([]string, 0)
+ dir, _ := os.Getwd()
+ err := fs.WalkDir(os.DirFS(dir), "sub/html", func(path string, d fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+ if d.IsDir() {
+ return nil
+ }
+ files = append(files, path)
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ return files, nil
+}
+
+func (s *Server) getHtmlTemplate(funcMap template.FuncMap) (*template.Template, error) {
+ t := template.New("").Funcs(funcMap)
+ err := fs.WalkDir(htmlFS, "html", func(path string, d fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+
+ if d.IsDir() {
+ newT, err := t.ParseFS(htmlFS, path+"/*.html")
+ if err != nil {
+ // ignore
+ return nil
+ }
+ t = newT
+ }
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ return t, nil
+}
+
func (s *Server) initRouter() (*gin.Engine, error) {
if config.IsDebug() {
gin.SetMode(gin.DebugMode)
@@ -48,6 +97,33 @@ func (s *Server) initRouter() (*gin.Engine, error) {
engine := gin.Default()
+ basePath, err := s.settingService.GetBasePath()
+ if err != nil {
+ return nil, err
+ }
+ engine.Use(gzip.Gzip(gzip.DefaultCompression, gzip.WithExcludedPaths([]string{basePath + "panel/API/"})))
+
+ engine.Use(func(c *gin.Context) {
+ c.Set("base_path", basePath)
+ })
+
+ // set static files and template
+ if config.IsDebug() {
+ // for development
+ files, err := s.getHtmlFiles()
+ if err != nil {
+ return nil, err
+ }
+ engine.LoadHTMLFiles(files...)
+ } else {
+ // for production
+ template, err := s.getHtmlTemplate(engine.FuncMap)
+ if err != nil {
+ return nil, err
+ }
+ engine.SetHTMLTemplate(template)
+ }
+
subDomain, err := s.settingService.GetSubDomain()
if err != nil {
return nil, err
From 5cc04d03439d5166bc8d945e9551ffae4e1d8dc5 Mon Sep 17 00:00:00 2001
From: Hassan Dashtizadeh <101067119+Wolf6470@users.noreply.github.com>
Date: Thu, 6 Mar 2025 14:37:57 +0300
Subject: [PATCH 4/6] Rename sub/sub.html to sub/html/sub.html
---
sub/{ => html}/sub.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
rename sub/{ => html}/sub.html (99%)
diff --git a/sub/sub.html b/sub/html/sub.html
similarity index 99%
rename from sub/sub.html
rename to sub/html/sub.html
index aeae5b21..d0afdb20 100644
--- a/sub/sub.html
+++ b/sub/html/sub.html
@@ -82,4 +82,4 @@