Compare commits

..

1 Commits

Author SHA1 Message Date
yndu13 8ac445bc69 [v2.x]Rebuild retry policy 2024-03-19 21:22:17 +08:00
15 changed files with 155 additions and 531 deletions
-35
View File
@@ -1,35 +0,0 @@
{
"scope": "darabonba",
"name": "HttpClient",
"version": "0.0.1",
"main": "./main.dara",
"maintainers": [
{
"name": "Alibaba Cloud SDK",
"email": "sdk-team@alibabacloud.com"
}
],
"libraries": {
},
"releases": {
"go": "github.com/alibabacloud-go/tea/tea:v1.2.3-0.20240528133401-8788f78f9c46"
},
"go": {
"interface": true,
"clientName": "HttpClient",
"typedef": {
"HttpRequest": {
"import": "net/http",
"type": "http.Request"
},
"HttpResponse": {
"import": "net/http",
"type": "http.Response"
},
"HttpTransport": {
"import": "net/http",
"type": "http.Transport"
}
}
}
}
-8
View File
@@ -1,8 +0,0 @@
typedef HttpRequest;
typedef HttpResponse;
typedef HttpTransport;
init(){
}
async function call(request: HttpRequest, transport: HttpTransport): HttpResponse;
+2 -2
View File
@@ -1,4 +1,4 @@
module github.com/alibabacloud-go/tea
module github.com/alibabacloud-go/tea/v2
go 1.14
@@ -6,5 +6,5 @@ require (
github.com/alibabacloud-go/debug v1.0.0
github.com/json-iterator/go v1.1.12
github.com/modern-go/reflect2 v1.0.2
golang.org/x/net v0.22.0
golang.org/x/net v0.20.0
)
+8 -9
View File
@@ -1,6 +1,7 @@
github.com/alibabacloud-go/debug v1.0.0 h1:3eIEQWfay1fB24PQIEzXAswlVJtdQok8f3EVN5VrBnA=
github.com/alibabacloud-go/debug v1.0.0/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@@ -9,14 +10,15 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OH
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -24,9 +26,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -37,14 +38,12 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"reflect"
"testing"
"github.com/alibabacloud-go/tea/utils"
"github.com/alibabacloud-go/tea/v2/utils"
)
func TestBackoffPolicy(t *testing.T) {
+21 -55
View File
@@ -22,35 +22,14 @@ import (
"time"
"github.com/alibabacloud-go/debug/debug"
"github.com/alibabacloud-go/tea/utils"
"github.com/alibabacloud-go/tea/v2/utils"
"golang.org/x/net/proxy"
)
var debugLog = debug.Init("tea")
type HttpRequest interface {
}
type HttpResponse interface {
}
type HttpClient interface {
Call(request *http.Request, transport *http.Transport) (response *http.Response, err error)
}
type teaClient struct {
sync.Mutex
httpClient *http.Client
ifInit bool
}
func (client *teaClient) Call(request *http.Request, transport *http.Transport) (response *http.Response, err error) {
response, err = client.httpClient.Do(request)
return
}
var hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) {
var hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) {
return fn
}
@@ -100,7 +79,12 @@ type RuntimeObject struct {
Tracker *utils.ReaderTracker `json:"tracker" xml:"tracker"`
Logger *utils.Logger `json:"logger" xml:"logger"`
RetryOptions *RetryOptions `json:"retryOptions" xml:"retryOptions"`
HttpClient
}
type teaClient struct {
sync.Mutex
httpClient *http.Client
ifInit bool
}
var clientPool = &sync.Map{}
@@ -144,9 +128,6 @@ func NewRuntimeObject(runtime map[string]interface{}) *RuntimeObject {
if runtime["logger"] != nil {
runtimeObject.Logger = runtime["logger"].(*utils.Logger)
}
if runtime["httpClient"] != nil {
runtimeObject.HttpClient = runtime["httpClient"].(HttpClient)
}
return runtimeObject
}
@@ -198,8 +179,8 @@ func getTeaClient(tag string) *teaClient {
return client.(*teaClient)
}
// DoAction is used send request to server
func DoAction(request *Request, runtimeObject *RuntimeObject) (response *Response, err error) {
// DoRequest is used send request to server
func DoRequest(request *Request, runtimeObject *RuntimeObject) (response *Response, err error) {
if runtimeObject == nil {
runtimeObject = &RuntimeObject{}
}
@@ -247,27 +228,19 @@ func DoAction(request *Request, runtimeObject *RuntimeObject) (response *Respons
return
}
httpRequest.Host = StringValue(request.Domain)
var client HttpClient
if runtimeObject.HttpClient == nil {
client = getTeaClient(runtimeObject.getClientTag(StringValue(request.Domain)))
} else {
client = runtimeObject.HttpClient
}
trans, err := getHttpTransport(request, runtimeObject)
if err != nil {
return
}
if defaultClient, ok := client.(*teaClient); ok {
defaultClient.Lock()
if !defaultClient.ifInit || defaultClient.httpClient.Transport == nil {
defaultClient.httpClient.Transport = trans
client := getTeaClient(runtimeObject.getClientTag(StringValue(request.Domain)))
client.Lock()
if !client.ifInit {
trans, err := getHttpTransport(request, runtimeObject)
if err != nil {
return nil, err
}
defaultClient.httpClient.Timeout = time.Duration(IntValue(runtimeObject.ReadTimeout)) * time.Millisecond
defaultClient.ifInit = true
defaultClient.Unlock()
client.httpClient.Timeout = time.Duration(IntValue(runtimeObject.ReadTimeout)) * time.Millisecond
client.httpClient.Transport = trans
client.ifInit = true
}
client.Unlock()
for key, value := range request.Headers {
if value == nil || key == "content-length" {
continue
@@ -289,7 +262,7 @@ func DoAction(request *Request, runtimeObject *RuntimeObject) (response *Respons
putMsgToMap(fieldMap, httpRequest)
startTime := time.Now()
fieldMap["{start_time}"] = startTime.Format("2006-01-02 15:04:05")
res, err := hookDo(client.Call)(httpRequest, trans)
res, err := hookDo(client.httpClient.Do)(httpRequest)
fieldMap["{cost}"] = time.Since(startTime).String()
completedBytes := int64(0)
if runtimeObject.Tracker != nil {
@@ -317,13 +290,6 @@ func DoAction(request *Request, runtimeObject *RuntimeObject) (response *Respons
return
}
// DoRequest is used send request to server
func DoRequest(request *Request, requestRuntime map[string]interface{}) (response *Response, err error) {
runtimeObject := NewRuntimeObject(requestRuntime)
response, err = DoAction(request, runtimeObject)
return
}
func getHttpTransport(req *Request, runtime *RuntimeObject) (*http.Transport, error) {
trans := new(http.Transport)
httpProxy, err := getHttpProxy(StringValue(req.Protocol), StringValue(req.Domain), runtime)
+24 -131
View File
@@ -15,7 +15,7 @@ import (
"testing"
"time"
"github.com/alibabacloud-go/tea/utils"
"github.com/alibabacloud-go/tea/v2/utils"
)
type test struct {
@@ -267,8 +267,8 @@ DEMilhlFY+o9mqCygFVxuvHtQVhpPS938H2h7/P6pXN65jK2Y5hHefZEELq9ulQe
func Test_DoRequest(t *testing.T) {
origTestHookDo := hookDo
defer func() { hookDo = origTestHookDo }()
hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) {
return func(req *http.Request, transport *http.Transport) (*http.Response, error) {
hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) {
return func(req *http.Request) (*http.Response, error) {
return mockResponse(200, ``, errors.New("Internal error"))
}
}
@@ -278,113 +278,6 @@ func Test_DoRequest(t *testing.T) {
utils.AssertNil(t, resp)
utils.AssertEqual(t, `net/http: invalid method "TEA TEST"`, err.Error())
request.Method = String("")
request.Protocol = String("https")
request.Query = map[string]*string{
"tea": String("test"),
}
runtimeObj["httpsProxy"] = "# #%gfdf"
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, resp)
utils.AssertContains(t, err.Error(), `invalid URL escape "%gf"`)
request.Pathname = String("?log")
request.Headers["tea"] = String("")
request.Headers["content-length"] = nil
runtimeObj["httpsProxy"] = "http://someuser:somepassword@ecs.aliyun.com"
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, resp)
utils.AssertEqual(t, `Internal error`, err.Error())
request.Headers["host"] = String("tea-cn-hangzhou.aliyuncs.com:80")
request.Headers["user-agent"] = String("test")
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, resp)
utils.AssertEqual(t, `Internal error`, err.Error())
runtimeObj["socks5Proxy"] = "# #%gfdf"
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, resp)
utils.AssertContains(t, err.Error(), ` invalid URL escape "%gf"`)
hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) {
return func(req *http.Request, transport *http.Transport) (*http.Response, error) {
return mockResponse(200, ``, nil)
}
}
runtimeObj["socks5Proxy"] = "socks5://someuser:somepassword@ecs.aliyun.com"
runtimeObj["localAddr"] = "127.0.0.1"
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
runtimeObj["key"] = "private rsa key"
runtimeObj["cert"] = "private certification"
runtimeObj["ca"] = "private ca"
runtimeObj["ignoreSSL"] = true
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, err)
utils.AssertNotNil(t, resp)
// update the host is to restart a client
request.Headers["host"] = String("a.com")
runtimeObj["ignoreSSL"] = false
resp, err = DoRequest(request, runtimeObj)
utils.AssertNotNil(t, err)
utils.AssertEqual(t, "tls: failed to find any PEM data in certificate input", err.Error())
utils.AssertNil(t, resp)
// update the host is to restart a client
request.Headers["host"] = String("b.com")
runtimeObj["key"] = key
runtimeObj["cert"] = cert
runtimeObj["ca"] = "private ca"
_, err = DoRequest(request, runtimeObj)
utils.AssertNotNil(t, err)
utils.AssertEqual(t, "Failed to parse root certificate", err.Error())
// update the host is to restart a client
request.Headers["host"] = String("c.com")
runtimeObj["ca"] = ca
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
request.Protocol = String("HTTP")
runtimeObj["ignoreSSL"] = false
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) {
return func(req *http.Request, transport *http.Transport) (*http.Response, error) {
utils.AssertEqual(t, "tea-cn-hangzhou.aliyuncs.com:1080", req.Host)
return mockResponse(200, ``, errors.New("Internal error"))
}
}
request.Pathname = String("/log")
request.Protocol = String("http")
request.Port = Int(1080)
request.Headers["host"] = String("tea-cn-hangzhou.aliyuncs.com")
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, resp)
utils.AssertEqual(t, `Internal error`, err.Error())
}
func Test_DoAction(t *testing.T) {
origTestHookDo := hookDo
defer func() { hookDo = origTestHookDo }()
hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) {
return func(req *http.Request, transport *http.Transport) (*http.Response, error) {
return mockResponse(200, ``, errors.New("Internal error"))
}
}
request := NewRequest()
request.Method = String("TEA TEST")
resp, err := DoAction(request, nil)
utils.AssertNil(t, resp)
utils.AssertEqual(t, `net/http: invalid method "TEA TEST"`, err.Error())
request.Method = String("")
request.Protocol = String("https")
request.Query = map[string]*string{
@@ -392,7 +285,7 @@ func Test_DoAction(t *testing.T) {
}
runtimeObj["httpsProxy"] = "# #%gfdf"
runtimeObject := NewRuntimeObject(runtimeObj)
resp, err = DoAction(request, runtimeObject)
resp, err = DoRequest(request, runtimeObject)
utils.AssertNil(t, resp)
utils.AssertContains(t, err.Error(), `invalid URL escape "%gf"`)
@@ -401,32 +294,32 @@ func Test_DoAction(t *testing.T) {
request.Headers["content-length"] = nil
runtimeObj["httpsProxy"] = "http://someuser:somepassword@ecs.aliyun.com"
runtimeObject = NewRuntimeObject(runtimeObj)
resp, err = DoAction(request, runtimeObject)
resp, err = DoRequest(request, runtimeObject)
utils.AssertNil(t, resp)
utils.AssertEqual(t, `Internal error`, err.Error())
request.Headers["host"] = String("tea-cn-hangzhou.aliyuncs.com:80")
request.Headers["user-agent"] = String("test")
runtimeObject = NewRuntimeObject(runtimeObj)
resp, err = DoAction(request, runtimeObject)
resp, err = DoRequest(request, runtimeObject)
utils.AssertNil(t, resp)
utils.AssertEqual(t, `Internal error`, err.Error())
runtimeObj["socks5Proxy"] = "# #%gfdf"
runtimeObject = NewRuntimeObject(runtimeObj)
resp, err = DoAction(request, runtimeObject)
resp, err = DoRequest(request, runtimeObject)
utils.AssertNil(t, resp)
utils.AssertContains(t, err.Error(), ` invalid URL escape "%gf"`)
hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) {
return func(req *http.Request, transport *http.Transport) (*http.Response, error) {
hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) {
return func(req *http.Request) (*http.Response, error) {
return mockResponse(200, ``, nil)
}
}
runtimeObj["socks5Proxy"] = "socks5://someuser:somepassword@ecs.aliyun.com"
runtimeObj["localAddr"] = "127.0.0.1"
runtimeObject = NewRuntimeObject(runtimeObj)
resp, err = DoAction(request, runtimeObject)
resp, err = DoRequest(request, runtimeObject)
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
@@ -435,7 +328,7 @@ func Test_DoAction(t *testing.T) {
runtimeObj["ca"] = "private ca"
runtimeObj["ignoreSSL"] = true
runtimeObject = NewRuntimeObject(runtimeObj)
resp, err = DoAction(request, runtimeObject)
resp, err = DoRequest(request, runtimeObject)
utils.AssertNil(t, err)
utils.AssertNotNil(t, resp)
@@ -443,7 +336,7 @@ func Test_DoAction(t *testing.T) {
request.Headers["host"] = String("a.com")
runtimeObj["ignoreSSL"] = false
runtimeObject = NewRuntimeObject(runtimeObj)
resp, err = DoAction(request, runtimeObject)
resp, err = DoRequest(request, runtimeObject)
utils.AssertNotNil(t, err)
utils.AssertEqual(t, "tls: failed to find any PEM data in certificate input", err.Error())
utils.AssertNil(t, resp)
@@ -454,7 +347,7 @@ func Test_DoAction(t *testing.T) {
runtimeObj["cert"] = cert
runtimeObj["ca"] = "private ca"
runtimeObject = NewRuntimeObject(runtimeObj)
_, err = DoAction(request, runtimeObject)
_, err = DoRequest(request, runtimeObject)
utils.AssertNotNil(t, err)
utils.AssertEqual(t, "Failed to parse root certificate", err.Error())
@@ -462,19 +355,19 @@ func Test_DoAction(t *testing.T) {
request.Headers["host"] = String("c.com")
runtimeObj["ca"] = ca
runtimeObject = NewRuntimeObject(runtimeObj)
resp, err = DoAction(request, runtimeObject)
resp, err = DoRequest(request, runtimeObject)
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
request.Protocol = String("HTTP")
runtimeObj["ignoreSSL"] = false
runtimeObject = NewRuntimeObject(runtimeObj)
resp, err = DoAction(request, runtimeObject)
resp, err = DoRequest(request, runtimeObject)
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) {
return func(req *http.Request, transport *http.Transport) (*http.Response, error) {
hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) {
return func(req *http.Request) (*http.Response, error) {
utils.AssertEqual(t, "tea-cn-hangzhou.aliyuncs.com:1080", req.Host)
return mockResponse(200, ``, errors.New("Internal error"))
}
@@ -484,16 +377,16 @@ func Test_DoAction(t *testing.T) {
request.Port = Int(1080)
request.Headers["host"] = String("tea-cn-hangzhou.aliyuncs.com")
runtimeObject = NewRuntimeObject(runtimeObj)
resp, err = DoAction(request, runtimeObject)
resp, err = DoRequest(request, runtimeObject)
utils.AssertNil(t, resp)
utils.AssertEqual(t, `Internal error`, err.Error())
}
func Test_DoActionWithConcurrent(t *testing.T) {
func Test_DoRequestWithConcurrent(t *testing.T) {
origTestHookDo := hookDo
defer func() { hookDo = origTestHookDo }()
hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) {
return func(req *http.Request, transport *http.Transport) (*http.Response, error) {
hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) {
return func(req *http.Request) (*http.Response, error) {
return mockResponse(200, ``, nil)
}
}
@@ -509,7 +402,7 @@ func Test_DoActionWithConcurrent(t *testing.T) {
wg.Add(1)
go func() {
request := NewRequest()
resp, err := DoAction(request, runtimeObject)
resp, err := DoRequest(request, runtimeObject)
utils.AssertNil(t, err)
utils.AssertNotNil(t, resp)
wg.Done()
@@ -590,11 +483,11 @@ func Test_SetDialContext(t *testing.T) {
}
func Test_hookdo(t *testing.T) {
fn := func(req *http.Request, transport *http.Transport) (*http.Response, error) {
fn := func(req *http.Request) (*http.Response, error) {
return nil, errors.New("hookdo")
}
result := hookDo(fn)
resp, err := result(nil, nil)
resp, err := result(nil)
utils.AssertNil(t, resp)
utils.AssertEqual(t, "hookdo", err.Error())
}
+11 -56
View File
@@ -13,11 +13,11 @@ type BaseError interface {
error
ErrorName() *string
ErrorCode() *string
RetryAfterTimeMillis() *int64
}
// CastError is used for cast type fails
type CastError struct {
BaseError
Message *string
Code *string
}
@@ -43,10 +43,12 @@ func (err *CastError) ErrorCode() *string {
return err.Code
}
// SDKError struct is used save error code and message, use as ResponseError
func (err *CastError) RetryAfterTimeMillis() *int64 {
return nil
}
// SDKError struct is used save error code and message
type SDKError struct {
BaseError
Name string
Code *string
StatusCode *int
Message *string
@@ -55,9 +57,6 @@ type SDKError struct {
errMsg *string
Description *string
AccessDeniedDetail map[string]interface{}
RequestId *string
Retryable *bool
RetryAfter *int64
}
// NewSDKError is used for shortly create SDKError object
@@ -126,54 +125,6 @@ func NewSDKError(obj map[string]interface{}) *SDKError {
return err
}
func NewError(name string, obj map[string]interface{}) *SDKError {
err := &SDKError{
Name: name,
}
if val, ok := obj["code"].(int); ok {
err.Code = String(strconv.Itoa(val))
} else if val, ok := obj["code"].(string); ok {
err.Code = String(val)
}
if obj["message"] != nil {
err.Message = String(obj["message"].(string))
}
if obj["description"] != nil {
err.Description = String(obj["description"].(string))
}
if detail := obj["accessDeniedDetail"]; detail != nil {
r := reflect.ValueOf(detail)
if r.Kind().String() == "map" {
res := make(map[string]interface{})
tmp := r.MapKeys()
for _, key := range tmp {
res[key.String()] = r.MapIndex(key).Interface()
}
err.AccessDeniedDetail = res
}
}
if obj["statusCode"] != nil {
err.StatusCode = Int(obj["statusCode"].(int))
}
if obj["requestId"] != nil {
err.RequestId = String(obj["requestId"].(string))
}
if obj["retryable"] != nil {
err.Retryable = Bool(obj["retryable"].(bool))
}
if obj["retryAfter"] != nil {
err.RetryAfter = Int64(obj["retryAfter"].(int64))
}
if data := obj["data"]; data != nil {
byt := bytes.NewBuffer([]byte{})
jsonEncoder := json.NewEncoder(byt)
jsonEncoder.SetEscapeHTML(false)
jsonEncoder.Encode(data)
err.Data = String(string(bytes.TrimSpace(byt.Bytes())))
}
return err
}
// Set ErrMsg by msg
func (err *SDKError) SetErrMsg(msg string) {
err.errMsg = String(msg)
@@ -189,9 +140,13 @@ func (err *SDKError) Error() string {
}
func (err *SDKError) ErrorName() *string {
return String(err.Name)
return String("SDKError")
}
func (err *SDKError) ErrorCode() *string {
return err.Code
}
func (err *SDKError) RetryAfterTimeMillis() *int64 {
return nil
}
+4 -38
View File
@@ -3,7 +3,7 @@ package tea
import (
"testing"
"github.com/alibabacloud-go/tea/utils"
"github.com/alibabacloud-go/tea/v2/utils"
)
func TestCastError(t *testing.T) {
@@ -12,6 +12,7 @@ func TestCastError(t *testing.T) {
utils.AssertEqual(t, "cast error", err.Error())
utils.AssertEqual(t, "", StringValue(err.ErrorCode()))
utils.AssertEqual(t, "CastError", StringValue(err.ErrorName()))
utils.AssertNil(t, err.RetryAfterTimeMillis())
}
func TestSDKError(t *testing.T) {
@@ -45,6 +46,7 @@ func TestSDKError(t *testing.T) {
utils.AssertEqual(t, "description", *err.Description)
utils.AssertEqual(t, "ImplicitDeny", err.AccessDeniedDetail["NoPermissionType"])
utils.AssertEqual(t, 123, err.AccessDeniedDetail["UserId"])
utils.AssertNil(t, err.RetryAfterTimeMillis())
err = NewSDKError(map[string]interface{}{
"statusCode": "404",
@@ -109,41 +111,5 @@ func TestSDKErrorCode404(t *testing.T) {
utils.AssertNotNil(t, err)
utils.AssertEqual(t, "SDKError:\n StatusCode: 404\n Code: NOTFOUND\n Message: message\n Data: \n", err.Error())
utils.AssertEqual(t, "NOTFOUND", StringValue(err.ErrorCode()))
utils.AssertEqual(t, "", StringValue(err.ErrorName()))
}
func TestNewError(t *testing.T) {
var err0 BaseError
err0 = NewError("ResponseError", map[string]interface{}{
"code": "code",
"statusCode": 404,
"message": "message",
"data": map[string]interface{}{
"httpCode": "404",
"requestId": "dfadfa32cgfdcasd4313",
"hostId": "github.com/alibabacloud/tea",
"recommend": "https://中文?q=a.b&product=c&requestId=123",
},
"description": "description",
"accessDeniedDetail": map[string]interface{}{
"AuthAction": "ram:ListUsers",
"AuthPrincipalType": "SubUser",
"PolicyType": "ResourceGroupLevelIdentityBassdPolicy",
"NoPermissionType": "ImplicitDeny",
"UserId": 123,
},
"requestId": "123456",
"retryable": true,
"retryAfter": int64(100),
})
utils.AssertNotNil(t, err0)
utils.AssertEqual(t, "SDKError:\n StatusCode: 404\n Code: code\n Message: message\n Data: {\"hostId\":\"github.com/alibabacloud/tea\",\"httpCode\":\"404\",\"recommend\":\"https://中文?q=a.b&product=c&requestId=123\",\"requestId\":\"dfadfa32cgfdcasd4313\"}\n", err0.Error())
var err *SDKError
err = err0.(*SDKError)
err.SetErrMsg("test")
utils.AssertEqual(t, "test", err.Error())
utils.AssertEqual(t, 404, *err.StatusCode)
utils.AssertEqual(t, "description", *err.Description)
utils.AssertEqual(t, "ImplicitDeny", err.AccessDeniedDetail["NoPermissionType"])
utils.AssertEqual(t, 123, err.AccessDeniedDetail["UserId"])
utils.AssertEqual(t, "SDKError", StringValue(err.ErrorName()))
}
+1 -6
View File
@@ -14,12 +14,7 @@ func Prettify(i interface{}) string {
return string(resp)
}
func Sleep(backoffTime *int) {
sleeptime := time.Duration(IntValue(backoffTime)) * time.Second
time.Sleep(sleeptime)
}
func SleepMillis(backoffTime *int64) {
func Sleep(backoffTime *int64) {
sleeptime := time.Duration(Int64Value(backoffTime)) * time.Millisecond
time.Sleep(sleeptime)
}
+5 -5
View File
@@ -5,7 +5,7 @@ import (
"testing"
"time"
"github.com/alibabacloud-go/tea/utils"
"github.com/alibabacloud-go/tea/v2/utils"
)
type PrettifyTest struct {
@@ -32,11 +32,11 @@ func Test_Prettify(t *testing.T) {
utils.AssertEqual(t, str, "null")
}
func Test_SleepMillis(t *testing.T) {
func Test_Sleep(t *testing.T) {
start := time.Now()
SleepMillis(Int64(1000))
SleepMillis(Int64(0))
SleepMillis(nil)
Sleep(Int64(1000))
Sleep(Int64(0))
Sleep(nil)
cost := time.Since(start)
utils.AssertEqual(t, cost.Seconds() >= 1, true)
}
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"reflect"
"testing"
"github.com/alibabacloud-go/tea/utils"
"github.com/alibabacloud-go/tea/v2/utils"
jsoniter "github.com/json-iterator/go"
"github.com/modern-go/reflect2"
)
+3 -54
View File
@@ -2,10 +2,9 @@ package tea
import (
"math"
"math/rand"
"time"
"github.com/alibabacloud-go/tea/utils"
"github.com/alibabacloud-go/tea/v2/utils"
)
const (
@@ -66,11 +65,6 @@ func ShouldRetry(options *RetryOptions, ctx *RetryPolicyContext) *bool {
if IntValue(ctx.RetriesAttempted) > IntValue(retryCondition.MaxAttempts) {
return Bool(false)
}
if err1, ok := err.(*SDKError); ok {
if BoolValue(err1.Retryable) == false {
return Bool(false)
}
}
return Bool(true)
}
}
@@ -97,13 +91,9 @@ func GetBackoffDelay(options *RetryOptions, ctx *RetryPolicyContext) *int64 {
} else {
maxDelay = DefaultMaxDelay.Milliseconds()
}
if err1, ok := err.(*SDKError); ok {
if err1.RetryAfter != nil {
return Int64(int64(math.Min(float64(Int64Value(err1.RetryAfter)), float64(maxDelay))))
}
if err.RetryAfterTimeMillis() != nil {
return Int64(int64(math.Min(float64(Int64Value(err.RetryAfterTimeMillis())), float64(maxDelay))))
}
if retryCondition.Backoff == nil {
return Int64(DefaultMinDelay.Milliseconds())
}
@@ -115,44 +105,3 @@ func GetBackoffDelay(options *RetryOptions, ctx *RetryPolicyContext) *int64 {
}
return Int64(DefaultMinDelay.Milliseconds())
}
// Deperacated
func AllowRetry(retry interface{}, retryTimes *int) *bool {
if IntValue(retryTimes) == 0 {
return Bool(true)
}
retryMap, ok := retry.(map[string]interface{})
if !ok {
return Bool(false)
}
retryable, ok := retryMap["retryable"].(bool)
if !ok || !retryable {
return Bool(false)
}
maxAttempts, ok := retryMap["maxAttempts"].(int)
if !ok || maxAttempts < IntValue(retryTimes) {
return Bool(false)
}
return Bool(true)
}
// Deperacated
func GetBackoffTime(backoff interface{}, retrytimes *int) *int {
backoffMap, ok := backoff.(map[string]interface{})
if !ok {
return Int(0)
}
policy, ok := backoffMap["policy"].(string)
if !ok || policy == "no" {
return Int(0)
}
period, ok := backoffMap["period"].(int)
if !ok || period == 0 {
return Int(0)
}
maxTime := math.Pow(2.0, float64(IntValue(retrytimes)))
return Int(rand.Intn(int(maxTime-1)) * period)
}
+73 -129
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"strings"
"testing"
"github.com/alibabacloud-go/tea/utils"
"github.com/alibabacloud-go/tea/v2/utils"
)
func Test_Trans(t *testing.T) {