|
- package topsdk
-
- import (
- "bytes"
- zhios_third_party_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/utils"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "mime/multipart"
- "net"
- "net/http"
- "net/url"
- "strings"
- "time"
- )
-
- type TopClient struct {
- AppKey string
- AppSecret string
- ServerUrl string
- Format string
- SignMethod string
- ConnectTimeout int64
- ReadTimeout int64
- Version string
- Simplify bool
- httpClient *http.Client
- }
- type HttpTransportConfig struct {
- DialTimeout int64
- KeepAlive int64
- MaxIdleConns int
- MaxIdleConnsPerHost int
- IdleConnTimeout int64
- MaxConnsPerHost int
- }
-
- func NewDefaultTopClient(AppKey string, AppSecret string, ServerUrl string, connectTimeount int64, readTimeout int64) TopClient {
- var httpTransportConfig = &HttpTransportConfig{
- DialTimeout: 30000,
- KeepAlive: 30000,
- MaxIdleConns: 100,
- MaxIdleConnsPerHost: 50,
- IdleConnTimeout: 30000,
- }
- return NewTopClientWithConfig(AppKey, AppSecret, ServerUrl, connectTimeount, readTimeout, httpTransportConfig)
-
- }
-
- func NewTopClientWithConfig(AppKey string, AppSecret string, ServerUrl string, connectTimeount int64, readTimeout int64, httpTransportConfig *HttpTransportConfig) TopClient {
- httpClient := http.Client{
- Timeout: time.Duration(connectTimeount) * time.Millisecond,
- Transport: &http.Transport{
- DialContext: (&net.Dialer{
- Timeout: time.Duration(httpTransportConfig.DialTimeout) * time.Millisecond,
- KeepAlive: time.Duration(httpTransportConfig.KeepAlive) * time.Millisecond,
- }).DialContext,
- ForceAttemptHTTP2: true,
- MaxIdleConns: httpTransportConfig.MaxIdleConns,
- MaxIdleConnsPerHost: httpTransportConfig.MaxIdleConnsPerHost,
- IdleConnTimeout: time.Duration(httpTransportConfig.IdleConnTimeout) * time.Millisecond,
- TLSHandshakeTimeout: 10 * time.Second,
- ExpectContinueTimeout: 1 * time.Second,
- },
- }
- return TopClient{
- AppKey: AppKey,
- AppSecret: AppSecret,
- ServerUrl: ServerUrl,
- Format: ApiFormat,
- SignMethod: SignMethod,
- ConnectTimeout: connectTimeount,
- ReadTimeout: readTimeout,
- Version: TopVersion,
- Simplify: true,
- httpClient: &httpClient,
- }
- }
-
- func (client *TopClient) ExecuteWithSession(method string, data map[string]interface{}, fileData map[string]interface{}, session string) (string, error) {
- var publicParam = make(map[string]interface{})
- publicParam["method"] = method
- publicParam["app_key"] = client.AppKey
- publicParam["timestamp"] = time.Now().Format(DateFormat)
- publicParam["v"] = client.Version
- publicParam["sign_method"] = client.SignMethod
- publicParam["format"] = client.Format
- publicParam["simplify"] = client.Simplify
- publicParam["partner_id"] = SdkVersion
- if session != "" {
- publicParam["session"] = session
- }
- sign := zhios_third_party_utils.GetSign(publicParam, data, client.AppSecret)
- // 构建url
- serverUrl, _ := url.Parse(client.ServerUrl)
- urlValues := url.Values{}
- urlValues.Add("sign", sign)
- for k, v := range publicParam {
- urlValues.Add(k, fmt.Sprint(v))
- }
- serverUrl.RawQuery = urlValues.Encode()
- urlPath := serverUrl.String()
- // 构建body
- if fileData != nil && len(fileData) > 0 {
- return doPostWithFile(urlPath, data, fileData, client.httpClient)
- } else {
- return doPost(urlPath, data, client.httpClient)
- }
-
- }
-
- func doPost(urlPath string, data map[string]interface{}, httpClient *http.Client) (string, error) {
- bodyParam := url.Values{}
- for k, v := range data {
- bodyParam.Add(k, fmt.Sprint(v))
- }
- resp, err := httpClient.Post(urlPath, "application/x-www-form-urlencoded", strings.NewReader(bodyParam.Encode()))
- if resp != nil {
- defer resp.Body.Close()
- }
- if err != nil {
- log.Println("http.PostForm error", err)
- return "", err
- }
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- log.Println("ioutil.ReadAll", err)
- return "", err
- }
- return string(body), nil
- }
-
- func doPostWithFile(urlPath string, data map[string]interface{}, fileData map[string]interface{}, httpClient *http.Client) (string, error) {
- bodyBuf := &bytes.Buffer{}
- writer := multipart.NewWriter(bodyBuf)
- for k, v := range data {
- err := writer.WriteField(k, fmt.Sprint(v))
- if err != nil {
- return "", err
- }
- }
- for k, v := range fileData {
- value, ok := v.([]byte)
- if ok {
- fileWriter, err := writer.CreateFormFile(k, "file")
- if err != nil {
- return "", err
- }
- _, err = io.Copy(fileWriter, bytes.NewReader(value))
- if err != nil {
- return "", err
- }
- } else {
- value, ok := v.(zhios_third_party_utils.FileItem)
- if ok {
- fileWriter, err := writer.CreateFormFile(k, value.FileName)
- if err != nil {
- return "", err
- }
- _, err = io.Copy(fileWriter, bytes.NewReader(value.Content))
- if err != nil {
- return "", err
- }
- }
- }
- }
-
- err := writer.Close()
- if err != nil {
- return "", err
- }
-
- resp, err := httpClient.Post(urlPath, writer.FormDataContentType(), bodyBuf)
- if err != nil {
- log.Println("http.PostForm error", err)
- return "", err
- }
- defer resp.Body.Close()
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- log.Println("ioutil.ReadAll", err)
- return "", err
- }
- return string(body), nil
- }
-
- func (client *TopClient) Execute(method string, data map[string]interface{}, fileData map[string]interface{}) (string, error) {
- return client.ExecuteWithSession(method, data, fileData, "")
- }
|