proxy_ws.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package router
  2. import (
  3. "github.com/0xJacky/Nginx-UI/server/internal/logger"
  4. "github.com/0xJacky/Nginx-UI/server/query"
  5. "github.com/gin-gonic/gin"
  6. "github.com/pretty66/websocketproxy"
  7. "github.com/spf13/cast"
  8. "net/http"
  9. "net/url"
  10. "strings"
  11. )
  12. func proxyWs() gin.HandlerFunc {
  13. return func(c *gin.Context) {
  14. nodeID, ok := c.Get("ProxyNodeID")
  15. if !ok {
  16. c.Next()
  17. return
  18. }
  19. id := cast.ToInt(nodeID)
  20. if id == 0 {
  21. c.Next()
  22. return
  23. }
  24. defer c.Abort()
  25. env := query.Environment
  26. environment, err := env.Where(env.ID.Eq(id)).First()
  27. if err != nil {
  28. logger.Error(err)
  29. return
  30. }
  31. baseUrl, err := url.Parse(environment.URL)
  32. if err != nil {
  33. logger.Error(err)
  34. return
  35. }
  36. logger.Debug(baseUrl.Port())
  37. defaultPort := ""
  38. if baseUrl.Port() == "" {
  39. switch baseUrl.Scheme {
  40. default:
  41. fallthrough
  42. case "http":
  43. defaultPort = "80"
  44. case "https":
  45. defaultPort = "443"
  46. }
  47. baseUrl.Host = baseUrl.Hostname() + ":" + defaultPort
  48. }
  49. logger.Debug(baseUrl.String())
  50. u, err := url.JoinPath(baseUrl.String(), c.Request.RequestURI)
  51. if err != nil {
  52. logger.Error(err)
  53. return
  54. }
  55. decodedUri, err := url.QueryUnescape(u)
  56. if err != nil {
  57. logger.Error(err)
  58. return
  59. }
  60. // http will be replaced with ws, https will be replaced with wss
  61. decodedUri = strings.ReplaceAll(decodedUri, "http", "ws")
  62. logger.Debug("Proxy request", decodedUri)
  63. wp, err := websocketproxy.NewProxy(decodedUri, func(r *http.Request) error {
  64. r.Header.Set("X-Node-Secret", environment.Token)
  65. return nil
  66. })
  67. if err != nil {
  68. logger.Error(err)
  69. return
  70. }
  71. wp.Proxy(c.Writer, c.Request)
  72. }
  73. }