package service import ( "bufio" "bytes" "compress/flate" "compress/gzip" "context" "github.com/gogf/gf/v2/frame/g" "io" "net" "net/http" "net/http/httputil" "net/url" "time" ) func CreateDefaultProxyClient(remoteUrl *url.URL) *httputil.ReverseProxy { rp := httputil.NewSingleHostReverseProxy(remoteUrl) dialer := &net.Dialer{ Timeout: time.Duration(g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.timeout", 15).Int()) * time.Second, KeepAlive: time.Duration(g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.keepAlive", 60).Int()) * time.Second, } rp.Transport = &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { // 在这里可以自定义网络连接的创建方式 conn, err := dialer.DialContext(ctx, network, addr) if err != nil { return nil, err } return conn, nil }, MaxIdleConns: g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.maxIdleConns", 100).Int(), //空闲链接数量 IdleConnTimeout: time.Duration(g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.idleConnTimeout", 60).Int()) * time.Second, //空闲连接自动关闭时间 0不会被关闭 TLSHandshakeTimeout: time.Duration(g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.tLSHandshakeTimeout", 15).Int()) * time.Second, //TLS握手的超时时间 ExpectContinueTimeout: time.Duration(g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.expectContinueTimeout", 30).Int()) * time.Second, //等待服务器响应的时间 0一直等待 MaxIdleConnsPerHost: g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.maxIdleConnsPerHost", 2).Int(), //最大空闲 } //http.DefaultTransport //rp.ModifyResponse = ChangeResponse return rp } func ChangeResponse(resp *http.Response) (err error) { content := []byte{} encoding := resp.Header.Get("Content-Encoding") if encoding == "gzip" { //处理解压 body, _ := gzip.NewReader(resp.Body) content, err = io.ReadAll(body) //Read html } else if encoding == "deflate" { content, err = io.ReadAll(flate.NewReader(resp.Body)) //Read html } else { //无设置压缩 content, err = io.ReadAll(resp.Body) //Read html } if err != nil { return err } err = resp.Body.Close() if err != nil { return err } //压缩内容 var zBuf bytes.Buffer var output_writer io.Writer if encoding == "gzip" || encoding == "deflate" { //压缩 if encoding == "gzip" { output_writer, _ = gzip.NewWriterLevel(&zBuf, gzip.BestSpeed) } else { output_writer, _ = flate.NewWriter(&zBuf, flate.BestSpeed) } } else { output_writer = bufio.NewWriter(&zBuf) resp.ContentLength = int64(len(content)) } if _, err = output_writer.Write(content); err != nil { return err } switch output_writer.(type) { case *gzip.Writer: _ = output_writer.(*gzip.Writer).Close() case *flate.Writer: _ = output_writer.(*flate.Writer).Close() case *bufio.Writer: _ = output_writer.(*bufio.Writer).Flush() } resp.Body = io.NopCloser(bytes.NewReader(zBuf.Bytes())) return nil }