diff --git a/.env.example b/.env.example index 5f23ebc1..faf177ce 100644 --- a/.env.example +++ b/.env.example @@ -4,4 +4,7 @@ BUILD_WITH_ANTIZAPRET="0" XUI_SERVER_IP="" XUI_PANEL_DOMAIN="" XUI_SUB_DOMAIN="" -XUI_VLESS_SNI="" \ No newline at end of file +XUI_VLESS_SNI="" +#XUI_SUB_PROFILE_TITLE="" +#XUI_SUB_SUPPORT_URL="" +#XUI_SUB_PROFILE_WEB_PAGE_URL="" \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index cf76df52..0b5bdead 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,14 +32,18 @@ services: - "traefik.tcp.routers.vless.service=3x-ui-inbound-443" - "traefik.tcp.services.3x-ui-inbound-443.loadbalancer.server.port=443" volumes: - - $PWD/db/:/etc/x-ui/ - - $PWD/cert/:/root/cert/ + - ./db/:/etc/x-ui/ + - ./cert/:/root/cert/ + - ./announce.txt:/etc/x-ui/announce.txt environment: PUID: 1000 PGID: 1000 XRAY_VMESS_AEAD_FORCED: "false" TZ: Europe/Moscow XUI_SERVER_IP: "${XUI_SERVER_IP}" + XUI_SUB_PROFILE_TITLE: "${XUI_SUB_PROFILE_TITLE:-}" + XUI_SUB_SUPPORT_URL: "${XUI_SUB_SUPPORT_URL:-}" + XUI_SUB_PROFILE_WEB_PAGE_URL: "${XUI_SUB_PROFILE_WEB_PAGE_URL:-}" tty: true restart: unless-stopped diff --git a/sub/subController.go b/sub/subController.go index edd34481..ba33e52b 100644 --- a/sub/subController.go +++ b/sub/subController.go @@ -4,6 +4,7 @@ import ( "encoding/base64" "net" "strings" + "io/ioutil" "os" "github.com/gin-gonic/gin" @@ -74,6 +75,23 @@ func (a *SUBController) subs(c *gin.Context) { host = c.Request.Host } } + var profileTitle string + profileTitle = os.Getenv("XUI_SUB_PROFILE_TITLE") + if profileTitle == "" { + profileTitle = subId + } + var supportUrl string + supportUrl = os.Getenv("XUI_SUB_PROFILE_TITLE") + if supportUrl == "" { + supportUrl = os.Getenv("XUI_SUB_DOMAIN") + } + var profileWebPageUrl string + profileWebPageUrl = os.Getenv("XUI_SUB_PROFILE_WEB_PAGE_URL") + if profileWebPageUrl == "" { + profileWebPageUrl = os.Getenv("XUI_SUB_DOMAIN") + } + var announceText string + announceText = getAnnounceText() subs, header, err := a.subService.GetSubs(subId, host) if err != nil || len(subs) == 0 { c.String(400, "Error!") @@ -86,7 +104,12 @@ func (a *SUBController) subs(c *gin.Context) { // 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) + c.Writer.Header().Set("Profile-Title", profileTitle) + c.Writer.Header().Set("Support-Url", supportUrl) + c.Writer.Header().Set("Profile-Web-Page-Url", profileWebPageUrl) + if announceText != "" { + c.Writer.Header().Set("Announce", announceText) + } if a.subEncrypt { c.String(200, base64.StdEncoding.EncodeToString([]byte(result))) @@ -115,6 +138,23 @@ func (a *SUBController) subJsons(c *gin.Context) { host = c.Request.Host } } + var profileTitle string + profileTitle = os.Getenv("XUI_SUB_PROFILE_TITLE") + if profileTitle == "" { + profileTitle = subId + } + var supportUrl string + supportUrl = os.Getenv("XUI_SUB_PROFILE_TITLE") + if supportUrl == "" { + supportUrl = os.Getenv("XUI_SUB_DOMAIN") + } + var profileWebPageUrl string + profileWebPageUrl = os.Getenv("XUI_SUB_PROFILE_WEB_PAGE_URL") + if profileWebPageUrl == "" { + profileWebPageUrl = os.Getenv("XUI_SUB_DOMAIN") + } + var announceText string + announceText = getAnnounceText() jsonSub, header, err := a.subJsonService.GetJson(subId, host) if err != nil || len(jsonSub) == 0 { c.String(400, "Error!") @@ -123,12 +163,32 @@ func (a *SUBController) subJsons(c *gin.Context) { // 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) + c.Writer.Header().Set("Profile-Title", profileTitle) + c.Writer.Header().Set("Support-Url", supportUrl) + c.Writer.Header().Set("Profile-Web-Page-Url", profileWebPageUrl) + if announceText != "" { + c.Writer.Header().Set("Announce", announceText) + } c.String(200, jsonSub) } } +func getAnnounceText() (string) { + announceFilePath := "/etc/x-ui/announce.txt" + _, err := os.Stat(announceFilePath) + if os.IsNotExist(err) { + return "" + } + + content, err := ioutil.ReadFile(announceFilePath) + if err != nil { + return "" + } + + return string(content) +} + func getHostFromXFH(s string) (string, error) { if strings.Contains(s, ":") { realHost, _, err := net.SplitHostPort(s)