gclient.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. // Package gclient provides convenient http client functionalities.
  7. package gclient
  8. import (
  9. "crypto/rand"
  10. "crypto/tls"
  11. "fmt"
  12. "net/http"
  13. "os"
  14. "time"
  15. "github.com/gogf/gf/v2"
  16. "github.com/gogf/gf/v2/errors/gerror"
  17. "github.com/gogf/gf/v2/net/gsel"
  18. "github.com/gogf/gf/v2/net/gsvc"
  19. "github.com/gogf/gf/v2/os/gfile"
  20. )
  21. // Client is the HTTP client for HTTP request management.
  22. type Client struct {
  23. http.Client // Underlying HTTP Client.
  24. header map[string]string // Custom header map.
  25. cookies map[string]string // Custom cookie map.
  26. prefix string // Prefix for request.
  27. authUser string // HTTP basic authentication: user.
  28. authPass string // HTTP basic authentication: pass.
  29. retryCount int // Retry count when request fails.
  30. noUrlEncode bool // No url encoding for request parameters.
  31. retryInterval time.Duration // Retry interval when request fails.
  32. middlewareHandler []HandlerFunc // Interceptor handlers
  33. discovery gsvc.Discovery // Discovery for service.
  34. builder gsel.Builder // Builder for request balance.
  35. }
  36. const (
  37. httpProtocolName = `http`
  38. httpParamFileHolder = `@file:`
  39. httpRegexParamJson = `^[\w\[\]]+=.+`
  40. httpRegexHeaderRaw = `^([\w\-]+):\s*(.+)`
  41. httpHeaderHost = `Host`
  42. httpHeaderCookie = `Cookie`
  43. httpHeaderUserAgent = `User-Agent`
  44. httpHeaderContentType = `Content-Type`
  45. httpHeaderContentTypeJson = `application/json`
  46. httpHeaderContentTypeXml = `application/xml`
  47. httpHeaderContentTypeForm = `application/x-www-form-urlencoded`
  48. )
  49. var (
  50. hostname, _ = os.Hostname()
  51. defaultClientAgent = fmt.Sprintf(`GClient %s at %s`, gf.VERSION, hostname)
  52. )
  53. // New creates and returns a new HTTP client object.
  54. func New() *Client {
  55. c := &Client{
  56. Client: http.Client{
  57. Transport: &http.Transport{
  58. // No validation for https certification of the server in default.
  59. TLSClientConfig: &tls.Config{
  60. InsecureSkipVerify: true,
  61. },
  62. DisableKeepAlives: true,
  63. },
  64. },
  65. header: make(map[string]string),
  66. cookies: make(map[string]string),
  67. builder: gsel.GetBuilder(),
  68. discovery: gsvc.GetRegistry(),
  69. }
  70. c.header[httpHeaderUserAgent] = defaultClientAgent
  71. // It enables OpenTelemetry for client in default.
  72. c.Use(internalMiddlewareTracing, internalMiddlewareDiscovery)
  73. return c
  74. }
  75. // Clone deeply clones current client and returns a new one.
  76. func (c *Client) Clone() *Client {
  77. newClient := New()
  78. *newClient = *c
  79. if len(c.header) > 0 {
  80. newClient.header = make(map[string]string)
  81. for k, v := range c.header {
  82. newClient.header[k] = v
  83. }
  84. }
  85. if len(c.cookies) > 0 {
  86. newClient.cookies = make(map[string]string)
  87. for k, v := range c.cookies {
  88. newClient.cookies[k] = v
  89. }
  90. }
  91. return newClient
  92. }
  93. // LoadKeyCrt creates and returns a TLS configuration object with given certificate and key files.
  94. func LoadKeyCrt(crtFile, keyFile string) (*tls.Config, error) {
  95. crtPath, err := gfile.Search(crtFile)
  96. if err != nil {
  97. return nil, err
  98. }
  99. keyPath, err := gfile.Search(keyFile)
  100. if err != nil {
  101. return nil, err
  102. }
  103. crt, err := tls.LoadX509KeyPair(crtPath, keyPath)
  104. if err != nil {
  105. err = gerror.Wrapf(err, `tls.LoadX509KeyPair failed for certFile "%s", keyFile "%s"`, crtPath, keyPath)
  106. return nil, err
  107. }
  108. tlsConfig := &tls.Config{}
  109. tlsConfig.Certificates = []tls.Certificate{crt}
  110. tlsConfig.Time = time.Now
  111. tlsConfig.Rand = rand.Reader
  112. return tlsConfig, nil
  113. }