123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- package util
- import (
- "bytes"
- "crypto/tls"
- "encoding/xml"
- "errors"
- "fmt"
- "io/ioutil"
- "math/rand"
- "net"
- "net/http"
- "net/url"
- "time"
- )
- // TokenAPI 获取带 token 的 API 地址
- func TokenAPI(api, token string) (string, error) {
- u, err := url.Parse(api)
- if err != nil {
- return "", err
- }
- query := u.Query()
- query.Set("access_token", token)
- u.RawQuery = query.Encode()
- return u.String(), nil
- }
- // GetQuery returns url query value
- func GetQuery(req *http.Request, key string) string {
- if values, ok := req.URL.Query()[key]; ok && len(values) > 0 {
- return values[0]
- }
- return ""
- }
- // RandomString random string generator
- //
- // @ln length of return string
- func RandomString(ln int) string {
- letters := []rune("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
- b := make([]rune, ln)
- r := rand.New(rand.NewSource(time.Now().UnixNano()))
- for i := range b {
- b[i] = letters[r.Intn(len(letters))]
- }
- return string(b)
- }
- // PostXML perform a HTTP/POST request with XML body
- func PostXML(uri string, obj interface{}) ([]byte, error) {
- data, err := xml.Marshal(obj)
- if err != nil {
- return nil, err
- }
- body := bytes.NewBuffer(data)
- res, err := http.Post(uri, "application/xml; charset=utf-8", body)
- if err != nil {
- return nil, err
- }
- defer res.Body.Close()
- if res.StatusCode != http.StatusOK {
- return nil, fmt.Errorf("http code error : uri=%v , statusCode=%v", uri, res.StatusCode)
- }
- return ioutil.ReadAll(res.Body)
- }
- // TSLPostXML ...
- func TSLPostXML(uri string, obj interface{}, certPath, keyPath string) ([]byte, error) {
- data, err := xml.Marshal(obj)
- if err != nil {
- return nil, err
- }
- body := bytes.NewBuffer(data)
- cli, err := NewTLSClient(certPath, keyPath)
- if err != nil {
- return nil, err
- }
- res, err := cli.Post(uri, "application/xml; charset=utf-8", body)
- if err != nil {
- return nil, err
- }
- defer res.Body.Close()
- if res.StatusCode != http.StatusOK {
- return nil, fmt.Errorf("http code error : uri=%v , statusCode=%v", uri, res.StatusCode)
- }
- return ioutil.ReadAll(res.Body)
- }
- // NewTLSClient 创建支持双向证书认证的 http.Client.
- func NewTLSClient(certPath, keyPath string) (httpClient *http.Client, err error) {
- cert, err := tls.LoadX509KeyPair(certPath, keyPath)
- if err != nil {
- return nil, err
- }
- tlsConfig := &tls.Config{
- Certificates: []tls.Certificate{cert},
- }
- return newTLSClient(tlsConfig)
- }
- func newTLSClient(tlsConfig *tls.Config) (*http.Client, error) {
- dialTLS := func(network, addr string) (net.Conn, error) {
- return tls.DialWithDialer(&net.Dialer{
- Timeout: 5 * time.Second,
- KeepAlive: 30 * time.Second,
- }, network, addr, tlsConfig)
- }
- return &http.Client{
- Transport: &http.Transport{
- Proxy: http.ProxyFromEnvironment,
- DialContext: (&net.Dialer{
- Timeout: 5 * time.Second,
- KeepAlive: 30 * time.Second,
- DualStack: true,
- }).DialContext,
- DialTLS: dialTLS,
- MaxIdleConns: 100,
- IdleConnTimeout: 90 * time.Second,
- ExpectContinueTimeout: 1 * time.Second,
- },
- }, nil
- }
- // FetchIP current IP address
- func FetchIP() (net.IP, error) {
- addrs, err := net.InterfaceAddrs()
- if err != nil {
- return nil, err
- }
- for index := range addrs {
- // 检查ip地址判断是否回环地址
- if IPNet, ok := addrs[index].(*net.IPNet); ok && !IPNet.IP.IsLoopback() {
- if IPNet.IP.To4() != nil {
- return IPNet.IP, nil
- }
- }
- }
- return nil, errors.New("failed to found IP address")
- }
|