This is an automated email from the ASF dual-hosted git repository.
ocket8888 pushed a commit to branch 5.1.x
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
The following commit(s) were added to refs/heads/5.1.x by this push:
new fac4746 Prevent looping in case of login failure (#5790)
fac4746 is described below
commit fac47462bdef9cc0f1aa4cf70f6d0a6fdbe655cf
Author: Srijeet Chatterjee <[email protected]>
AuthorDate: Tue Apr 27 16:09:10 2021 -0600
Prevent looping in case of login failure (#5790)
---
CHANGELOG.md | 1 +
traffic_ops/v3-client/session.go | 40 +++++++++++++++++++++++-----------------
2 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f7d6fd7..8c0eab0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ The format is based on [Keep a
Changelog](http://keepachangelog.com/en/1.0.0/).
- Fixed Traffic Monitor to report `ONLINE` caches as available.
- [#5744](https://github.com/apache/trafficcontrol/issues/5744) - Sort TM
Delivery Service States page by DS name
- [#5724](https://github.com/apache/trafficcontrol/issues/5724) - Set XMPPID
to hostname if the server had none, don't error on server update when XMPPID is
empty
+- [#5739](https://github.com/apache/trafficcontrol/issues/5739) - Prevent
looping in case of a failed login attempt
## [5.1.1] - 2021-03-19
### Added
diff --git a/traffic_ops/v3-client/session.go b/traffic_ops/v3-client/session.go
index 2e0f4c9..390cc3c 100644
--- a/traffic_ops/v3-client/session.go
+++ b/traffic_ops/v3-client/session.go
@@ -212,7 +212,7 @@ func (to *Session) login() (net.Addr, error) {
// Can't use req() because it retries login failures, which would be an
infinite loop.
reqF := composeReqFuncs(makeRequestWithHeader, []MidReqF{reqTryLatest,
reqFallback, reqAPI})
- reqInf, err := reqF(to, http.MethodPost, path, body, nil, &alerts)
+ reqInf, err := reqF(to, http.MethodPost, path, body, nil, &alerts, true)
if err != nil {
return reqInf.RemoteAddr, fmt.Errorf("Login error %v, alerts
string: %+v", err, alerts)
}
@@ -425,7 +425,7 @@ func (to *Session) errUnlessOKOrNotModified(resp
*http.Response, remoteAddr net.
func (to *Session) getURL(path string) string { return to.URL + path }
-type ReqF func(to *Session, method string, path string, body interface{},
header http.Header, response interface{}) (ReqInf, error)
+type ReqF func(to *Session, method string, path string, body interface{},
header http.Header, response interface{}, raw bool) (ReqInf, error)
type MidReqF func(ReqF) ReqF
@@ -442,7 +442,7 @@ func composeReqFuncs(reqF ReqF, middleware []MidReqF) ReqF {
// reqTryLatest will re-set to.latestSupportedAPI to the latest, if it's less
than the latest and to.apiVerCheckInterval has passed.
// This does not fallback, so it should generally be composed with reqFallback.
func reqTryLatest(reqF ReqF) ReqF {
- return func(to *Session, method string, path string, body interface{},
header http.Header, response interface{}) (ReqInf, error) {
+ return func(to *Session, method string, path string, body interface{},
header http.Header, response interface{}, raw bool) (ReqInf, error) {
if to.apiVerCheckInterval == 0 {
// Session could have been default-initialized rather
than created with a func, so we need to check here, not just in login funcs.
to.apiVerCheckInterval = DefaultAPIVersionCheckInterval
@@ -460,7 +460,7 @@ func reqTryLatest(reqF ReqF) ReqF {
to.lastAPIVerCheck = time.Now().Add(time.Hour * 24 *
365)
defer func() { to.lastAPIVerCheck = time.Now() }()
}
- return reqF(to, method, path, body, header, response)
+ return reqF(to, method, path, body, header, response, raw)
}
}
@@ -470,15 +470,15 @@ func reqTryLatest(reqF ReqF) ReqF {
// This is designed to handle expired sessions, when the time between requests
is longer than the session expiration;
// it does not do perpetual retry.
func reqLogin(reqF ReqF) ReqF {
- return func(to *Session, method string, path string, body interface{},
header http.Header, response interface{}) (ReqInf, error) {
- inf, err := reqF(to, method, path, body, header, response)
+ return func(to *Session, method string, path string, body interface{},
header http.Header, response interface{}, raw bool) (ReqInf, error) {
+ inf, err := reqF(to, method, path, body, header, response, raw)
if inf.StatusCode != http.StatusUnauthorized && inf.StatusCode
!= http.StatusForbidden {
return inf, err
}
if _, lerr := to.login(); lerr != nil {
return inf, err
}
- return reqF(to, method, path, body, header, response)
+ return reqF(to, method, path, body, header, response, raw)
}
}
@@ -486,9 +486,9 @@ func reqLogin(reqF ReqF) ReqF {
// falls back to the previous and retries, recursively.
// If all supported versions fail, the last response error is returned.
func reqFallback(reqF ReqF) ReqF {
- var fallbackFunc func(to *Session, method string, path string, body
interface{}, header http.Header, response interface{}) (ReqInf, error)
- fallbackFunc = func(to *Session, method string, path string, body
interface{}, header http.Header, response interface{}) (ReqInf, error) {
- inf, err := reqF(to, method, path, body, header, response)
+ var fallbackFunc func(to *Session, method string, path string, body
interface{}, header http.Header, response interface{}, raw bool) (ReqInf, error)
+ fallbackFunc = func(to *Session, method string, path string, body
interface{}, header http.Header, response interface{}, raw bool) (ReqInf,
error) {
+ inf, err := reqF(to, method, path, body, header, response,
false)
if err == nil {
return inf, err
}
@@ -512,7 +512,7 @@ func reqFallback(reqF ReqF) ReqF {
}
to.latestSupportedAPI = apiVersions[nextAPIVerI]
- return fallbackFunc(to, method, path, body, header, response)
+ return fallbackFunc(to, method, path, body, header, response,
false)
}
return fallbackFunc
}
@@ -524,9 +524,9 @@ func reqFallback(reqF ReqF) ReqF {
// and this will request '/api/3.1/deliveryservices'.
//
func reqAPI(reqF ReqF) ReqF {
- return func(to *Session, method string, path string, body interface{},
header http.Header, response interface{}) (ReqInf, error) {
+ return func(to *Session, method string, path string, body interface{},
header http.Header, response interface{}, raw bool) (ReqInf, error) {
path = to.APIBase() + path
- return reqF(to, method, path, body, header, response)
+ return reqF(to, method, path, body, header, response, raw)
}
}
@@ -543,18 +543,24 @@ func reqAPI(reqF ReqF) ReqF {
//
// To request the bytes without deserializing, pass a *[]byte response.
//
-func makeRequestWithHeader(to *Session, method, path string, body interface{},
header http.Header, response interface{}) (ReqInf, error) {
+func makeRequestWithHeader(to *Session, method, path string, body interface{},
header http.Header, response interface{}, raw bool) (ReqInf, error) {
var remoteAddr net.Addr
+ var resp *http.Response
+ var err error
reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr:
remoteAddr}
var reqBody []byte
- var err error
+
if body != nil {
reqBody, err = json.Marshal(body)
if err != nil {
return reqInf, errors.New("marshalling request body: "
+ err.Error())
}
}
- resp, remoteAddr, err := to.request(method, path, reqBody, header)
+ if raw {
+ resp, remoteAddr, err = to.RawRequestWithHdr(method, path,
reqBody, header)
+ } else {
+ resp, remoteAddr, err = to.request(method, path, reqBody,
header)
+ }
reqInf.RemoteAddr = remoteAddr
if resp != nil {
reqInf.StatusCode = resp.StatusCode
@@ -600,7 +606,7 @@ func (to *Session) del(path string, header http.Header,
response interface{}) (R
func (to *Session) req(method string, path string, body interface{}, header
http.Header, response interface{}) (ReqInf, error) {
reqF := composeReqFuncs(makeRequestWithHeader, []MidReqF{reqTryLatest,
reqFallback, reqAPI, reqLogin})
- return reqF(to, method, path, body, header, response)
+ return reqF(to, method, path, body, header, response, false)
}
// request performs the HTTP request to Traffic Ops, trying to refresh the
cookie if an Unauthorized or Forbidden code is received. It only tries once. If
the login fails, the original Unauthorized/Forbidden response is returned. If
the login succeeds and the subsequent re-request fails, the re-request's
response is returned even if it's another Unauthorized/Forbidden.