package loadbalance import ( "encoding/json" "errors" "net/http" "net/url" "strings" "time" "imuslab.com/zoraxy/mod/dynamicproxy/dpcore" ) // StartProxy create and start a HTTP proxy using dpcore // Example of webProxyEndpoint: https://example.com:443 or http://192.168.1.100:8080 func (u *Upstream) StartProxy() error { //Filter the tailing slash if any domain := u.OriginIpOrDomain if len(domain) == 0 { return errors.New("invalid endpoint config") } if domain[len(domain)-1:] == "/" { domain = domain[:len(domain)-1] } if !strings.HasPrefix("http://", domain) && !strings.HasPrefix("https://", domain) { //TLS is not hardcoded in proxy target domain if u.RequireTLS { domain = "https://" + domain } else { domain = "http://" + domain } } //Create a new proxy agent for this upstream path, err := url.Parse(domain) if err != nil { return err } proxy := dpcore.NewDynamicProxyCore(path, "", &dpcore.DpcoreOptions{ IgnoreTLSVerification: u.SkipCertValidations, FlushInterval: 100 * time.Millisecond, ResponseHeaderTimeout: u.RespTimeout, IdleConnectionTimeout: u.IdleTimeout, MaxConcurrentConnection: u.MaxConn, }) u.proxy = proxy return nil } // IsReady return the proxy ready state of the upstream server // Return false if StartProxy() is not called on this upstream before func (u *Upstream) IsReady() bool { return u.proxy != nil } // Clone return a new deep copy object of the identical upstream func (u *Upstream) Clone() *Upstream { newUpstream := Upstream{} js, _ := json.Marshal(u) json.Unmarshal(js, &newUpstream) return &newUpstream } // ServeHTTP uses this upstream proxy router to route the current request, return the status code and error if any func (u *Upstream) ServeHTTP(w http.ResponseWriter, r *http.Request, rrr *dpcore.ResponseRewriteRuleSet) (int, error) { //Auto rewrite to upstream origin if not set if rrr.ProxyDomain == "" { rrr.ProxyDomain = u.OriginIpOrDomain } return u.proxy.ServeHTTP(w, r, rrr) } // String return the string representations of endpoints in this upstream func (u *Upstream) String() string { return u.OriginIpOrDomain }