request.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package myth
  2. import (
  3. "compress/gzip"
  4. "crypto/tls"
  5. "crypto/x509"
  6. "io"
  7. "io/ioutil"
  8. "net"
  9. "net/http"
  10. "time"
  11. )
  12. const (
  13. // RequestTimeOut http request timeout (second)
  14. RequestTimeOut = 30
  15. )
  16. // GetRealIP get real IP from Request
  17. func GetRealIP(req *http.Request) (ip string) {
  18. if ips := req.Header["X-Real-Ip"]; ips != nil {
  19. ip = ips[0]
  20. }
  21. return
  22. }
  23. // HTTPMessage HTTP response
  24. type HTTPMessage struct {
  25. StatusCode int
  26. Body []byte
  27. Header http.Header
  28. }
  29. func newRequest(method, uri, certPath, keyPath string, header map[string]string, body io.Reader) (res *http.Response, err error) {
  30. t := &http.Transport{
  31. Dial: func(netw, addr string) (net.Conn, error) {
  32. conn, err := net.DialTimeout(netw, addr, time.Second*RequestTimeOut)
  33. if err != nil {
  34. return nil, err
  35. }
  36. conn.SetDeadline(time.Now().Add(time.Second * RequestTimeOut))
  37. return conn, nil
  38. },
  39. ResponseHeaderTimeout: time.Second * RequestTimeOut,
  40. }
  41. if certPath != "" {
  42. cert, e := tls.LoadX509KeyPair(certPath, keyPath)
  43. if e != nil {
  44. t.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
  45. } else {
  46. pool := x509.NewCertPool()
  47. t.TLSClientConfig = &tls.Config{InsecureSkipVerify: true, Certificates: []tls.Certificate{cert}, RootCAs: pool}
  48. }
  49. }
  50. client := &http.Client{Transport: t}
  51. var (
  52. req *http.Request
  53. )
  54. if body != nil {
  55. req, err = http.NewRequest(method, uri, body)
  56. } else {
  57. req, err = http.NewRequest(method, uri, nil)
  58. }
  59. if err != nil {
  60. return
  61. }
  62. for k := range header {
  63. req.Header.Add(k, header[k])
  64. }
  65. res, err = client.Do(req)
  66. return
  67. }
  68. func readBody(res *http.Response) (msg HTTPMessage, err error) {
  69. var (
  70. body []byte
  71. reader io.Reader
  72. )
  73. encoding := res.Header.Get("Content-Encoding")
  74. switch encoding {
  75. case "gzip":
  76. reader, err = gzip.NewReader(res.Body)
  77. if err == nil {
  78. body, err = ioutil.ReadAll(reader)
  79. }
  80. default:
  81. body, err = ioutil.ReadAll(res.Body)
  82. }
  83. if err != nil {
  84. return
  85. }
  86. msg.StatusCode = res.StatusCode
  87. msg.Header = res.Header
  88. msg.Body = body
  89. return
  90. }
  91. // Post HTTP request POST
  92. func Post(uri, certPath, keyPath string, header map[string]string, data io.Reader) (msg HTTPMessage, err error) {
  93. var res *http.Response
  94. if res, err = newRequest("POST", uri, certPath, keyPath, header, data); err != nil {
  95. return
  96. }
  97. defer res.Body.Close()
  98. msg, err = readBody(res)
  99. return
  100. }
  101. // Get HTTP request GET
  102. func Get(uri, certPath, keyPath string, header map[string]string) (msg HTTPMessage, err error) {
  103. var res *http.Response
  104. if res, err = newRequest("GET", uri, certPath, keyPath, header, nil); err != nil {
  105. return
  106. }
  107. defer res.Body.Close()
  108. msg, err = readBody(res)
  109. return
  110. }