|
|
package util
import ( "bufio" "bytes" "context" "errors" //"fmt"
"io/ioutil" "net" "net/http" "time"
"git.drinkme.beer/yinghe/log" )
// Network contains common configuration.
type Network struct { Env string `toml:"env"` Host []string `toml:"gateway"` GatewayURL string RequestTimeout time.Duration `toml:"request_timeout"` ConnectTimeout time.Duration `toml:"connect_timeout"` SocketTimeout time.Duration `toml:"socket_timeout"` }
var network = Network{ RequestTimeout: 45 * time.Second, ConnectTimeout: 45 * time.Second, SocketTimeout: 55 * time.Second, }
var client = &http.Client{ Transport: &http.Transport{ DialContext: func(ctx context.Context, n, addr string) (net.Conn, error) { conn, err := net.DialTimeout(n, addr, time.Second*network.RequestTimeout, ) if err != nil { return conn, err } conn.SetDeadline(time.Now(). Add(time.Second * network.ConnectTimeout)) return conn, err }, ResponseHeaderTimeout: time.Second * network.SocketTimeout, MaxConnsPerHost: 20, IdleConnTimeout: 3 * time.Minute, MaxIdleConns: 10, //Proxy: func(_ *http.Request) (*url.URL, error) {
// return url.Parse("http://192.168.0.104:1087")
//},
}, }
func SetNetworkCfg(cfg Network) { if 0 < cfg.RequestTimeout { network.RequestTimeout = cfg.RequestTimeout }
if 0 < cfg.ConnectTimeout { network.ConnectTimeout = cfg.ConnectTimeout }
if 0 < cfg.SocketTimeout { network.SocketTimeout = cfg.SocketTimeout } }
type Body interface { BuildRequest() []byte }
type Client struct { GatewayURL string URI string Headers map[string]string Authorization string Method string HTTPStatus int Body []byte // Indicates both Request Body & Response Body
TraceId interface{} Buffer *bufio.Reader }
func (c *Client) AddHeader(k, v string) { c.Headers[k] = v }
type Bytes []byte
func (self Bytes) BuildRequest() []byte { return self }
/* url, uri, method, body */ func NewHttpClient(url, uri, m string, b []byte) *Client { return &Client{ GatewayURL: url, URI: uri, Method: m, Headers: make(map[string]string), Body: b, } }
func (c *Client) BuildRequest(body Body) { if nil == c.Body { c.Body = make([]byte, 0, 1024) } c.Body = append(c.Body, body.BuildRequest()...) }
func (c *Client) Request() (err error) { log.Infof("request url: %s", c.GatewayURL+c.URI) request, err := http.NewRequest(c.Method, c.GatewayURL+c.URI, bytes.NewReader(c.Body), ) if err != nil { log.Info("Post err occurs:", err.Error()) return }
for k, v := range c.Headers { request.Header.Set(k, v) }
resp, err := client.Do(request) if nil == resp { log.Info("none response received") err = errors.New("none response received") return }
defer resp.Body.Close() c.HTTPStatus = resp.StatusCode c.Body, err = ioutil.ReadAll(resp.Body)
return }
func Request(req *http.Request) ([]byte, error) { var ( err error body []byte )
if nil == req { log.Errorf("illegal request") return nil, errors.New("illegal request") } //log.Infof("%v", req)
resp, err := client.Do(req) if nil == resp { log.Info("none response received") err = errors.New("none response received") return nil, err }
defer resp.Body.Close() if http.StatusOK != resp.StatusCode { if nil != resp.Body {
body, _ = ioutil.ReadAll(resp.Body) log.Infof("response: %s", string(body)) } log.Errorf("unexpected status: %d", resp.StatusCode) return nil, errors.New("unexpected status") }
body, err = ioutil.ReadAll(resp.Body) if nil != err { log.Errorf("invalid response body: %s", err.Error()) return nil, err }
log.Infof("response: %s", string(body))
return body, nil }
|