util.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package util
  2. import (
  3. "bytes"
  4. "crypto/tls"
  5. "encoding/xml"
  6. "errors"
  7. "fmt"
  8. "io/ioutil"
  9. "math/rand"
  10. "net"
  11. "net/http"
  12. "net/url"
  13. "time"
  14. )
  15. // TokenAPI 获取带 token 的 API 地址
  16. func TokenAPI(api, token string) (string, error) {
  17. u, err := url.Parse(api)
  18. if err != nil {
  19. return "", err
  20. }
  21. query := u.Query()
  22. query.Set("access_token", token)
  23. u.RawQuery = query.Encode()
  24. return u.String(), nil
  25. }
  26. // GetQuery returns url query value
  27. func GetQuery(req *http.Request, key string) string {
  28. if values, ok := req.URL.Query()[key]; ok && len(values) > 0 {
  29. return values[0]
  30. }
  31. return ""
  32. }
  33. // RandomString random string generator
  34. //
  35. // @ln length of return string
  36. func RandomString(ln int) string {
  37. letters := []rune("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
  38. b := make([]rune, ln)
  39. r := rand.New(rand.NewSource(time.Now().UnixNano()))
  40. for i := range b {
  41. b[i] = letters[r.Intn(len(letters))]
  42. }
  43. return string(b)
  44. }
  45. // PostXML perform a HTTP/POST request with XML body
  46. func PostXML(uri string, obj interface{}) ([]byte, error) {
  47. data, err := xml.Marshal(obj)
  48. if err != nil {
  49. return nil, err
  50. }
  51. body := bytes.NewBuffer(data)
  52. res, err := http.Post(uri, "application/xml; charset=utf-8", body)
  53. if err != nil {
  54. return nil, err
  55. }
  56. defer res.Body.Close()
  57. if res.StatusCode != http.StatusOK {
  58. return nil, fmt.Errorf("http code error : uri=%v , statusCode=%v", uri, res.StatusCode)
  59. }
  60. return ioutil.ReadAll(res.Body)
  61. }
  62. // TSLPostXML ...
  63. func TSLPostXML(uri string, obj interface{}, certPath, keyPath string) ([]byte, error) {
  64. data, err := xml.Marshal(obj)
  65. if err != nil {
  66. return nil, err
  67. }
  68. body := bytes.NewBuffer(data)
  69. cli, err := NewTLSClient(certPath, keyPath)
  70. if err != nil {
  71. return nil, err
  72. }
  73. res, err := cli.Post(uri, "application/xml; charset=utf-8", body)
  74. if err != nil {
  75. return nil, err
  76. }
  77. defer res.Body.Close()
  78. if res.StatusCode != http.StatusOK {
  79. return nil, fmt.Errorf("http code error : uri=%v , statusCode=%v", uri, res.StatusCode)
  80. }
  81. return ioutil.ReadAll(res.Body)
  82. }
  83. // NewTLSClient 创建支持双向证书认证的 http.Client.
  84. func NewTLSClient(certPath, keyPath string) (httpClient *http.Client, err error) {
  85. cert, err := tls.LoadX509KeyPair(certPath, keyPath)
  86. if err != nil {
  87. return nil, err
  88. }
  89. tlsConfig := &tls.Config{
  90. Certificates: []tls.Certificate{cert},
  91. }
  92. return newTLSClient(tlsConfig)
  93. }
  94. func newTLSClient(tlsConfig *tls.Config) (*http.Client, error) {
  95. dialTLS := func(network, addr string) (net.Conn, error) {
  96. return tls.DialWithDialer(&net.Dialer{
  97. Timeout: 5 * time.Second,
  98. KeepAlive: 30 * time.Second,
  99. }, network, addr, tlsConfig)
  100. }
  101. return &http.Client{
  102. Transport: &http.Transport{
  103. Proxy: http.ProxyFromEnvironment,
  104. DialContext: (&net.Dialer{
  105. Timeout: 5 * time.Second,
  106. KeepAlive: 30 * time.Second,
  107. DualStack: true,
  108. }).DialContext,
  109. DialTLS: dialTLS,
  110. MaxIdleConns: 100,
  111. IdleConnTimeout: 90 * time.Second,
  112. ExpectContinueTimeout: 1 * time.Second,
  113. },
  114. }, nil
  115. }
  116. // FetchIP current IP address
  117. func FetchIP() (net.IP, error) {
  118. addrs, err := net.InterfaceAddrs()
  119. if err != nil {
  120. return nil, err
  121. }
  122. for index := range addrs {
  123. // 检查ip地址判断是否回环地址
  124. if IPNet, ok := addrs[index].(*net.IPNet); ok && !IPNet.IP.IsLoopback() {
  125. if IPNet.IP.To4() != nil {
  126. return IPNet.IP, nil
  127. }
  128. }
  129. }
  130. return nil, errors.New("failed to found IP address")
  131. }