proxy.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package proxy
  2. import (
  3. "github.com/astaxie/beego/context"
  4. "github.com/astaxie/beego/logs"
  5. "net/http"
  6. "net/url"
  7. "nginx-ui/server/models"
  8. "regexp"
  9. "strings"
  10. )
  11. type Data struct {
  12. *models.ProxyEntity
  13. Regexp []*regexp.Regexp `orm:"-" json:"-"`
  14. proxy *HttpProxy
  15. wsProxy *WebsocketProxy
  16. }
  17. type ReverseProxy struct {
  18. proxies []*Data
  19. NoProxies []*regexp.Regexp `json:"-"`
  20. }
  21. func NewReverseProxy() *ReverseProxy {
  22. return &ReverseProxy{
  23. proxies: make([]*Data, 0),
  24. NoProxies: make([]*regexp.Regexp, 0),
  25. }
  26. }
  27. func (proxy *ReverseProxy) AddNoProxy(pattern *regexp.Regexp) {
  28. proxy.NoProxies = append(proxy.NoProxies, pattern)
  29. }
  30. func (proxy *ReverseProxy) proxy(ctx *context.Context, data *Data) {
  31. if data.wsProxy != nil {
  32. if data.wsProxy.Proxy(ctx.ResponseWriter, ctx.Request) {
  33. return
  34. }
  35. }
  36. data.proxy.ServeHTTP(ctx.ResponseWriter, ctx.Request)
  37. }
  38. func (proxy *ReverseProxy) LoadProxies(list []*models.ProxyEntity) {
  39. entities := make([]*Data, 0)
  40. for _, p := range list {
  41. data := &Data{ProxyEntity: p}
  42. items := make([]*regexp.Regexp, 0)
  43. patterns := strings.Split(p.Patterns, ",")
  44. for _, pattern := range patterns {
  45. reg, err := regexp.Compile(pattern)
  46. if err != nil {
  47. logs.Error("regexp error: %s", err)
  48. continue
  49. }
  50. items = append(items, reg)
  51. }
  52. data.Regexp = items
  53. parsedURL, err := url.Parse(p.Target)
  54. if err != nil {
  55. logs.Error("target parse url error: %s", err)
  56. continue
  57. }
  58. data.proxy = NewSingleHostReverseProxy(parsedURL, p)
  59. if len(p.Ws) > 0 {
  60. ws, err := NewWebsocketProxy(p.Ws, func(r *http.Request) error {
  61. return nil
  62. })
  63. if err != nil {
  64. logs.Error("NewWebsocketProxy fail: %v", err)
  65. } else {
  66. data.wsProxy = ws
  67. }
  68. }
  69. entities = append(entities, data)
  70. }
  71. proxy.proxies = entities
  72. }
  73. func (proxy *ReverseProxy) Filter(ctx *context.Context) {
  74. request := ctx.Request.RequestURI
  75. for _, n := range proxy.NoProxies {
  76. if n.MatchString(request) {
  77. return
  78. }
  79. }
  80. for _, p := range proxy.proxies {
  81. for _, pattern := range p.Regexp {
  82. if pattern.MatchString(request) {
  83. proxy.proxy(ctx, p)
  84. return
  85. }
  86. }
  87. }
  88. }