package proxy import ( "net" "net/http" "net/http/httputil" "net/url" "strings" "time" ) func CreateCustomProxyClient(target *url.URL, errFunc func(http.ResponseWriter, *http.Request, error)) *httputil.ReverseProxy { director := func(req *http.Request) { targetQuery := target.RawQuery req.URL.Scheme = target.Scheme req.URL.Host = target.Host req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path) if targetQuery == "" || req.URL.RawQuery == "" { req.URL.RawQuery = targetQuery + req.URL.RawQuery } else { req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery } if _, ok := req.Header["User-Agent"]; !ok { // explicitly disable User-Agent so it's not set to default value req.Header.Set("User-Agent", "") } } //超时处理 transport := &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ Timeout: 15 * time.Second, //连接超时 KeepAlive: 15 * time.Second, //长连接超时时间 DualStack: true, }).DialContext, MaxIdleConns: 30, //最大空闲连接 IdleConnTimeout: 90 * time.Second, //空闲超时时间 TLSHandshakeTimeout: 10 * time.Second, //tls握手超时时间 ExpectContinueTimeout: 1 * time.Second, //100-continue 超时时间 MaxIdleConnsPerHost: 300, } //异常处理 //errFunc := func(w http.ResponseWriter, r *http.Request, err error) { // http.Error(w, "proxy error:", 500) // logs.GInfo.Error(r.Context(), err.Error()) //} reverseProxy := &httputil.ReverseProxy{ Director: director, Transport: transport, //ModifyResponse: change, ErrorHandler: errFunc} return reverseProxy } func singleJoiningSlash(a, b string) string { aslash := strings.HasSuffix(a, "/") bslash := strings.HasPrefix(b, "/") switch { case aslash && bslash: return a + b[1:] case !aslash && !bslash: return a + "/" + b } return a + b }