reverseProxy.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package service
  2. import (
  3. "bufio"
  4. "bytes"
  5. "compress/flate"
  6. "compress/gzip"
  7. "context"
  8. "github.com/gogf/gf/v2/frame/g"
  9. "io"
  10. "net"
  11. "net/http"
  12. "net/http/httputil"
  13. "net/url"
  14. "time"
  15. )
  16. func CreateDefaultProxyClient(remoteUrl *url.URL) *httputil.ReverseProxy {
  17. rp := httputil.NewSingleHostReverseProxy(remoteUrl)
  18. dialer := &net.Dialer{
  19. Timeout: time.Duration(g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.timeout", 15).Int()) * time.Second,
  20. KeepAlive: time.Duration(g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.keepAlive", 60).Int()) * time.Second,
  21. }
  22. rp.Transport = &http.Transport{
  23. Proxy: http.ProxyFromEnvironment,
  24. DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
  25. // 在这里可以自定义网络连接的创建方式
  26. conn, err := dialer.DialContext(ctx, network, addr)
  27. if err != nil {
  28. return nil, err
  29. }
  30. return conn, nil
  31. },
  32. MaxIdleConns: g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.maxIdleConns", 100).Int(), //空闲链接数量
  33. IdleConnTimeout: time.Duration(g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.idleConnTimeout", 60).Int()) * time.Second, //空闲连接自动关闭时间 0不会被关闭
  34. TLSHandshakeTimeout: time.Duration(g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.tLSHandshakeTimeout", 15).Int()) * time.Second, //TLS握手的超时时间
  35. ExpectContinueTimeout: time.Duration(g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.expectContinueTimeout", 30).Int()) * time.Second, //等待服务器响应的时间 0一直等待
  36. MaxIdleConnsPerHost: g.Cfg().MustGet(context.Background(), "elasticSearch.reverseProxy.maxIdleConnsPerHost", 2).Int(), //最大空闲
  37. }
  38. //http.DefaultTransport
  39. //rp.ModifyResponse = ChangeResponse
  40. return rp
  41. }
  42. func ChangeResponse(resp *http.Response) (err error) {
  43. content := []byte{}
  44. encoding := resp.Header.Get("Content-Encoding")
  45. if encoding == "gzip" { //处理解压
  46. body, _ := gzip.NewReader(resp.Body)
  47. content, err = io.ReadAll(body) //Read html
  48. } else if encoding == "deflate" {
  49. content, err = io.ReadAll(flate.NewReader(resp.Body)) //Read html
  50. } else { //无设置压缩
  51. content, err = io.ReadAll(resp.Body) //Read html
  52. }
  53. if err != nil {
  54. return err
  55. }
  56. err = resp.Body.Close()
  57. if err != nil {
  58. return err
  59. }
  60. //压缩内容
  61. var zBuf bytes.Buffer
  62. var output_writer io.Writer
  63. if encoding == "gzip" || encoding == "deflate" { //压缩
  64. if encoding == "gzip" {
  65. output_writer, _ = gzip.NewWriterLevel(&zBuf, gzip.BestSpeed)
  66. } else {
  67. output_writer, _ = flate.NewWriter(&zBuf, flate.BestSpeed)
  68. }
  69. } else {
  70. output_writer = bufio.NewWriter(&zBuf)
  71. resp.ContentLength = int64(len(content))
  72. }
  73. if _, err = output_writer.Write(content); err != nil {
  74. return err
  75. }
  76. switch output_writer.(type) {
  77. case *gzip.Writer:
  78. _ = output_writer.(*gzip.Writer).Close()
  79. case *flate.Writer:
  80. _ = output_writer.(*flate.Writer).Close()
  81. case *bufio.Writer:
  82. _ = output_writer.(*bufio.Writer).Flush()
  83. }
  84. resp.Body = io.NopCloser(bytes.NewReader(zBuf.Bytes()))
  85. return nil
  86. }