subController.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package sub
  2. import (
  3. "encoding/base64"
  4. "strings"
  5. "x-ui/config"
  6. "github.com/gin-gonic/gin"
  7. )
  8. type SUBController struct {
  9. subTitle string
  10. subPath string
  11. subJsonPath string
  12. subEncrypt bool
  13. updateInterval string
  14. subService *SubService
  15. subJsonService *SubJsonService
  16. }
  17. func NewSUBController(
  18. g *gin.RouterGroup,
  19. subPath string,
  20. jsonPath string,
  21. encrypt bool,
  22. showInfo bool,
  23. rModel string,
  24. update string,
  25. jsonFragment string,
  26. jsonNoise string,
  27. jsonMux string,
  28. jsonRules string,
  29. subTitle string,
  30. ) *SUBController {
  31. sub := NewSubService(showInfo, rModel)
  32. a := &SUBController{
  33. subTitle: subTitle,
  34. subPath: subPath,
  35. subJsonPath: jsonPath,
  36. subEncrypt: encrypt,
  37. updateInterval: update,
  38. subService: sub,
  39. subJsonService: NewSubJsonService(jsonFragment, jsonNoise, jsonMux, jsonRules, sub),
  40. }
  41. a.initRouter(g)
  42. return a
  43. }
  44. func (a *SUBController) initRouter(g *gin.RouterGroup) {
  45. gLink := g.Group(a.subPath)
  46. gJson := g.Group(a.subJsonPath)
  47. gLink.GET(":subid", a.subs)
  48. gJson.GET(":subid", a.subJsons)
  49. }
  50. func (a *SUBController) subs(c *gin.Context) {
  51. subId := c.Param("subid")
  52. scheme, host, hostWithPort, hostHeader := a.subService.ResolveRequest(c)
  53. subs, header, lastOnline, err := a.subService.GetSubs(subId, host)
  54. if err != nil || len(subs) == 0 {
  55. c.String(400, "Error!")
  56. } else {
  57. result := ""
  58. for _, sub := range subs {
  59. result += sub + "\n"
  60. }
  61. // If the request expects HTML (e.g., browser) or explicitly asked (?html=1 or ?view=html), render the info page here
  62. accept := c.GetHeader("Accept")
  63. if strings.Contains(strings.ToLower(accept), "text/html") || c.Query("html") == "1" || strings.EqualFold(c.Query("view"), "html") {
  64. // Build page data in service
  65. subURL, subJsonURL := a.subService.BuildURLs(scheme, hostWithPort, a.subPath, a.subJsonPath, subId)
  66. page := a.subService.BuildPageData(subId, hostHeader, header, lastOnline, subs, subURL, subJsonURL)
  67. c.HTML(200, "subscription.html", gin.H{
  68. "title": "subscription.title",
  69. "cur_ver": config.GetVersion(),
  70. "host": page.Host,
  71. "base_path": page.BasePath,
  72. "sId": page.SId,
  73. "download": page.Download,
  74. "upload": page.Upload,
  75. "total": page.Total,
  76. "used": page.Used,
  77. "remained": page.Remained,
  78. "expire": page.Expire,
  79. "lastOnline": page.LastOnline,
  80. "datepicker": page.Datepicker,
  81. "downloadByte": page.DownloadByte,
  82. "uploadByte": page.UploadByte,
  83. "totalByte": page.TotalByte,
  84. "subUrl": page.SubUrl,
  85. "subJsonUrl": page.SubJsonUrl,
  86. "result": page.Result,
  87. })
  88. return
  89. }
  90. // Add headers
  91. a.ApplyCommonHeaders(c, header, a.updateInterval, a.subTitle)
  92. if a.subEncrypt {
  93. c.String(200, base64.StdEncoding.EncodeToString([]byte(result)))
  94. } else {
  95. c.String(200, result)
  96. }
  97. }
  98. }
  99. func (a *SUBController) subJsons(c *gin.Context) {
  100. subId := c.Param("subid")
  101. _, host, _, _ := a.subService.ResolveRequest(c)
  102. jsonSub, header, err := a.subJsonService.GetJson(subId, host)
  103. if err != nil || len(jsonSub) == 0 {
  104. c.String(400, "Error!")
  105. } else {
  106. // Add headers
  107. a.ApplyCommonHeaders(c, header, a.updateInterval, a.subTitle)
  108. c.String(200, jsonSub)
  109. }
  110. }
  111. func (a *SUBController) ApplyCommonHeaders(c *gin.Context, header, updateInterval, profileTitle string) {
  112. c.Writer.Header().Set("Subscription-Userinfo", header)
  113. c.Writer.Header().Set("Profile-Update-Interval", updateInterval)
  114. c.Writer.Header().Set("Profile-Title", "base64:"+base64.StdEncoding.EncodeToString([]byte(profileTitle)))
  115. }