client.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package httpclient
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/json"
  6. "encoding/xml"
  7. "fmt"
  8. "git.nspix.com/golang/micro/helper/random"
  9. "io"
  10. "net"
  11. "net/http"
  12. "strings"
  13. "time"
  14. )
  15. var (
  16. httpClient = http.Client{
  17. Timeout: time.Second * 15,
  18. Transport: &http.Transport{
  19. Proxy: http.ProxyFromEnvironment,
  20. DialContext: (&net.Dialer{
  21. Timeout: 30 * time.Second,
  22. KeepAlive: 30 * time.Second,
  23. }).DialContext,
  24. ForceAttemptHTTP2: false,
  25. MaxIdleConns: 10,
  26. IdleConnTimeout: 30 * time.Second,
  27. TLSHandshakeTimeout: 10 * time.Second,
  28. ExpectContinueTimeout: 1 * time.Second,
  29. },
  30. }
  31. )
  32. func Get(ctx context.Context, url string, header map[string]string) (res *http.Response, err error) {
  33. var (
  34. req *http.Request
  35. )
  36. if req, err = http.NewRequest("GET", url, nil); err != nil {
  37. return
  38. }
  39. if header != nil {
  40. for k, v := range header {
  41. req.Header.Set(k, v)
  42. }
  43. }
  44. return MockDo(ctx, req)
  45. }
  46. func Post(ctx context.Context, url string, header map[string]string, data interface{}) (res *http.Response, err error) {
  47. var (
  48. req *http.Request
  49. contentType string
  50. reader io.Reader
  51. )
  52. switch v := data.(type) {
  53. case string:
  54. reader = strings.NewReader(v)
  55. contentType = "x-www-form-urlencoded"
  56. case []byte:
  57. reader = bytes.NewReader(v)
  58. contentType = ""
  59. default:
  60. var b []byte
  61. if b, err = json.Marshal(v); err == nil {
  62. reader = bytes.NewReader(b)
  63. contentType = "application/json"
  64. } else {
  65. return
  66. }
  67. }
  68. if req, err = http.NewRequest("POST", url, reader); err != nil {
  69. return
  70. }
  71. if contentType != "" {
  72. req.Header.Set("Content-Type", contentType)
  73. }
  74. if header != nil {
  75. for k, v := range header {
  76. req.Header.Set(k, v)
  77. }
  78. }
  79. return MockDo(ctx, req)
  80. }
  81. func MockDo(ctx context.Context, req *http.Request) (res *http.Response, err error) {
  82. randomIp := random.IP()
  83. req.Header.Set("X-Forwarded-For", randomIp)
  84. req.Header.Set("X-Real-IP", randomIp)
  85. req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36")
  86. if ctx != nil {
  87. req = req.WithContext(ctx)
  88. }
  89. return Do(ctx, req)
  90. }
  91. func Fetch(ctx context.Context, req *http.Request, outer interface{}) (err error) {
  92. var (
  93. res *http.Response
  94. contentType string
  95. )
  96. randomIp := random.IP()
  97. req.Header.Set("X-Forwarded-For", randomIp)
  98. req.Header.Set("X-Real-IP", randomIp)
  99. req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.81 Safari/537.36 Edg/104.0.1293.54")
  100. if req.Header.Get("Referer") == "" {
  101. req.Header.Set("Referer", req.URL.String())
  102. }
  103. if ctx != nil {
  104. req = req.WithContext(ctx)
  105. }
  106. if res, err = Do(ctx, req); err != nil {
  107. return
  108. }
  109. defer func() {
  110. _ = res.Body.Close()
  111. }()
  112. if res.StatusCode != http.StatusOK {
  113. err = fmt.Errorf("got http response (%d)%s", res.StatusCode, res.Status)
  114. return
  115. }
  116. contentType = res.Header.Get("Content-Type")
  117. if strings.HasPrefix(contentType, "application/json") {
  118. err = json.NewDecoder(res.Body).Decode(outer)
  119. } else if strings.HasPrefix(contentType, "application/xml") {
  120. err = xml.NewDecoder(res.Body).Decode(outer)
  121. }
  122. return
  123. }
  124. func Do(ctx context.Context, req *http.Request) (res *http.Response, err error) {
  125. if ctx != nil {
  126. req = req.WithContext(ctx)
  127. }
  128. return httpClient.Do(req)
  129. }