geziyor/client/proxy.go
Administrator 688c516c9f 初始化
2024-09-04 16:48:42 +08:00

49 lines
1.2 KiB
Go

package client
import (
"context"
"net/http"
"net/url"
"sync/atomic"
"softdown.com/shusou/geziyor/internal"
)
type ProxyURLKey int
type roundRobinProxy struct {
proxyURLs []*url.URL
index uint32
}
func (r *roundRobinProxy) GetProxy(pr *http.Request) (*url.URL, error) {
index := atomic.AddUint32(&r.index, 1) - 1
u := r.proxyURLs[index%uint32(len(r.proxyURLs))]
// Set proxy url to context
ctx := context.WithValue(pr.Context(), ProxyURLKey(0), u.String())
*pr = *pr.WithContext(ctx)
return u, nil
}
// RoundRobinProxy creates a proxy switcher function which rotates
// ProxyURLs on every request.
// The proxy type is determined by the URL scheme. "http", "https"
// and "socks5" are supported. If the scheme is empty,
// "http" is assumed.
func RoundRobinProxy(proxyURLs ...string) func(*http.Request) (*url.URL, error) {
if len(proxyURLs) < 1 {
return http.ProxyFromEnvironment
}
parsedProxyURLs := make([]*url.URL, len(proxyURLs))
for i, u := range proxyURLs {
parsedURL, err := url.Parse(u)
if err != nil {
internal.Logger.Printf("proxy url parse: %v", err)
return nil
}
parsedProxyURLs[i] = parsedURL
}
return (&roundRobinProxy{parsedProxyURLs, 0}).GetProxy
}