Asana Integeration
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
3.7 KiB

3 years ago
3 years ago
  1. package util
  2. import (
  3. "bufio"
  4. "bytes"
  5. "context"
  6. "errors"
  7. //"fmt"
  8. "io/ioutil"
  9. "net"
  10. "net/http"
  11. "time"
  12. "git.drinkme.beer/yinghe/log"
  13. )
  14. // Network contains common configuration.
  15. type Network struct {
  16. Env string `toml:"env"`
  17. Host []string `toml:"gateway"`
  18. GatewayURL string
  19. RequestTimeout time.Duration `toml:"request_timeout"`
  20. ConnectTimeout time.Duration `toml:"connect_timeout"`
  21. SocketTimeout time.Duration `toml:"socket_timeout"`
  22. }
  23. var network = Network{
  24. RequestTimeout: 45 * time.Second,
  25. ConnectTimeout: 45 * time.Second,
  26. SocketTimeout: 55 * time.Second,
  27. }
  28. var client = &http.Client{
  29. Transport: &http.Transport{
  30. DialContext: func(ctx context.Context, n, addr string) (net.Conn, error) {
  31. conn, err := net.DialTimeout(n, addr,
  32. time.Second*network.RequestTimeout,
  33. )
  34. if err != nil {
  35. return conn, err
  36. }
  37. conn.SetDeadline(time.Now().
  38. Add(time.Second * network.ConnectTimeout))
  39. return conn, err
  40. },
  41. ResponseHeaderTimeout: time.Second * network.SocketTimeout,
  42. MaxConnsPerHost: 20,
  43. IdleConnTimeout: 3 * time.Minute,
  44. MaxIdleConns: 10,
  45. //Proxy: func(_ *http.Request) (*url.URL, error) {
  46. // return url.Parse("http://192.168.0.104:1087")
  47. //},
  48. },
  49. }
  50. func SetNetworkCfg(cfg Network) {
  51. if 0 < cfg.RequestTimeout {
  52. network.RequestTimeout = cfg.RequestTimeout
  53. }
  54. if 0 < cfg.ConnectTimeout {
  55. network.ConnectTimeout = cfg.ConnectTimeout
  56. }
  57. if 0 < cfg.SocketTimeout {
  58. network.SocketTimeout = cfg.SocketTimeout
  59. }
  60. }
  61. type Body interface {
  62. BuildRequest() []byte
  63. }
  64. type Client struct {
  65. GatewayURL string
  66. URI string
  67. Headers map[string]string
  68. Authorization string
  69. Method string
  70. HTTPStatus int
  71. Body []byte // Indicates both Request Body & Response Body
  72. TraceId interface{}
  73. Buffer *bufio.Reader
  74. }
  75. func (c *Client) AddHeader(k, v string) {
  76. c.Headers[k] = v
  77. }
  78. type Bytes []byte
  79. func (self Bytes) BuildRequest() []byte {
  80. return self
  81. }
  82. /*
  83. url, uri, method, body
  84. */
  85. func NewHttpClient(url, uri, m string, b []byte) *Client {
  86. return &Client{
  87. GatewayURL: url,
  88. URI: uri,
  89. Method: m,
  90. Headers: make(map[string]string),
  91. Body: b,
  92. }
  93. }
  94. func (c *Client) BuildRequest(body Body) {
  95. if nil == c.Body {
  96. c.Body = make([]byte, 0, 1024)
  97. }
  98. c.Body = append(c.Body, body.BuildRequest()...)
  99. }
  100. func (c *Client) Request() (err error) {
  101. log.Infof("request url: %s", c.GatewayURL+c.URI)
  102. request, err := http.NewRequest(c.Method,
  103. c.GatewayURL+c.URI,
  104. bytes.NewReader(c.Body),
  105. )
  106. if err != nil {
  107. log.Info("Post err occurs:", err.Error())
  108. return
  109. }
  110. for k, v := range c.Headers {
  111. request.Header.Set(k, v)
  112. }
  113. resp, err := client.Do(request)
  114. if nil == resp {
  115. log.Info("none response received")
  116. err = errors.New("none response received")
  117. return
  118. }
  119. defer resp.Body.Close()
  120. c.HTTPStatus = resp.StatusCode
  121. c.Body, err = ioutil.ReadAll(resp.Body)
  122. log.Infof("response: %s", string(c.Body))
  123. return
  124. }
  125. func Request(req *http.Request) ([]byte, error) {
  126. var (
  127. err error
  128. body []byte
  129. )
  130. if nil == req {
  131. log.Errorf("illegal request")
  132. return nil, errors.New("illegal request")
  133. }
  134. //log.Infof("%v", req)
  135. resp, err := client.Do(req)
  136. if nil == resp {
  137. log.Info("none response received")
  138. err = errors.New("none response received")
  139. return nil, err
  140. }
  141. defer resp.Body.Close()
  142. if http.StatusOK != resp.StatusCode {
  143. if nil != resp.Body {
  144. body, _ = ioutil.ReadAll(resp.Body)
  145. log.Infof("response: %s", string(body))
  146. }
  147. log.Errorf("unexpected status: %d", resp.StatusCode)
  148. return nil, errors.New("unexpected status")
  149. }
  150. body, err = ioutil.ReadAll(resp.Body)
  151. if nil != err {
  152. log.Errorf("invalid response body: %s", err.Error())
  153. return nil, err
  154. }
  155. log.Infof("response: %s", string(body))
  156. return body, nil
  157. }