From 2c34d96b9df5f23fa490d99b8b1bd94c75e275a5 Mon Sep 17 00:00:00 2001 From: John Guo Date: Tue, 23 Feb 2021 22:00:11 +0800 Subject: [PATCH] add tls configuration for ghttp.Client --- container/gvar/gvar_z_unit_basic_test.go | 55 +++++++++++++++++++-- net/ghttp/internal/client/client.go | 55 +++++++++++++++++++-- net/ghttp/internal/client/client_request.go | 4 +- 3 files changed, 103 insertions(+), 11 deletions(-) diff --git a/container/gvar/gvar_z_unit_basic_test.go b/container/gvar/gvar_z_unit_basic_test.go index d46ab188f..fd20aeeb5 100644 --- a/container/gvar/gvar_z_unit_basic_test.go +++ b/container/gvar/gvar_z_unit_basic_test.go @@ -245,12 +245,57 @@ func Test_Duration(t *testing.T) { }) } -func Test_UnmarshalValue(t *testing.T) { - type V struct { - Name string - Var *gvar.Var - } +func Test_UnmarshalJson(t *testing.T) { gtest.C(t, func(t *gtest.T) { + type V struct { + Name string + Var *gvar.Var + } + var v *V + err := gconv.Struct(map[string]interface{}{ + "name": "john", + "var": "v", + }, &v) + t.Assert(err, nil) + t.Assert(v.Name, "john") + t.Assert(v.Var.String(), "v") + }) + gtest.C(t, func(t *gtest.T) { + type V struct { + Name string + Var gvar.Var + } + var v *V + err := gconv.Struct(map[string]interface{}{ + "name": "john", + "var": "v", + }, &v) + t.Assert(err, nil) + t.Assert(v.Name, "john") + t.Assert(v.Var.String(), "v") + }) +} + +func Test_UnmarshalValue(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + type V struct { + Name string + Var *gvar.Var + } + var v *V + err := gconv.Struct(map[string]interface{}{ + "name": "john", + "var": "v", + }, &v) + t.Assert(err, nil) + t.Assert(v.Name, "john") + t.Assert(v.Var.String(), "v") + }) + gtest.C(t, func(t *gtest.T) { + type V struct { + Name string + Var gvar.Var + } var v *V err := gconv.Struct(map[string]interface{}{ "name": "john", diff --git a/net/ghttp/internal/client/client.go b/net/ghttp/internal/client/client.go index 6c2b292b1..7e6366e2d 100644 --- a/net/ghttp/internal/client/client.go +++ b/net/ghttp/internal/client/client.go @@ -8,9 +8,12 @@ package client import ( "context" + "crypto/rand" "crypto/tls" "fmt" "github.com/gogf/gf" + "github.com/gogf/gf/errors/gerror" + "github.com/gogf/gf/os/gfile" "github.com/gogf/gf/text/gstr" "golang.org/x/net/proxy" "net" @@ -198,8 +201,8 @@ func (c *Client) SetProxy(proxyURL string) { return } if _proxy.Scheme == "http" { - if _, ok := c.Transport.(*http.Transport); ok { - c.Transport.(*http.Transport).Proxy = http.ProxyURL(_proxy) + if v, ok := c.Transport.(*http.Transport); ok { + v.Proxy = http.ProxyURL(_proxy) } } else { var auth = &proxy.Auth{} @@ -227,11 +230,55 @@ func (c *Client) SetProxy(proxyURL string) { if err != nil { return } - if _, ok := c.Transport.(*http.Transport); ok { - c.Transport.(*http.Transport).DialContext = func(ctx context.Context, network, addr string) (conn net.Conn, e error) { + if v, ok := c.Transport.(*http.Transport); ok { + v.DialContext = func(ctx context.Context, network, addr string) (conn net.Conn, e error) { return dialer.Dial(network, addr) } } //c.SetTimeout(10*time.Second) } } + +// SetTlsKeyCrt sets the certificate and key file for TLS configuration of client. +func (c *Client) SetTLSKeyCrt(crtFile, keyFile string) error { + tlsConfig, err := LoadKeyCrt(crtFile, keyFile) + if err != nil { + return err + } + if v, ok := c.Transport.(*http.Transport); ok { + tlsConfig.InsecureSkipVerify = true + v.TLSClientConfig = tlsConfig + return nil + } + return gerror.New(`cannot set TLSClientConfig for custom Transport of the client`) +} + +// SetTlsConfig sets the TLS configuration of client. +func (c *Client) SetTLSConfig(tlsConfig *tls.Config) error { + if v, ok := c.Transport.(*http.Transport); ok { + v.TLSClientConfig = tlsConfig + return nil + } + return gerror.New(`cannot set TLSClientConfig for custom Transport of the client`) +} + +// LoadKeyCrt creates and returns a TLS configuration object with given certificate and key files. +func LoadKeyCrt(crtFile, keyFile string) (*tls.Config, error) { + crtPath, err := gfile.Search(crtFile) + if err != nil { + return nil, err + } + keyPath, err := gfile.Search(keyFile) + if err != nil { + return nil, err + } + crt, err := tls.LoadX509KeyPair(crtPath, keyPath) + if err != nil { + return nil, err + } + tlsConfig := &tls.Config{} + tlsConfig.Certificates = []tls.Certificate{crt} + tlsConfig.Time = time.Now + tlsConfig.Rand = rand.Reader + return tlsConfig, nil +} diff --git a/net/ghttp/internal/client/client_request.go b/net/ghttp/internal/client/client_request.go index e12ddf501..cc8da7504 100644 --- a/net/ghttp/internal/client/client_request.go +++ b/net/ghttp/internal/client/client_request.go @@ -258,8 +258,8 @@ func (c *Client) prepareRequest(method, url string, data ...interface{}) (req *h } } // It's necessary set the req.Host if you want to custom the host value of the request. - // It uses the "Host" value from header if it's not set in the request. - if host := req.Header.Get("Host"); host != "" && req.Host == "" { + // It uses the "Host" value from header if it's not empty. + if host := req.Header.Get("Host"); host != "" { req.Host = host } // Custom Cookie.