1
0

upstream.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package loadbalance
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "net/http"
  6. "net/url"
  7. "strings"
  8. "time"
  9. "imuslab.com/zoraxy/mod/dynamicproxy/dpcore"
  10. )
  11. // StartProxy create and start a HTTP proxy using dpcore
  12. // Example of webProxyEndpoint: https://example.com:443 or http://192.168.1.100:8080
  13. func (u *Upstream) StartProxy() error {
  14. //Filter the tailing slash if any
  15. domain := u.OriginIpOrDomain
  16. if len(domain) == 0 {
  17. return errors.New("invalid endpoint config")
  18. }
  19. if domain[len(domain)-1:] == "/" {
  20. domain = domain[:len(domain)-1]
  21. }
  22. if !strings.HasPrefix("http://", domain) && !strings.HasPrefix("https://", domain) {
  23. //TLS is not hardcoded in proxy target domain
  24. if u.RequireTLS {
  25. domain = "https://" + domain
  26. } else {
  27. domain = "http://" + domain
  28. }
  29. }
  30. //Create a new proxy agent for this upstream
  31. path, err := url.Parse(domain)
  32. if err != nil {
  33. return err
  34. }
  35. proxy := dpcore.NewDynamicProxyCore(path, "", &dpcore.DpcoreOptions{
  36. IgnoreTLSVerification: u.SkipCertValidations,
  37. FlushInterval: 100 * time.Millisecond,
  38. ResponseHeaderTimeout: u.RespTimeout,
  39. IdleConnectionTimeout: u.IdleTimeout,
  40. MaxConcurrentConnection: u.MaxConn,
  41. })
  42. u.proxy = proxy
  43. return nil
  44. }
  45. // IsReady return the proxy ready state of the upstream server
  46. // Return false if StartProxy() is not called on this upstream before
  47. func (u *Upstream) IsReady() bool {
  48. return u.proxy != nil
  49. }
  50. // Clone return a new deep copy object of the identical upstream
  51. func (u *Upstream) Clone() *Upstream {
  52. newUpstream := Upstream{}
  53. js, _ := json.Marshal(u)
  54. json.Unmarshal(js, &newUpstream)
  55. return &newUpstream
  56. }
  57. // ServeHTTP uses this upstream proxy router to route the current request, return the status code and error if any
  58. func (u *Upstream) ServeHTTP(w http.ResponseWriter, r *http.Request, rrr *dpcore.ResponseRewriteRuleSet) (int, error) {
  59. //Auto rewrite to upstream origin if not set
  60. if rrr.ProxyDomain == "" {
  61. rrr.ProxyDomain = u.OriginIpOrDomain
  62. }
  63. return u.proxy.ServeHTTP(w, r, rrr)
  64. }
  65. // String return the string representations of endpoints in this upstream
  66. func (u *Upstream) String() string {
  67. return u.OriginIpOrDomain
  68. }