123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
-
- package csbhttp
-
- import (
- "fmt"
-
- "bytes"
- "encoding/json"
- "io/ioutil"
- "net"
- "net/http"
- "net/url"
- "strings"
- "sync"
- "time"
- )
-
- var settingMutex sync.Mutex
-
- const (
- CSB_SDK_VERSION = "1.1.0"
-
- API_NAME_KEY = "_api_name"
- VERSION_KEY = "_api_version"
- ACCESS_KEY = "_api_access_key"
- SECRET_KEY = "_api_secret_key"
- SIGNATURE_KEY = "_api_signature"
- TIMESTAMP_KEY = "_api_timestamp"
- RESTFUL_PATH_SIGNATURE_KEY = "csb_restful_path_signature_key"
- )
-
-
- type CSBHTTPSettings struct {
- ShowDebug bool
- UserAgent string
- ConnectTimeout time.Duration
- ReadWriteTimeout time.Duration
-
- Retries int
- CareResponseHttpHeader bool
- SignPath bool
-
-
-
- }
-
- var defaultSetting = CSBHTTPSettings{
- ShowDebug: true,
- UserAgent: "csbBroker",
- ConnectTimeout: 60 * time.Second,
- ReadWriteTimeout: 60 * time.Second,
- CareResponseHttpHeader: true,
- }
-
-
- func SetDefaultSetting(setting CSBHTTPSettings) {
- settingMutex.Lock()
- defer settingMutex.Unlock()
- defaultSetting = setting
- }
-
-
- func appendParams(reqUrl string, params string) string {
- if strings.Contains(reqUrl, "?") {
- return reqUrl + "&" + params
- } else {
- return reqUrl + "?" + params
- }
- }
-
-
- func parseUrlParamsMap(reqUrl string) (params map[string]string, err *HttpCallerException) {
- params = make(map[string]string)
- if strings.Contains(reqUrl, "?") {
- i := strings.Index(reqUrl, "?")
- reqUrl = string(reqUrl[i+1:])
- fmt.Println(reqUrl)
- kvs := strings.Split(reqUrl, "&")
-
- if len(kvs) > 0 {
- for _, kv := range kvs {
- i = strings.Index(kv, "=")
- if i >= 0 {
- params[string(kv[0:i])] = string(kv[i+1:])
- } else {
-
- fmt.Errorf("bad kv pair:", kv)
- }
- }
- }
- }
- return params, nil
- }
-
-
- func signParams(params map[string]string, api string, version string, ak string, sk string, time_stamp string) (headMaps map[string]string) {
- headMaps = make(map[string]string)
-
- params[API_NAME_KEY] = api
- headMaps[API_NAME_KEY] = api
-
- params[VERSION_KEY] = version
- headMaps[VERSION_KEY] = version
-
-
-
- params[TIMESTAMP_KEY] = time_stamp
- headMaps[TIMESTAMP_KEY] = time_stamp
-
- if ak != "" {
- params[ACCESS_KEY] = ak
- headMaps[ACCESS_KEY] = ak
-
- delete(params, SECRET_KEY)
- delete(params, SIGNATURE_KEY)
-
- signValue := doSign(params, sk)
-
- headMaps[SIGNATURE_KEY] = signValue
- }
-
- return headMaps
- }
-
-
- func Invoke(params HttpParams, time_stamp string) (str string, rtnHeaders map[string][]string, hcError *HttpCallerException) {
-
- rtnHeaders = make(map[string][]string)
-
- hcError = params.Validate()
- if hcError != nil {
- return str, rtnHeaders, hcError
- }
-
- _, err := url.Parse(params.requestUrl)
- if err != nil {
- return str, rtnHeaders, &HttpCallerException{CauseErr: err}
- }
-
- client := &http.Client{
- Transport: &http.Transport{
- Dial: func(netw, addr string) (net.Conn, error) {
- conn, err := net.DialTimeout(netw, addr, defaultSetting.ConnectTimeout)
- if err != nil {
- return nil, err
- }
- conn.SetDeadline(time.Now().Add(defaultSetting.ReadWriteTimeout))
- return conn, nil
- },
- ResponseHeaderTimeout: time.Second * 60,
- },
- }
-
-
-
- data := url.Values{}
- if params.params != nil {
- for k, v := range params.params {
-
- data.Set(k, v)
- }
- }
- var reqStr string
- var method string
-
- if params.method == "post" {
-
- method = "POST"
- } else {
- method = "GET"
- }
-
- reqUrl := params.requestUrl
-
- defaultContentType := "application/json;charset=utf-8"
- if params.ct.jsonBody != "" {
- json.Marshal(params.ct.jsonBody)
-
-
-
- reqStr = params.ct.jsonBody
- defaultContentType = params.ct.contentType
- reqUrl = appendParams(reqUrl, data.Encode())
- } else if params.ct.bytesBody != nil {
- reqStr = string(params.ct.bytesBody)
- defaultContentType = params.ct.contentType
- reqUrl = appendParams(reqUrl, data.Encode())
- } else {
- reqStr = data.Encode()
- }
-
- req, err := http.NewRequest(method, reqUrl, bytes.NewBufferString(reqStr))
-
- if err != nil {
- return str, rtnHeaders, &HttpCallerException{Message: "failed to construct http post request", CauseErr: err}
- }
-
-
- urlParams, hcError := parseUrlParamsMap(params.requestUrl)
- if err != nil {
- return str, rtnHeaders, hcError
- }
- printDebug("urlparams", urlParams)
- mergeTwoMaps(urlParams, params.params)
- printDebug("merged urlparams", urlParams)
- signHeaders := signParams(urlParams, params.api, params.version, params.ak, params.sk, time_stamp)
- printDebug("signHeaders", signHeaders)
-
- req.Header.Add("Content-Type", defaultContentType)
- if params.headers != nil {
- for k, v := range params.headers {
- req.Header.Add(k, v)
- }
- }
-
- if signHeaders != nil {
- for k, v := range signHeaders {
- req.Header.Add(k, v)
- }
- }
-
-
- resp, err := client.Do(req)
-
- if err != nil {
- return str, rtnHeaders, &HttpCallerException{Message: "failed to invoke http post", CauseErr: err}
- }
-
- if err != nil {
- fmt.Println(err)
- }
-
- defer resp.Body.Close()
-
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- fmt.Println(err)
- }
- str = string(body)
- if defaultSetting.CareResponseHttpHeader {
- rtnHeaders = resp.Header
- }
-
-
- return str, rtnHeaders, nil
- }
|