golang 的 rabbitmq 消费项目
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.

curl.go 4.6 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package utils
  2. import (
  3. "bytes"
  4. "crypto/tls"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "net/http"
  9. "net/url"
  10. "sort"
  11. "strings"
  12. "time"
  13. )
  14. var CurlDebug bool
  15. func CurlGet(router string, header map[string]string) ([]byte, error) {
  16. return curl(http.MethodGet, router, nil, header)
  17. }
  18. // 只支持form 与json 提交, 请留意body的类型, 支持string, []byte, map[string]string
  19. func CurlPost(router string, body interface{}, header map[string]string) ([]byte, error) {
  20. return curl(http.MethodPost, router, body, header)
  21. }
  22. func CurlPut(router string, body interface{}, header map[string]string) ([]byte, error) {
  23. return curl(http.MethodPut, router, body, header)
  24. }
  25. // 只支持form 与json 提交, 请留意body的类型, 支持string, []byte, map[string]string
  26. func CurlPatch(router string, body interface{}, header map[string]string) ([]byte, error) {
  27. return curl(http.MethodPatch, router, body, header)
  28. }
  29. // CurlDelete is curl delete
  30. func CurlDelete(router string, body interface{}, header map[string]string) ([]byte, error) {
  31. return curl(http.MethodDelete, router, body, header)
  32. }
  33. func curl(method, router string, body interface{}, header map[string]string) ([]byte, error) {
  34. var reqBody io.Reader
  35. contentType := "application/json"
  36. switch v := body.(type) {
  37. case string:
  38. reqBody = strings.NewReader(v)
  39. case []byte:
  40. reqBody = bytes.NewReader(v)
  41. case map[string]string:
  42. val := url.Values{}
  43. for k, v := range v {
  44. val.Set(k, v)
  45. }
  46. reqBody = strings.NewReader(val.Encode())
  47. contentType = "application/x-www-form-urlencoded"
  48. case map[string]interface{}:
  49. val := url.Values{}
  50. for k, v := range v {
  51. val.Set(k, v.(string))
  52. }
  53. reqBody = strings.NewReader(val.Encode())
  54. contentType = "application/x-www-form-urlencoded"
  55. }
  56. if header == nil {
  57. header = map[string]string{"Content-Type": contentType}
  58. }
  59. if _, ok := header["Content-Type"]; !ok {
  60. header["Content-Type"] = contentType
  61. }
  62. resp, er := CurlReq(method, router, reqBody, header)
  63. if er != nil {
  64. return nil, er
  65. }
  66. res, err := ioutil.ReadAll(resp.Body)
  67. if CurlDebug {
  68. blob := SerializeStr(body)
  69. if contentType != "application/json" {
  70. blob = HttpBuild(body)
  71. }
  72. fmt.Printf("\n\n=====================\n[url]: %s\n[time]: %s\n[method]: %s\n[content-type]: %v\n[req_header]: %s\n[req_body]: %#v\n[resp_err]: %v\n[resp_header]: %v\n[resp_body]: %v\n=====================\n\n",
  73. router,
  74. time.Now().Format("2006-01-02 15:04:05.000"),
  75. method,
  76. contentType,
  77. HttpBuildQuery(header),
  78. blob,
  79. err,
  80. SerializeStr(resp.Header),
  81. string(res),
  82. )
  83. }
  84. resp.Body.Close()
  85. return res, err
  86. }
  87. func CurlReq(method, router string, reqBody io.Reader, header map[string]string) (*http.Response, error) {
  88. req, _ := http.NewRequest(method, router, reqBody)
  89. if header != nil {
  90. for k, v := range header {
  91. req.Header.Set(k, v)
  92. }
  93. }
  94. // 绕过github等可能因为特征码返回503问题
  95. // https://www.imwzk.com/posts/2021-03-14-why-i-always-get-503-with-golang/
  96. defaultCipherSuites := []uint16{0xc02f, 0xc030, 0xc02b, 0xc02c, 0xcca8, 0xcca9, 0xc013, 0xc009,
  97. 0xc014, 0xc00a, 0x009c, 0x009d, 0x002f, 0x0035, 0xc012, 0x000a}
  98. client := &http.Client{
  99. Transport: &http.Transport{
  100. TLSClientConfig: &tls.Config{
  101. InsecureSkipVerify: true,
  102. CipherSuites: append(defaultCipherSuites[8:], defaultCipherSuites[:8]...),
  103. },
  104. },
  105. // 获取301重定向
  106. CheckRedirect: func(req *http.Request, via []*http.Request) error {
  107. return http.ErrUseLastResponse
  108. },
  109. }
  110. return client.Do(req)
  111. }
  112. // 组建get请求参数,sortAsc true为小到大,false为大到小,nil不排序 a=123&b=321
  113. func HttpBuildQuery(args map[string]string, sortAsc ...bool) string {
  114. str := ""
  115. if len(args) == 0 {
  116. return str
  117. }
  118. if len(sortAsc) > 0 {
  119. keys := make([]string, 0, len(args))
  120. for k := range args {
  121. keys = append(keys, k)
  122. }
  123. if sortAsc[0] {
  124. sort.Strings(keys)
  125. } else {
  126. sort.Sort(sort.Reverse(sort.StringSlice(keys)))
  127. }
  128. for _, k := range keys {
  129. str += "&" + k + "=" + args[k]
  130. }
  131. } else {
  132. for k, v := range args {
  133. str += "&" + k + "=" + v
  134. }
  135. }
  136. return str[1:]
  137. }
  138. func HttpBuild(body interface{}, sortAsc ...bool) string {
  139. params := map[string]string{}
  140. if args, ok := body.(map[string]interface{}); ok {
  141. for k, v := range args {
  142. params[k] = AnyToString(v)
  143. }
  144. return HttpBuildQuery(params, sortAsc...)
  145. }
  146. if args, ok := body.(map[string]string); ok {
  147. for k, v := range args {
  148. params[k] = AnyToString(v)
  149. }
  150. return HttpBuildQuery(params, sortAsc...)
  151. }
  152. if args, ok := body.(map[string]int); ok {
  153. for k, v := range args {
  154. params[k] = AnyToString(v)
  155. }
  156. return HttpBuildQuery(params, sortAsc...)
  157. }
  158. return AnyToString(body)
  159. }