1
0

util.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package controller
  2. import (
  3. "net"
  4. "net/http"
  5. "strings"
  6. "github.com/mhsanaei/3x-ui/v2/config"
  7. "github.com/mhsanaei/3x-ui/v2/logger"
  8. "github.com/mhsanaei/3x-ui/v2/web/entity"
  9. "github.com/gin-gonic/gin"
  10. )
  11. // getRemoteIp extracts the real IP address from the request headers or remote address.
  12. func getRemoteIp(c *gin.Context) string {
  13. value := c.GetHeader("X-Real-IP")
  14. if value != "" {
  15. return value
  16. }
  17. value = c.GetHeader("X-Forwarded-For")
  18. if value != "" {
  19. ips := strings.Split(value, ",")
  20. return ips[0]
  21. }
  22. addr := c.Request.RemoteAddr
  23. ip, _, _ := net.SplitHostPort(addr)
  24. return ip
  25. }
  26. // jsonMsg sends a JSON response with a message and error status.
  27. func jsonMsg(c *gin.Context, msg string, err error) {
  28. jsonMsgObj(c, msg, nil, err)
  29. }
  30. // jsonObj sends a JSON response with an object and error status.
  31. func jsonObj(c *gin.Context, obj any, err error) {
  32. jsonMsgObj(c, "", obj, err)
  33. }
  34. // jsonMsgObj sends a JSON response with a message, object, and error status.
  35. func jsonMsgObj(c *gin.Context, msg string, obj any, err error) {
  36. m := entity.Msg{
  37. Obj: obj,
  38. }
  39. if err == nil {
  40. m.Success = true
  41. if msg != "" {
  42. m.Msg = msg
  43. }
  44. } else {
  45. m.Success = false
  46. errStr := err.Error()
  47. if errStr != "" {
  48. m.Msg = msg + " (" + errStr + ")"
  49. logger.Warning(msg+" "+I18nWeb(c, "fail")+": ", err)
  50. } else if msg != "" {
  51. m.Msg = msg
  52. logger.Warning(msg + " " + I18nWeb(c, "fail"))
  53. } else {
  54. m.Msg = I18nWeb(c, "somethingWentWrong")
  55. logger.Warning(I18nWeb(c, "somethingWentWrong") + " " + I18nWeb(c, "fail"))
  56. }
  57. }
  58. c.JSON(http.StatusOK, m)
  59. }
  60. // pureJsonMsg sends a pure JSON message response with custom status code.
  61. func pureJsonMsg(c *gin.Context, statusCode int, success bool, msg string) {
  62. c.JSON(statusCode, entity.Msg{
  63. Success: success,
  64. Msg: msg,
  65. })
  66. }
  67. // html renders an HTML template with the provided data and title.
  68. func html(c *gin.Context, name string, title string, data gin.H) {
  69. if data == nil {
  70. data = gin.H{}
  71. }
  72. data["title"] = title
  73. host := c.GetHeader("X-Forwarded-Host")
  74. if host == "" {
  75. host = c.GetHeader("X-Real-IP")
  76. }
  77. if host == "" {
  78. var err error
  79. host, _, err = net.SplitHostPort(c.Request.Host)
  80. if err != nil {
  81. host = c.Request.Host
  82. }
  83. }
  84. data["host"] = host
  85. data["request_uri"] = c.Request.RequestURI
  86. data["base_path"] = c.GetString("base_path")
  87. c.HTML(http.StatusOK, name, getContext(data))
  88. }
  89. // getContext adds version and other context data to the provided gin.H.
  90. func getContext(h gin.H) gin.H {
  91. a := gin.H{
  92. "cur_ver": config.GetVersion(),
  93. }
  94. for key, value := range h {
  95. a[key] = value
  96. }
  97. return a
  98. }
  99. // isAjax checks if the request is an AJAX request.
  100. func isAjax(c *gin.Context) bool {
  101. return c.GetHeader("X-Requested-With") == "XMLHttpRequest"
  102. }