|
@@ -0,0 +1,70 @@
|
|
|
+package proxy
|
|
|
+
|
|
|
+import (
|
|
|
+ "gateway/core/logs"
|
|
|
+ "net"
|
|
|
+ "net/http"
|
|
|
+ "net/http/httputil"
|
|
|
+ "net/url"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+func CreateCustomProxyClient(target *url.URL) *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
|
|
|
+}
|