From 10a13d30e5b174f01b232b5fdfbb730067ada234 Mon Sep 17 00:00:00 2001 From: Jeevanandam M Date: Sun, 10 May 2020 23:26:09 -0700 Subject: [PATCH] #339 Addressing HTTP2 issue on go1.13 above --- .travis.yml | 2 +- client.go | 22 ---------------------- client_test.go | 6 ++++-- context_test.go | 3 ++- middleware.go | 1 + request_test.go | 12 +++++++++--- response.go | 8 ++++++++ retry_test.go | 5 +++-- transport.go | 35 +++++++++++++++++++++++++++++++++++ transport112.go | 34 ++++++++++++++++++++++++++++++++++ 10 files changed, 97 insertions(+), 31 deletions(-) create mode 100644 transport.go create mode 100644 transport112.go diff --git a/.travis.yml b/.travis.yml index 103aa35d..fa1ce907 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: go sudo: false go: # use travis ci resource effectively, keep always latest 2 versions and tip :) - - 1.12.x + - 1.14.x - 1.13.x - tip diff --git a/client.go b/client.go index c66bcb8b..95b81560 100644 --- a/client.go +++ b/client.go @@ -15,12 +15,10 @@ import ( "io" "io/ioutil" "math" - "net" "net/http" "net/url" "reflect" "regexp" - "runtime" "strings" "sync" "time" @@ -961,23 +959,3 @@ func createClient(hc *http.Client) *Client { return c } - -func createTransport(localAddr net.Addr) *http.Transport { - dialer := &net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - DualStack: true, - } - if localAddr != nil { - dialer.LocalAddr = localAddr - } - return &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: dialer.DialContext, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1, - } -} diff --git a/client_test.go b/client_test.go index c5a3feff..551491fd 100644 --- a/client_test.go +++ b/client_test.go @@ -107,11 +107,13 @@ func TestClientRedirectPolicy(t *testing.T) { c := dc().SetRedirectPolicy(FlexibleRedirectPolicy(20)) _, err := c.R().Get(ts.URL + "/redirect-1") - assertEqual(t, "Get /redirect-21: stopped after 20 redirects", err.Error()) + assertEqual(t, true, ("Get /redirect-21: stopped after 20 redirects" == err.Error() || + "Get \"/redirect-21\": stopped after 20 redirects" == err.Error())) c.SetRedirectPolicy(NoRedirectPolicy()) _, err = c.R().Get(ts.URL + "/redirect-1") - assertEqual(t, "Get /redirect-2: auto redirect is disabled", err.Error()) + assertEqual(t, true, ("Get /redirect-2: auto redirect is disabled" == err.Error() || + "Get \"/redirect-2\": auto redirect is disabled" == err.Error())) } func TestClientTimeout(t *testing.T) { diff --git a/context_test.go b/context_test.go index 21d14ee0..eab215c5 100644 --- a/context_test.go +++ b/context_test.go @@ -192,7 +192,8 @@ func TestClientRetryWithSetContext(t *testing.T) { SetContext(context.Background()). Get(ts.URL + "/") - assertEqual(t, true, strings.HasPrefix(err.Error(), "Get "+ts.URL+"/")) + assertEqual(t, true, (strings.HasPrefix(err.Error(), "Get "+ts.URL+"/") || + strings.HasPrefix(err.Error(), "Get \""+ts.URL+"/\""))) } func TestRequestContext(t *testing.T) { diff --git a/middleware.go b/middleware.go index 611f4489..703f07c6 100644 --- a/middleware.go +++ b/middleware.go @@ -314,6 +314,7 @@ func responseLogger(c *Client, res *Response) error { debugLog := res.Request.values[debugRequestLogKey].(string) debugLog += "~~~ RESPONSE ~~~\n" + fmt.Sprintf("STATUS : %s\n", res.Status()) + + fmt.Sprintf("PROTO : %s\n", res.RawResponse.Proto) + fmt.Sprintf("RECEIVED AT : %v\n", res.ReceivedAt().Format(time.RFC3339Nano)) + fmt.Sprintf("TIME DURATION: %v\n", res.Time()) + "HEADERS :\n" + diff --git a/request_test.go b/request_test.go index 22b97eda..ba437516 100644 --- a/request_test.go +++ b/request_test.go @@ -38,6 +38,7 @@ func TestGet(t *testing.T) { assertError(t, err) assertEqual(t, http.StatusOK, resp.StatusCode()) + assertEqual(t, "HTTP/1.1", resp.Proto()) assertEqual(t, "200 OK", resp.Status()) assertNotNil(t, resp.Body()) assertEqual(t, "TestGet: text response", resp.String()) @@ -56,6 +57,7 @@ func TestGetCustomUserAgent(t *testing.T) { assertError(t, err) assertEqual(t, http.StatusOK, resp.StatusCode()) + assertEqual(t, "HTTP/1.1", resp.Proto()) assertEqual(t, "200 OK", resp.Status()) assertEqual(t, "TestGet: text response", resp.String()) @@ -80,6 +82,7 @@ func TestGetClientParamRequestParam(t *testing.T) { assertError(t, err) assertEqual(t, http.StatusOK, resp.StatusCode()) + assertEqual(t, "HTTP/1.1", resp.Proto()) assertEqual(t, "200 OK", resp.Status()) assertEqual(t, "TestGet: text response", resp.String()) @@ -952,7 +955,8 @@ func TestHTTPAutoRedirectUpTo10(t *testing.T) { _, err := dc().R().Get(ts.URL + "/redirect-1") - assertEqual(t, "Get /redirect-11: stopped after 10 redirects", err.Error()) + assertEqual(t, true, ("Get /redirect-11: stopped after 10 redirects" == err.Error() || + "Get \"/redirect-11\": stopped after 10 redirects" == err.Error())) } func TestHostCheckRedirectPolicy(t *testing.T) { @@ -1119,11 +1123,13 @@ func TestGetClient(t *testing.T) { func TestIncorrectURL(t *testing.T) { c := dc() _, err := c.R().Get("//not.a.user@%66%6f%6f.com/just/a/path/also") - assertEqual(t, true, strings.Contains(err.Error(), "parse //not.a.user@%66%6f%6f.com/just/a/path/also")) + assertEqual(t, true, (strings.Contains(err.Error(), "parse //not.a.user@%66%6f%6f.com/just/a/path/also") || + strings.Contains(err.Error(), "parse \"//not.a.user@%66%6f%6f.com/just/a/path/also\""))) c.SetHostURL("//not.a.user@%66%6f%6f.com") _, err1 := c.R().Get("/just/a/path/also") - assertEqual(t, true, strings.Contains(err1.Error(), "parse //not.a.user@%66%6f%6f.com/just/a/path/also")) + assertEqual(t, true, (strings.Contains(err1.Error(), "parse //not.a.user@%66%6f%6f.com/just/a/path/also") || + strings.Contains(err1.Error(), "parse \"//not.a.user@%66%6f%6f.com/just/a/path/also\""))) } func TestDetectContentTypeForPointer(t *testing.T) { diff --git a/response.go b/response.go index b5c0e5d8..b82bce44 100644 --- a/response.go +++ b/response.go @@ -55,6 +55,14 @@ func (r *Response) StatusCode() int { return r.RawResponse.StatusCode } +// Proto method returns the HTTP response protocol used for the request. +func (r *Response) Proto() string { + if r.RawResponse == nil { + return "" + } + return r.RawResponse.Proto +} + // Result method returns the response value as an object if it has one func (r *Response) Result() interface{} { return r.Request.Result diff --git a/retry_test.go b/retry_test.go index 6b3b4e44..ac1a54c1 100644 --- a/retry_test.go +++ b/retry_test.go @@ -151,7 +151,8 @@ func TestClientRetryGet(t *testing.T) { assertNotNil(t, resp.Body()) assertEqual(t, 0, len(resp.Header())) - assertEqual(t, true, strings.HasPrefix(err.Error(), "Get "+ts.URL+"/set-retrycount-test")) + assertEqual(t, true, (strings.HasPrefix(err.Error(), "Get "+ts.URL+"/set-retrycount-test") || + strings.HasPrefix(err.Error(), "Get \""+ts.URL+"/set-retrycount-test\""))) } func TestClientRetryWait(t *testing.T) { @@ -616,7 +617,7 @@ func TestClientRetryCount(t *testing.T) { // 2 attempts were made assertEqual(t, attempt, 2) - assertEqual(t, true, strings.HasPrefix(err.Error(), "Get "+ts.URL+"/set-retrycount-test")) + assertEqual(t, true, strings.HasPrefix(err.Error(), "Get \""+ts.URL+"/set-retrycount-test\"")) } func filler(*Response, error) bool { diff --git a/transport.go b/transport.go new file mode 100644 index 00000000..6cde29e8 --- /dev/null +++ b/transport.go @@ -0,0 +1,35 @@ +// +build go1.13 + +// Copyright (c) 2015-2020 Jeevanandam M (jeeva@myjeeva.com), All rights reserved. +// resty source code and usage is governed by a MIT style +// license that can be found in the LICENSE file. + +package resty + +import ( + "net" + "net/http" + "runtime" + "time" +) + +func createTransport(localAddr net.Addr) *http.Transport { + dialer := &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + } + if localAddr != nil { + dialer.LocalAddr = localAddr + } + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: dialer.DialContext, + ForceAttemptHTTP2: true, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1, + } +} diff --git a/transport112.go b/transport112.go new file mode 100644 index 00000000..ff7c2770 --- /dev/null +++ b/transport112.go @@ -0,0 +1,34 @@ +// +build !go1.13 + +// Copyright (c) 2015-2020 Jeevanandam M (jeeva@myjeeva.com), All rights reserved. +// resty source code and usage is governed by a MIT style +// license that can be found in the LICENSE file. + +package resty + +import ( + "net" + "net/http" + "runtime" + "time" +) + +func createTransport(localAddr net.Addr) *http.Transport { + dialer := &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + } + if localAddr != nil { + dialer.LocalAddr = localAddr + } + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: dialer.DialContext, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1, + } +}