restful-api.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package restful_api
  2. import (
  3. "github.com/gin-gonic/gin"
  4. "github.com/v2fly/v2ray-core/v4/common/net"
  5. "github.com/v2fly/v2ray-core/v4/transport/internet"
  6. "net/http"
  7. "strings"
  8. )
  9. type StatsUser struct {
  10. uuid string `form:"uuid" binging:"required_without=email,uuid4"`
  11. email string `form:"email" binging:"required_without=uuid,email"`
  12. }
  13. func statsUser(c *gin.Context) {
  14. var statsUser StatsUser
  15. if err := c.BindQuery(&statsUser); err != nil {
  16. c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  17. }
  18. c.JSON(http.StatusOK, gin.H{
  19. "uplink": 1,
  20. "downlink": 1,
  21. })
  22. }
  23. type Stats struct {
  24. tag string `form:"tag" binging:"required,alpha,min=1,max=255"`
  25. }
  26. type StatsBound struct { // Better name?
  27. Uplink int64 `json:"uplink"`
  28. Downlink int64 `json:"downlink"`
  29. }
  30. type StatsResponse struct {
  31. Inbound StatsBound `json:"inbound"`
  32. Outbound StatsBound `json:"outbound"`
  33. }
  34. func stats(c *gin.Context) {
  35. var stats Stats
  36. if err := c.BindQuery(&stats); err != nil {
  37. c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  38. }
  39. response := StatsResponse{
  40. Inbound: StatsBound{
  41. Uplink: 1,
  42. Downlink: 1,
  43. },
  44. Outbound: StatsBound{
  45. Uplink: 1,
  46. Downlink: 1,
  47. }}
  48. c.JSON(http.StatusOK, response)
  49. }
  50. func loggerReboot(c *gin.Context) {
  51. c.JSON(http.StatusOK, gin.H{})
  52. }
  53. func TokenAuthMiddleware() gin.HandlerFunc {
  54. return func(c *gin.Context) {
  55. auth := c.GetHeader("Authorization")
  56. if auth[6:] != "token123" { // tip: Bearer: token123
  57. c.JSON(http.StatusUnauthorized, "unauthorized")
  58. c.Abort()
  59. return
  60. }
  61. c.Next()
  62. }
  63. }
  64. func (r *restfulService) start() error {
  65. r.Engine = gin.New()
  66. r.GET("/ping", func(c *gin.Context) {
  67. c.JSON(200, gin.H{
  68. "message": "pong",
  69. })
  70. })
  71. v1 := r.Group("/v1")
  72. v1.Use(TokenAuthMiddleware())
  73. {
  74. v1.GET("/stats/user", statsUser)
  75. v1.GET("/stats", stats)
  76. v1.POST("/logger/reboot", loggerReboot)
  77. }
  78. var listener net.Listener
  79. var err error
  80. address := net.ParseAddress(r.config.ListenAddr)
  81. switch {
  82. case address.Family().IsIP():
  83. listener, err = internet.ListenSystem(r.ctx, &net.TCPAddr{IP: address.IP(), Port: int(r.config.ListenPort)}, nil)
  84. case strings.EqualFold(address.Domain(), "localhost"):
  85. listener, err = internet.ListenSystem(r.ctx, &net.TCPAddr{IP: net.IP{127, 0, 0, 1}, Port: int(r.config.ListenPort)}, nil)
  86. default:
  87. return newError("restful api cannot listen on the address: ", address)
  88. }
  89. if err != nil {
  90. return newError("restful api cannot listen on the port ", r.config.ListenPort).Base(err)
  91. }
  92. r.listener = listener
  93. go func() {
  94. if err := r.RunListener(listener); err != nil {
  95. newError("unable to serve restful api").WriteToLog()
  96. }
  97. }()
  98. return nil
  99. }