server.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. package controller
  2. import (
  3. "fmt"
  4. "net/http"
  5. "regexp"
  6. "time"
  7. "x-ui/web/global"
  8. "x-ui/web/service"
  9. "github.com/gin-gonic/gin"
  10. )
  11. var filenameRegex = regexp.MustCompile(`^[a-zA-Z0-9_\-.]+$`)
  12. type ServerController struct {
  13. BaseController
  14. serverService service.ServerService
  15. lastStatus *service.Status
  16. lastGetStatusTime time.Time
  17. lastVersions []string
  18. lastGetVersionsTime time.Time
  19. }
  20. func NewServerController(g *gin.RouterGroup) *ServerController {
  21. a := &ServerController{
  22. lastGetStatusTime: time.Now(),
  23. }
  24. a.initRouter(g)
  25. a.startTask()
  26. return a
  27. }
  28. func (a *ServerController) initRouter(g *gin.RouterGroup) {
  29. g = g.Group("/server")
  30. g.Use(a.checkLogin)
  31. g.POST("/status", a.status)
  32. g.POST("/getXrayVersion", a.getXrayVersion)
  33. g.POST("/stopXrayService", a.stopXrayService)
  34. g.POST("/restartXrayService", a.restartXrayService)
  35. g.POST("/installXray/:version", a.installXray)
  36. g.POST("/updateGeofile/:fileName", a.updateGeofile)
  37. g.POST("/logs/:count", a.getLogs)
  38. g.POST("/getConfigJson", a.getConfigJson)
  39. g.GET("/getDb", a.getDb)
  40. g.POST("/importDB", a.importDB)
  41. g.POST("/getNewX25519Cert", a.getNewX25519Cert)
  42. g.POST("/getNewmldsa65", a.getNewmldsa65)
  43. }
  44. func (a *ServerController) refreshStatus() {
  45. a.lastStatus = a.serverService.GetStatus(a.lastStatus)
  46. }
  47. func (a *ServerController) startTask() {
  48. webServer := global.GetWebServer()
  49. c := webServer.GetCron()
  50. c.AddFunc("@every 2s", func() {
  51. now := time.Now()
  52. if now.Sub(a.lastGetStatusTime) > time.Minute*3 {
  53. return
  54. }
  55. a.refreshStatus()
  56. })
  57. }
  58. func (a *ServerController) status(c *gin.Context) {
  59. a.lastGetStatusTime = time.Now()
  60. jsonObj(c, a.lastStatus, nil)
  61. }
  62. func (a *ServerController) getXrayVersion(c *gin.Context) {
  63. now := time.Now()
  64. if now.Sub(a.lastGetVersionsTime) <= time.Minute {
  65. jsonObj(c, a.lastVersions, nil)
  66. return
  67. }
  68. versions, err := a.serverService.GetXrayVersions()
  69. if err != nil {
  70. jsonMsg(c, I18nWeb(c, "getVersion"), err)
  71. return
  72. }
  73. a.lastVersions = versions
  74. a.lastGetVersionsTime = time.Now()
  75. jsonObj(c, versions, nil)
  76. }
  77. func (a *ServerController) installXray(c *gin.Context) {
  78. version := c.Param("version")
  79. err := a.serverService.UpdateXray(version)
  80. jsonMsg(c, I18nWeb(c, "pages.index.xraySwitchVersionPopover"), err)
  81. }
  82. func (a *ServerController) updateGeofile(c *gin.Context) {
  83. fileName := c.Param("fileName")
  84. err := a.serverService.UpdateGeofile(fileName)
  85. jsonMsg(c, I18nWeb(c, "pages.index.geofileUpdatePopover"), err)
  86. }
  87. func (a *ServerController) stopXrayService(c *gin.Context) {
  88. a.lastGetStatusTime = time.Now()
  89. err := a.serverService.StopXrayService()
  90. if err != nil {
  91. jsonMsg(c, I18nWeb(c, "pages.xray.stopError"), err)
  92. return
  93. }
  94. jsonMsg(c, I18nWeb(c, "pages.xray.stopSuccess"), err)
  95. }
  96. func (a *ServerController) restartXrayService(c *gin.Context) {
  97. err := a.serverService.RestartXrayService()
  98. if err != nil {
  99. jsonMsg(c, I18nWeb(c, "pages.xray.restartError"), err)
  100. return
  101. }
  102. jsonMsg(c, I18nWeb(c, "pages.xray.restartSuccess"), err)
  103. }
  104. func (a *ServerController) getLogs(c *gin.Context) {
  105. count := c.Param("count")
  106. level := c.PostForm("level")
  107. syslog := c.PostForm("syslog")
  108. logs := a.serverService.GetLogs(count, level, syslog)
  109. jsonObj(c, logs, nil)
  110. }
  111. func (a *ServerController) getConfigJson(c *gin.Context) {
  112. configJson, err := a.serverService.GetConfigJson()
  113. if err != nil {
  114. jsonMsg(c, I18nWeb(c, "pages.index.getConfigError"), err)
  115. return
  116. }
  117. jsonObj(c, configJson, nil)
  118. }
  119. func (a *ServerController) getDb(c *gin.Context) {
  120. db, err := a.serverService.GetDb()
  121. if err != nil {
  122. jsonMsg(c, I18nWeb(c, "pages.index.getDatabaseError"), err)
  123. return
  124. }
  125. filename := "x-ui.db"
  126. if !isValidFilename(filename) {
  127. c.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid filename"))
  128. return
  129. }
  130. // Set the headers for the response
  131. c.Header("Content-Type", "application/octet-stream")
  132. c.Header("Content-Disposition", "attachment; filename="+filename)
  133. // Write the file contents to the response
  134. c.Writer.Write(db)
  135. }
  136. func isValidFilename(filename string) bool {
  137. // Validate that the filename only contains allowed characters
  138. return filenameRegex.MatchString(filename)
  139. }
  140. func (a *ServerController) importDB(c *gin.Context) {
  141. // Get the file from the request body
  142. file, _, err := c.Request.FormFile("db")
  143. if err != nil {
  144. jsonMsg(c, I18nWeb(c, "pages.index.readDatabaseError"), err)
  145. return
  146. }
  147. defer file.Close()
  148. // Always restart Xray before return
  149. defer a.serverService.RestartXrayService()
  150. defer func() {
  151. a.lastGetStatusTime = time.Now()
  152. }()
  153. // Import it
  154. err = a.serverService.ImportDB(file)
  155. if err != nil {
  156. jsonMsg(c, I18nWeb(c, "pages.index.importDatabaseError"), err)
  157. return
  158. }
  159. jsonObj(c, I18nWeb(c, "pages.index.importDatabaseSuccess"), nil)
  160. }
  161. func (a *ServerController) getNewX25519Cert(c *gin.Context) {
  162. cert, err := a.serverService.GetNewX25519Cert()
  163. if err != nil {
  164. jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.getNewX25519CertError"), err)
  165. return
  166. }
  167. jsonObj(c, cert, nil)
  168. }
  169. func (a *ServerController) getNewmldsa65(c *gin.Context) {
  170. cert, err := a.serverService.GetNewmldsa65()
  171. if err != nil {
  172. jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.getNewmldsa65Error"), err)
  173. return
  174. }
  175. jsonObj(c, cert, nil)
  176. }