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.

183 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. return
  123. }
  124. func Request(req *http.Request) ([]byte, error) {
  125. var (
  126. err error
  127. body []byte
  128. )
  129. if nil == req {
  130. log.Errorf("illegal request")
  131. return nil, errors.New("illegal request")
  132. }
  133. //log.Infof("%v", req)
  134. resp, err := client.Do(req)
  135. if nil == resp {
  136. log.Info("none response received")
  137. err = errors.New("none response received")
  138. return nil, err
  139. }
  140. defer resp.Body.Close()
  141. if http.StatusOK != resp.StatusCode {
  142. if nil != resp.Body {
  143. body, _ = ioutil.ReadAll(resp.Body)
  144. log.Infof("response: %s", string(body))
  145. }
  146. log.Errorf("unexpected status: %d", resp.StatusCode)
  147. return nil, errors.New("unexpected status")
  148. }
  149. body, err = ioutil.ReadAll(resp.Body)
  150. if nil != err {
  151. log.Errorf("invalid response body: %s", err.Error())
  152. return nil, err
  153. }
  154. log.Infof("response: %s", string(body))
  155. return body, nil
  156. }