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