|
- package zhios_pay_utils
-
- import (
- "bytes"
- "crypto/tls"
- "fmt"
- "io"
- "io/ioutil"
- "net/http"
- "net/url"
- "sort"
- "strings"
- "time"
- )
-
- var CurlDebug bool
-
- func CurlGet(router string, header map[string]string) ([]byte, error) {
- return curl(http.MethodGet, router, nil, header)
- }
- func CurlGetJson(router string, body interface{}, header map[string]string) ([]byte, error) {
- return curl_new(http.MethodGet, router, body, header)
- }
-
- // 只支持form 与json 提交, 请留意body的类型, 支持string, []byte, map[string]string
- func CurlPost(router string, body interface{}, header map[string]string) ([]byte, error) {
- return curl(http.MethodPost, router, body, header)
- }
-
- func CurlPut(router string, body interface{}, header map[string]string) ([]byte, error) {
- return curl(http.MethodPut, router, body, header)
- }
-
- // 只支持form 与json 提交, 请留意body的类型, 支持string, []byte, map[string]string
- func CurlPatch(router string, body interface{}, header map[string]string) ([]byte, error) {
- return curl(http.MethodPatch, router, body, header)
- }
-
- // CurlDelete is curl delete
- func CurlDelete(router string, body interface{}, header map[string]string) ([]byte, error) {
- return curl(http.MethodDelete, router, body, header)
- }
-
- func curl(method, router string, body interface{}, header map[string]string) ([]byte, error) {
- var reqBody io.Reader
- contentType := "application/json"
- switch v := body.(type) {
- case string:
- reqBody = strings.NewReader(v)
- case []byte:
- reqBody = bytes.NewReader(v)
- case map[string]string:
- val := url.Values{}
- for k, v := range v {
- val.Set(k, v)
- }
- reqBody = strings.NewReader(val.Encode())
- contentType = "application/x-www-form-urlencoded"
- case map[string]interface{}:
- val := url.Values{}
- for k, v := range v {
- val.Set(k, v.(string))
- }
- reqBody = strings.NewReader(val.Encode())
- contentType = "application/x-www-form-urlencoded"
- }
- if header == nil {
- header = map[string]string{"Content-Type": contentType}
- }
- if _, ok := header["Content-Type"]; !ok {
- header["Content-Type"] = contentType
- }
- resp, er := CurlReq(method, router, reqBody, header)
- if er != nil {
- return nil, er
- }
- res, err := ioutil.ReadAll(resp.Body)
- if CurlDebug {
- blob := SerializeStr(body)
- if contentType != "application/json" {
- blob = HttpBuild(body)
- }
- 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",
- router,
- time.Now().Format("2006-01-02 15:04:05.000"),
- method,
- contentType,
- HttpBuildQuery(header),
- blob,
- err,
- SerializeStr(resp.Header),
- string(res),
- )
- }
- resp.Body.Close()
- return res, err
- }
-
- func curl_new(method, router string, body interface{}, header map[string]string) ([]byte, error) {
- var reqBody io.Reader
- contentType := "application/json"
-
- if header == nil {
- header = map[string]string{"Content-Type": contentType}
- }
- if _, ok := header["Content-Type"]; !ok {
- header["Content-Type"] = contentType
- }
- resp, er := CurlReq(method, router, reqBody, header)
- if er != nil {
- return nil, er
- }
- res, err := ioutil.ReadAll(resp.Body)
- if CurlDebug {
- blob := SerializeStr(body)
- if contentType != "application/json" {
- blob = HttpBuild(body)
- }
- 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",
- router,
- time.Now().Format("2006-01-02 15:04:05.000"),
- method,
- contentType,
- HttpBuildQuery(header),
- blob,
- err,
- SerializeStr(resp.Header),
- string(res),
- )
- }
- resp.Body.Close()
- return res, err
- }
-
- func CurlReq(method, router string, reqBody io.Reader, header map[string]string) (*http.Response, error) {
- req, _ := http.NewRequest(method, router, reqBody)
- if header != nil {
- for k, v := range header {
- req.Header.Set(k, v)
- }
- }
- // 绕过github等可能因为特征码返回503问题
- // https://www.imwzk.com/posts/2021-03-14-why-i-always-get-503-with-golang/
- defaultCipherSuites := []uint16{0xc02f, 0xc030, 0xc02b, 0xc02c, 0xcca8, 0xcca9, 0xc013, 0xc009,
- 0xc014, 0xc00a, 0x009c, 0x009d, 0x002f, 0x0035, 0xc012, 0x000a}
- client := &http.Client{
- Transport: &http.Transport{
- TLSClientConfig: &tls.Config{
- InsecureSkipVerify: true,
- CipherSuites: append(defaultCipherSuites[8:], defaultCipherSuites[:8]...),
- },
- },
- // 获取301重定向
- CheckRedirect: func(req *http.Request, via []*http.Request) error {
- return http.ErrUseLastResponse
- },
- }
- return client.Do(req)
- }
-
- // 组建get请求参数,sortAsc true为小到大,false为大到小,nil不排序 a=123&b=321
- func HttpBuildQuery(args map[string]string, sortAsc ...bool) string {
- str := ""
- if len(args) == 0 {
- return str
- }
- if len(sortAsc) > 0 {
- keys := make([]string, 0, len(args))
- for k := range args {
- keys = append(keys, k)
- }
- if sortAsc[0] {
- sort.Strings(keys)
- } else {
- sort.Sort(sort.Reverse(sort.StringSlice(keys)))
- }
- for _, k := range keys {
- str += "&" + k + "=" + args[k]
- }
- } else {
- for k, v := range args {
- str += "&" + k + "=" + v
- }
- }
- return str[1:]
- }
-
- func HttpBuild(body interface{}, sortAsc ...bool) string {
- params := map[string]string{}
- if args, ok := body.(map[string]interface{}); ok {
- for k, v := range args {
- params[k] = AnyToString(v)
- }
- return HttpBuildQuery(params, sortAsc...)
- }
- if args, ok := body.(map[string]string); ok {
- for k, v := range args {
- params[k] = AnyToString(v)
- }
- return HttpBuildQuery(params, sortAsc...)
- }
- if args, ok := body.(map[string]int); ok {
- for k, v := range args {
- params[k] = AnyToString(v)
- }
- return HttpBuildQuery(params, sortAsc...)
- }
- return AnyToString(body)
- }
|