From fa6ac348e3befcb06c093c75d097740049d7447b Mon Sep 17 00:00:00 2001 From: gazebo Date: Thu, 16 Aug 2018 11:03:06 +0800 Subject: [PATCH] - fk. Request.Close = true for weixin api. --- platformapi/autonavi/autonavi.go | 47 ++++++----- platformapi/dadaapi/dadaapi.go | 55 +++++++------ platformapi/elmapi/elmapi.go | 123 ++++++++++++++--------------- platformapi/elmapi/elmapi_test.go | 2 +- platformapi/jdapi/jdapi.go | 48 ++++++----- platformapi/mtpsapi/mtpsapi.go | 46 ++++++----- platformapi/platformapi.go | 13 +-- platformapi/weixinapi/weixinapi.go | 72 +++++++++-------- 8 files changed, 210 insertions(+), 196 deletions(-) diff --git a/platformapi/autonavi/autonavi.go b/platformapi/autonavi/autonavi.go index 39959c64..a8e76c8c 100644 --- a/platformapi/autonavi/autonavi.go +++ b/platformapi/autonavi/autonavi.go @@ -99,27 +99,32 @@ func (a *API) AccessAPI(apiStr string, params map[string]interface{}) (retVal Re params2 := utils.MergeMaps(utils.Params2Map("key", a.key, "output", "json"), params) params2[signKey] = a.signParams(params2) - // request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(prodURL, apiStr, params2), nil) - err = platformapi.AccessPlatformAPIWithRetry(a.client, http.MethodGet, utils.GenerateGetURL(prodURL, apiStr, params2), "", nil, a.config, func(response *http.Response) (errLevel string, err error) { - jsonResult1, err := utils.HTTPResponse2Json(response) - if err != nil { - return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong - } - status := jsonResult1["status"].(string) - if status == StatusCodeSuccess { - retVal = jsonResult1 - return platformapi.ErrLevelSuccess, nil - } - infoCode := jsonResult1["infocode"].(string) - newErr := utils.NewErrorCode(jsonResult1["info"].(string), infoCode) - if _, ok := exceedLimitCodes[infoCode]; ok { - return platformapi.ErrLevelExceedLimit, newErr - } else if _, ok := canRetryCodes[infoCode]; ok { - return platformapi.ErrLevelRecoverableErr, newErr - } else { - return platformapi.ErrLevelCodeIsNotOK, newErr - } - }) + err = platformapi.AccessPlatformAPIWithRetry(a.client, + func() *http.Request { + request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(prodURL, apiStr, params2), nil) + return request + }, + a.config, + func(response *http.Response) (errLevel string, err error) { + jsonResult1, err := utils.HTTPResponse2Json(response) + if err != nil { + return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong + } + status := jsonResult1["status"].(string) + if status == StatusCodeSuccess { + retVal = jsonResult1 + return platformapi.ErrLevelSuccess, nil + } + infoCode := jsonResult1["infocode"].(string) + newErr := utils.NewErrorCode(jsonResult1["info"].(string), infoCode) + if _, ok := exceedLimitCodes[infoCode]; ok { + return platformapi.ErrLevelExceedLimit, newErr + } else if _, ok := canRetryCodes[infoCode]; ok { + return platformapi.ErrLevelRecoverableErr, newErr + } else { + return platformapi.ErrLevelCodeIsNotOK, newErr + } + }) return retVal, err } diff --git a/platformapi/dadaapi/dadaapi.go b/platformapi/dadaapi/dadaapi.go index 91fb8372..790c8c8e 100644 --- a/platformapi/dadaapi/dadaapi.go +++ b/platformapi/dadaapi/dadaapi.go @@ -1,6 +1,7 @@ package dadaapi import ( + "bytes" "crypto/md5" "fmt" "net/http" @@ -107,32 +108,36 @@ func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal *R } params2[signKey] = a.signParams(params2) params2Bytes := utils.MustMarshal(params2) - // request, _ := http.NewRequest(http.MethodPost, a.url+"/"+action, bytes.NewReader(params2Bytes)) - header := make(http.Header) - header.Set("Content-Type", "application/json") - err = platformapi.AccessPlatformAPIWithRetry(a.client, http.MethodPost, a.url+"/"+action, string(params2Bytes), header, a.config, func(response *http.Response) (result string, err error) { - jsonResult1, err := utils.HTTPResponse2Json(response) - if err != nil { - return platformapi.ErrLevelGeneralFail, err - } - code := int(utils.MustInterface2Int64(jsonResult1["code"])) - retVal = &ResponseResult{ - Code: code, - ErrorCode: code, - Msg: jsonResult1["msg"].(string), - Status: jsonResult1["status"].(string), - } - if code == ResponseCodeSuccess { - retVal.Result = jsonResult1["result"] - return platformapi.ErrLevelSuccess, nil - } - newErr := utils.NewErrorIntCode(retVal.Msg, code) - if code == ResponseCodeRetryLater || code == ResponseCodeNetworkErr { - return platformapi.ErrLevelRecoverableErr, newErr - } - return platformapi.ErrLevelCodeIsNotOK, newErr - }) + err = platformapi.AccessPlatformAPIWithRetry(a.client, + func() *http.Request { + request, _ := http.NewRequest(http.MethodPost, a.url+"/"+action, bytes.NewReader(params2Bytes)) + request.Header.Set("Content-Type", "application/json") + return request + }, + a.config, + func(response *http.Response) (result string, err error) { + jsonResult1, err := utils.HTTPResponse2Json(response) + if err != nil { + return platformapi.ErrLevelGeneralFail, err + } + code := int(utils.MustInterface2Int64(jsonResult1["code"])) + retVal = &ResponseResult{ + Code: code, + ErrorCode: code, + Msg: jsonResult1["msg"].(string), + Status: jsonResult1["status"].(string), + } + if code == ResponseCodeSuccess { + retVal.Result = jsonResult1["result"] + return platformapi.ErrLevelSuccess, nil + } + newErr := utils.NewErrorIntCode(retVal.Msg, code) + if code == ResponseCodeRetryLater || code == ResponseCodeNetworkErr { + return platformapi.ErrLevelRecoverableErr, newErr + } + return platformapi.ErrLevelCodeIsNotOK, newErr + }) return retVal, err } diff --git a/platformapi/elmapi/elmapi.go b/platformapi/elmapi/elmapi.go index 261dc97c..658c42f9 100644 --- a/platformapi/elmapi/elmapi.go +++ b/platformapi/elmapi/elmapi.go @@ -1,6 +1,7 @@ package elmapi import ( + "bytes" "crypto/md5" "encoding/base64" "fmt" @@ -145,38 +146,42 @@ func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal *R } pl.Signature = a.signParams(action, pl) + plBytes := utils.MustMarshal(pl) - bodyStr := string(utils.MustMarshal(pl)) - // request, _ := http.NewRequest(http.MethodPost, a.fullURL, strings.NewReader(bodyStr)) - header := make(http.Header) - header.Set("Content-Type", "application/json; charset=utf-8") - header.Set("Content-Encoding", "gzip, deflate") - header.Set("User-Agent", "eleme-golang-api") - err = platformapi.AccessPlatformAPIWithRetry(a.client, http.MethodPost, a.fullURL, bodyStr, header, a.config, func(response *http.Response) (result string, err error) { - jsonResult1, err := utils.HTTPResponse2Json(response) - if err != nil { - return platformapi.ErrLevelGeneralFail, err - } - resultError, _ := jsonResult1["error"].(map[string]interface{}) - retVal = &ResponseResult{ - ID: jsonResult1["id"].(string), - Error: resultError, - Result: jsonResult1["result"], - } - errinfoMap := retVal.Error - if errinfoMap == nil { - return platformapi.ErrLevelSuccess, nil - } - code := errinfoMap["code"].(string) - newErr := utils.NewErrorCode(errinfoMap["message"].(string), code) - if code == "EXCEED_LIMIT" { - return platformapi.ErrLevelExceedLimit, newErr - } else if code == "SERVER_ERROR" || code == "BIZ_SYSTEM_ERROR" || code == "BIZ_1006" || code == "BUSINESS_ERROR" { - return platformapi.ErrLevelRecoverableErr, newErr - } else { - return platformapi.ErrLevelCodeIsNotOK, newErr - } - }) + err = platformapi.AccessPlatformAPIWithRetry(a.client, + func() *http.Request { + request, _ := http.NewRequest(http.MethodPost, a.fullURL, bytes.NewReader(plBytes)) + request.Header.Set("Content-Type", "application/json; charset=utf-8") + request.Header.Set("Content-Encoding", "gzip, deflate") + request.Header.Set("User-Agent", "eleme-golang-api") + return request + }, + a.config, + func(response *http.Response) (result string, err error) { + jsonResult1, err := utils.HTTPResponse2Json(response) + if err != nil { + return platformapi.ErrLevelGeneralFail, err + } + resultError, _ := jsonResult1["error"].(map[string]interface{}) + retVal = &ResponseResult{ + ID: jsonResult1["id"].(string), + Error: resultError, + Result: jsonResult1["result"], + } + errinfoMap := retVal.Error + if errinfoMap == nil { + return platformapi.ErrLevelSuccess, nil + } + code := errinfoMap["code"].(string) + newErr := utils.NewErrorCode(errinfoMap["message"].(string), code) + if code == "EXCEED_LIMIT" { + return platformapi.ErrLevelExceedLimit, newErr + } else if code == "SERVER_ERROR" || code == "BIZ_SYSTEM_ERROR" || code == "BIZ_1006" || code == "BUSINESS_ERROR" { + return platformapi.ErrLevelRecoverableErr, newErr + } else { + return platformapi.ErrLevelCodeIsNotOK, newErr + } + }) return retVal, err } @@ -195,37 +200,31 @@ func (a *API) getAuthorizeURL() string { } func (a *API) AcccessAPI2(baseURL string, params map[string]interface{}, method string) (retVal map[string]interface{}, err error) { - // var request *http.Request - body := "" - requestURL := baseURL - var header http.Header - if method == http.MethodPost { - params2 := make(url.Values) - for k, v := range params { - params2[k] = []string{fmt.Sprint(v)} - } - body = params2.Encode() - // request, _ = http.NewRequest(http.MethodPost, baseURL, strings.NewReader(params2.Encode())) - header = make(http.Header) - header.Set("Content-Type", "application/x-www-form-urlencoded") - header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(a.appKey+":"+a.secret))) - } else { - requestURL = utils.GenerateGetURL(baseURL, "", params) - // fullURL, _ := url.Parse(utils.GenerateGetURL(baseURL, "", params)) - // // baseapi.SugarLogger.Debug(url.String()) - // request = &http.Request{ - // Method: http.MethodGet, - // URL: fullURL, - // } - } - err = platformapi.AccessPlatformAPIWithRetry(a.client, method, requestURL, body, header, a.config, func(response *http.Response) (result string, err error) { - jsonResult1, err := utils.HTTPResponse2Json(response) - if err != nil { - return platformapi.ErrLevelGeneralFail, err - } - retVal = jsonResult1 - return platformapi.ErrLevelSuccess, nil - }) + err = platformapi.AccessPlatformAPIWithRetry(a.client, + func() *http.Request { + var request *http.Request + if method == http.MethodPost { + params2 := make(url.Values) + for k, v := range params { + params2[k] = []string{fmt.Sprint(v)} + } + request, _ = http.NewRequest(method, baseURL, strings.NewReader(params2.Encode())) + request.Header.Set("Content-Type", "application/x-www-form-urlencoded") + request.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(a.appKey+":"+a.secret))) + } else { + request, _ = http.NewRequest(method, utils.GenerateGetURL(baseURL, "", params), nil) + } + return request + }, + a.config, + func(response *http.Response) (result string, err error) { + jsonResult1, err := utils.HTTPResponse2Json(response) + if err != nil { + return platformapi.ErrLevelGeneralFail, err + } + retVal = jsonResult1 + return platformapi.ErrLevelSuccess, nil + }) return retVal, err } diff --git a/platformapi/elmapi/elmapi_test.go b/platformapi/elmapi/elmapi_test.go index 888de393..0165e015 100644 --- a/platformapi/elmapi/elmapi_test.go +++ b/platformapi/elmapi/elmapi_test.go @@ -23,7 +23,7 @@ func init() { // sandbox elmapi = New("623c0904c0d2499e83df15b62902eb65", "RwT214gAsS", "56afff4b9ebd8a7eb532d18fa33f17be57f9b9db", false) // prod - // elmapi = New("b0168650ad84a44e49d7613e88d31572", "KLRDcOZGrk", "1fc221f8265506531da36fb613d5f5ad673f2e9a", true) + // elmapi = New("fee89f45d06f93037dd314ceb78fde7b", "KLRDcOZGrk", "1fc221f8265506531da36fb613d5f5ad673f2e9a", true) } func TestTest(t *testing.T) { diff --git a/platformapi/jdapi/jdapi.go b/platformapi/jdapi/jdapi.go index b0c4f2c4..5c1a9e7f 100644 --- a/platformapi/jdapi/jdapi.go +++ b/platformapi/jdapi/jdapi.go @@ -143,27 +143,33 @@ func (a *API) AccessAPI(apiStr string, jdParams map[string]interface{}) (retVal params["timestamp"] = utils.GetCurTimeStr() sign := a.signParams(params) params[signKey] = sign - // request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(prodURL, apiStr, params), nil) - //request.Close = true //todo 为了性能考虑 - err = platformapi.AccessPlatformAPIWithRetry(a.client, http.MethodGet, utils.GenerateGetURL(prodURL, apiStr, params), "", nil, a.config, func(response *http.Response) (errLevel string, err error) { - jsonResult1, err := utils.HTTPResponse2Json(response) - if err != nil { - return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong - } - code := jsonResult1["code"].(string) - if code == ResponseCodeSuccess { - retVal = jsonResult1 - return platformapi.ErrLevelSuccess, nil - } - newErr := utils.NewErrorCode(jsonResult1["msg"].(string), code) - if _, ok := exceedLimitCodes[code]; ok { - return platformapi.ErrLevelExceedLimit, newErr - } else if _, ok := canRetryCodes[code]; ok { - return platformapi.ErrLevelRecoverableErr, newErr - } else { - return platformapi.ErrLevelCodeIsNotOK, newErr - } - }) + + err = platformapi.AccessPlatformAPIWithRetry(a.client, + func() *http.Request { + request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(prodURL, apiStr, params), nil) + // request.Close = true //todo 为了性能考虑还是不要关闭 + return request + }, + a.config, + func(response *http.Response) (errLevel string, err error) { + jsonResult1, err := utils.HTTPResponse2Json(response) + if err != nil { + return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong + } + code := jsonResult1["code"].(string) + if code == ResponseCodeSuccess { + retVal = jsonResult1 + return platformapi.ErrLevelSuccess, nil + } + newErr := utils.NewErrorCode(jsonResult1["msg"].(string), code) + if _, ok := exceedLimitCodes[code]; ok { + return platformapi.ErrLevelExceedLimit, newErr + } else if _, ok := canRetryCodes[code]; ok { + return platformapi.ErrLevelRecoverableErr, newErr + } else { + return platformapi.ErrLevelCodeIsNotOK, newErr + } + }) return retVal, err } diff --git a/platformapi/mtpsapi/mtpsapi.go b/platformapi/mtpsapi/mtpsapi.go index 68417e80..a0939bb4 100644 --- a/platformapi/mtpsapi/mtpsapi.go +++ b/platformapi/mtpsapi/mtpsapi.go @@ -193,29 +193,33 @@ func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal *R params2["version"] = []string{"1.0"} params2[signKey] = []string{a.signParams(params2)} // baseapi.SugarLogger.Debug(params2.Encode()) - // request, _ := http.NewRequest(http.MethodPost, mtpsAPIURL+"/"+action, strings.NewReader(params2.Encode())) - header := make(http.Header) - header.Set("Content-Type", "application/x-www-form-urlencoded") - err = platformapi.AccessPlatformAPIWithRetry(a.client, http.MethodPost, mtpsAPIURL+"/"+action, params2.Encode(), header, a.config, func(response *http.Response) (result string, err error) { - jsonResult1, err := utils.HTTPResponse2Json(response) - if err != nil { - return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong - } - code := int(utils.MustInterface2Int64(jsonResult1["code"])) - retVal = &ResponseResult{ - Code: code, - } - if code == ResponseCodeSuccess { - if innerData, ok := jsonResult1["data"]; ok { - retVal.Data, _ = innerData.(map[string]interface{}) + err = platformapi.AccessPlatformAPIWithRetry(a.client, + func() *http.Request { + request, _ := http.NewRequest(http.MethodPost, mtpsAPIURL+"/"+action, strings.NewReader(params2.Encode())) + request.Header.Set("Content-Type", "application/x-www-form-urlencoded") + return request + }, + a.config, + func(response *http.Response) (result string, err error) { + jsonResult1, err := utils.HTTPResponse2Json(response) + if err != nil { + return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong } - return platformapi.ErrLevelSuccess, nil - } - retVal.Message = jsonResult1["message"].(string) - newErr := utils.NewErrorIntCode(retVal.Message, code) - return platformapi.ErrLevelCodeIsNotOK, newErr - }) + code := int(utils.MustInterface2Int64(jsonResult1["code"])) + retVal = &ResponseResult{ + Code: code, + } + if code == ResponseCodeSuccess { + if innerData, ok := jsonResult1["data"]; ok { + retVal.Data, _ = innerData.(map[string]interface{}) + } + return platformapi.ErrLevelSuccess, nil + } + retVal.Message = jsonResult1["message"].(string) + newErr := utils.NewErrorIntCode(retVal.Message, code) + return platformapi.ErrLevelCodeIsNotOK, newErr + }) return retVal, err } diff --git a/platformapi/platformapi.go b/platformapi/platformapi.go index a06b1021..0e8d474b 100644 --- a/platformapi/platformapi.go +++ b/platformapi/platformapi.go @@ -4,7 +4,6 @@ import ( "errors" "net" "net/http" - "strings" "time" "github.com/fatih/structs" @@ -73,19 +72,11 @@ func init() { structs.DefaultTagName = "json" } -func AccessPlatformAPIWithRetry(client *http.Client, method, requestURL, body string, header http.Header, config *APIConfig, handleResponse func(response *http.Response) (string, error)) error { +func AccessPlatformAPIWithRetry(client *http.Client, handleRequest func() *http.Request, config *APIConfig, handleResponse func(response *http.Response) (string, error)) error { exceedLimitRetryCount := 0 recoverableErrorRetryCount := 0 - var request *http.Request for { - if body != "" { - request, _ = http.NewRequest(method, requestURL, strings.NewReader(body)) - } else { - request, _ = http.NewRequest(method, requestURL, nil) - } - if header != nil { - request.Header = header - } + request := handleRequest() response, err := client.Do(request) if err != nil { baseapi.SugarLogger.Debugf("AccessPlatformAPIWithRetry client.Get return err:%v", err) diff --git a/platformapi/weixinapi/weixinapi.go b/platformapi/weixinapi/weixinapi.go index 729e9c94..f5926c79 100644 --- a/platformapi/weixinapi/weixinapi.go +++ b/platformapi/weixinapi/weixinapi.go @@ -2,6 +2,7 @@ package weixinapi import ( "net/http" + "strings" "sync" "git.rosy.net.cn/baseapi/platformapi" @@ -90,43 +91,46 @@ func (a *API) AccessAPI(action string, params map[string]interface{}, body strin } fullURL := utils.GenerateGetURL(prodURL, action, params2) // baseapi.SugarLogger.Debug(fullURL) - // var request *http.Request - var method string - if body == "" { - method = http.MethodGet - // request, _ = http.NewRequest(http.MethodGet, fullURL, nil) - } else { - method = http.MethodPost - // request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(body)) - } - // request.Close = true // todo try to fix EOF error when accessing weixin api. - err = platformapi.AccessPlatformAPIWithRetry(a.client, method, fullURL, body, nil, a.config, func(response *http.Response) (result string, err error) { - jsonResult1, err := utils.HTTPResponse2Json(response) - if err != nil { - return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong - } - var errInfo *ErrorInfo - // 微信的返回值,在错误与正常情况下,结构是完全不一样的 - if errCode, ok := jsonResult1["errcode"]; ok { - errInfo = &ErrorInfo{ - ErrCode: int(utils.MustInterface2Int64(errCode)), - ErrMsg: jsonResult1["errmsg"].(string), + + err = platformapi.AccessPlatformAPIWithRetry(a.client, + func() *http.Request { + var request *http.Request + if body == "" { + request, _ = http.NewRequest(http.MethodGet, fullURL, nil) + } else { + request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(body)) } - if errInfo.ErrCode == 0 { + request.Close = true // todo try to fix EOF error when accessing weixin api. + return request + }, + a.config, + func(response *http.Response) (result string, err error) { + jsonResult1, err := utils.HTTPResponse2Json(response) + if err != nil { + return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong + } + var errInfo *ErrorInfo + // 微信的返回值,在错误与正常情况下,结构是完全不一样的 + if errCode, ok := jsonResult1["errcode"]; ok { + errInfo = &ErrorInfo{ + ErrCode: int(utils.MustInterface2Int64(errCode)), + ErrMsg: jsonResult1["errmsg"].(string), + } + if errInfo.ErrCode == 0 { + retVal = jsonResult1 + } + } else { retVal = jsonResult1 } - } else { - retVal = jsonResult1 - } - if retVal != nil { - return platformapi.ErrLevelSuccess, nil - } - newErr := utils.NewErrorIntCode(errInfo.ErrMsg, errInfo.ErrCode) - if errInfo.ErrCode == ResponseCodeBusy { - return platformapi.ErrLevelRecoverableErr, newErr - } - return platformapi.ErrLevelCodeIsNotOK, newErr - }) + if retVal != nil { + return platformapi.ErrLevelSuccess, nil + } + newErr := utils.NewErrorIntCode(errInfo.ErrMsg, errInfo.ErrCode) + if errInfo.ErrCode == ResponseCodeBusy { + return platformapi.ErrLevelRecoverableErr, newErr + } + return platformapi.ErrLevelCodeIsNotOK, newErr + }) return retVal, err }