add option to block domains, add option to resolve specific domains through specific proxies, option to set the check interval
This commit is contained in:
parent
2ce41d0637
commit
a886056d7f
|
@ -4,6 +4,9 @@ http_port: 9000
|
|||
# How many proxies will be checked at once?
|
||||
proxy_checkers: 50
|
||||
|
||||
# The interval between proxy checks in seconds.
|
||||
proxy_check_interval: 60
|
||||
|
||||
# URL to get a proxy's IP.
|
||||
ip_checker_url: https://api.ipify.org
|
||||
|
||||
|
@ -32,3 +35,12 @@ thirdparty_bypass_domains:
|
|||
# Shuffle the proxy lists whenever the background thread refreshes them.
|
||||
# If false, round-robin on default order.
|
||||
shuffle_proxies: false
|
||||
|
||||
# Don't allow requests to these domains through the proxy.
|
||||
blocked_domains:
|
||||
- example.com
|
||||
|
||||
# Resolve specific domains through specific proxies.
|
||||
# Proxies here are not validated.
|
||||
resolve_through:
|
||||
github.com: http://1.2.3.4:3128
|
||||
|
|
|
@ -19,6 +19,9 @@ type Config struct {
|
|||
ThirdpartyTestUrls []string
|
||||
ThirdpartyBypassDomains []string
|
||||
ShuffleProxies bool
|
||||
BlockedDomains []string
|
||||
ResolveThrough map[string]string
|
||||
ProxyCheckInterval int
|
||||
}
|
||||
|
||||
func SetConfig(configFile string) (*Config, error) {
|
||||
|
@ -36,6 +39,9 @@ func SetConfig(configFile string) (*Config, error) {
|
|||
viper.SetDefault("thirdparty_test_urls", make([]string, 0))
|
||||
viper.SetDefault("thirdparty_bypass_domains", make([]string, 0))
|
||||
viper.SetDefault("shuffle_proxies", false)
|
||||
viper.SetDefault("blocked_domains", make([]string, 0))
|
||||
viper.SetDefault("resolve_through", make(map[string]string))
|
||||
viper.SetDefault("proxy_check_interval", 60)
|
||||
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
|
@ -51,6 +57,9 @@ func SetConfig(configFile string) (*Config, error) {
|
|||
ThirdpartyTestUrls: viper.GetStringSlice("thirdparty_test_urls"),
|
||||
ThirdpartyBypassDomains: viper.GetStringSlice("thirdparty_bypass_domains"),
|
||||
ShuffleProxies: viper.GetBool("shuffle_proxies"),
|
||||
BlockedDomains: viper.GetStringSlice("blocked_domains"),
|
||||
ResolveThrough: viper.GetStringMapString("resolve_through"),
|
||||
ProxyCheckInterval: viper.GetInt("proxy_check_interval"),
|
||||
}
|
||||
|
||||
if len(config.ProxyPoolOurs) == 0 && len(config.ProxyPoolThirdparty) == 0 {
|
||||
|
|
|
@ -82,6 +82,8 @@ func main() {
|
|||
log.Fatalf(`Failed to load config: %s`, err)
|
||||
}
|
||||
|
||||
log.Debugf(`Proxy check interval: %d sec`, config.GetConfig().ProxyCheckInterval)
|
||||
|
||||
proxyCluster := proxy.NewForwardProxyCluster()
|
||||
go func() {
|
||||
log.Fatal(http.ListenAndServe(":"+configData.HTTPPort, proxyCluster))
|
||||
|
|
|
@ -24,6 +24,7 @@ func logProxyRequest(remoteAddr string, proxyHost string, targetHost string, ret
|
|||
}
|
||||
|
||||
func (p *ForwardProxyCluster) validateRequestAndGetProxy(w http.ResponseWriter, req *http.Request) (string, string, string, string, *url.URL, error) {
|
||||
urlHostname := req.URL.Hostname()
|
||||
if p.BalancerReady.GetCount() != 0 {
|
||||
errStr := "proxy is not ready"
|
||||
http.Error(w, errStr, http.StatusServiceUnavailable)
|
||||
|
@ -39,6 +40,12 @@ func (p *ForwardProxyCluster) validateRequestAndGetProxy(w http.ResponseWriter,
|
|||
return "", "", "", "", nil, errors.New(errStr)
|
||||
}
|
||||
|
||||
if slices.Contains(config.GetConfig().BlockedDomains, urlHostname) {
|
||||
errStr := "this domain has been blocked"
|
||||
http.Error(w, errStr, http.StatusUnavailableForLegalReasons)
|
||||
return "", "", "", "", nil, errors.New(errStr)
|
||||
}
|
||||
|
||||
headerIncludeBrokenThirdparty := req.Header.Get(HeaderThirdpartyIncludeBroken)
|
||||
req.Header.Del(HeaderThirdpartyIncludeBroken)
|
||||
headerBypassThirdparty := req.Header.Get(HeaderThirdpartyBypass)
|
||||
|
@ -50,15 +57,20 @@ func (p *ForwardProxyCluster) validateRequestAndGetProxy(w http.ResponseWriter,
|
|||
}
|
||||
|
||||
var selectedProxy string
|
||||
if slices.Contains(config.GetConfig().ThirdpartyBypassDomains, req.URL.Hostname()) {
|
||||
selectedProxy = p.getProxyFromOurs()
|
||||
|
||||
if val, ok := config.GetConfig().ResolveThrough[urlHostname]; ok {
|
||||
selectedProxy = val
|
||||
} else {
|
||||
if headerIncludeBrokenThirdparty != "" {
|
||||
selectedProxy = p.getProxyFromAllWithBroken()
|
||||
} else if headerBypassThirdparty != "" {
|
||||
if slices.Contains(config.GetConfig().ThirdpartyBypassDomains, urlHostname) {
|
||||
selectedProxy = p.getProxyFromOurs()
|
||||
} else {
|
||||
selectedProxy = p.getProxyFromAll()
|
||||
if headerIncludeBrokenThirdparty != "" {
|
||||
selectedProxy = p.getProxyFromAllWithBroken()
|
||||
} else if headerBypassThirdparty != "" {
|
||||
selectedProxy = p.getProxyFromOurs()
|
||||
} else {
|
||||
selectedProxy = p.getProxyFromAll()
|
||||
}
|
||||
}
|
||||
}
|
||||
if selectedProxy == "" {
|
||||
|
@ -82,7 +94,10 @@ func (p *ForwardProxyCluster) proxyHttpConnect(w http.ResponseWriter, req *http.
|
|||
_, proxyUser, proxyPass, proxyHost, parsedProxyUrl, err := p.validateRequestAndGetProxy(w, req)
|
||||
if err != nil {
|
||||
// Error has already been handled, just log and return.
|
||||
log.Debugf(`%s -> %s -- HTTP -- Rejecting request: %s`, remoteAddr, proxyHost, err)
|
||||
if proxyHost == "" {
|
||||
proxyHost = "none"
|
||||
}
|
||||
log.Debugf(`%s -> %s -> %s -- HTTP -- Rejecting request: %s`, remoteAddr, proxyHost, req.Host, err)
|
||||
return
|
||||
}
|
||||
var returnCode *int
|
||||
|
@ -132,7 +147,10 @@ func (p *ForwardProxyCluster) proxyHttpsConnect(w http.ResponseWriter, req *http
|
|||
_, proxyUser, proxyPass, proxyHost, _, err := p.validateRequestAndGetProxy(w, req)
|
||||
if err != nil {
|
||||
// Error has already been handled, just log and return.
|
||||
log.Debugf(`%s -> %s -- CONNECT -- Rejecting request: %s`, remoteAddr, proxyHost, err)
|
||||
if proxyHost == "" {
|
||||
proxyHost = "none"
|
||||
}
|
||||
log.Debugf(`%s -> %s -> %s -- CONNECT -- Rejecting request: %s`, remoteAddr, proxyHost, targetHost, err)
|
||||
return
|
||||
}
|
||||
var returnCode *int
|
||||
|
|
|
@ -127,7 +127,7 @@ func (p *ForwardProxyCluster) ValidateProxiesThread() {
|
|||
p.mu.RUnlock()
|
||||
|
||||
p.refreshInProgress = false
|
||||
time.Sleep(60 * time.Second)
|
||||
time.Sleep(time.Duration(config.GetConfig().ProxyCheckInterval) * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue