summaryrefslogtreecommitdiff
path: root/internal/httpclient/client.go
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2023-04-29 17:44:20 +0100
committerLibravatar GitHub <noreply@github.com>2023-04-29 18:44:20 +0200
commit68b91d2128c7be3c4f060091b172c39057318ad4 (patch)
tree3bcf4af8fa79b43f56857df4bba1453977fa01b3 /internal/httpclient/client.go
parent[feature] Add GET endpoint for single notification (#1719) (diff)
downloadgotosocial-68b91d2128c7be3c4f060091b172c39057318ad4.tar.xz
[performance] tweak http client error handling (#1718)
* update errors library, check for more TLS type error in http client Signed-off-by: kim <grufwub@gmail.com> * bump cache library version to match errors library Signed-off-by: kim <grufwub@gmail.com> --------- Signed-off-by: kim <grufwub@gmail.com>
Diffstat (limited to 'internal/httpclient/client.go')
-rw-r--r--internal/httpclient/client.go40
1 files changed, 26 insertions, 14 deletions
diff --git a/internal/httpclient/client.go b/internal/httpclient/client.go
index 67a1d0715..68e11495d 100644
--- a/internal/httpclient/client.go
+++ b/internal/httpclient/client.go
@@ -149,7 +149,7 @@ func New(cfg Config) *Client {
// Initiate outgoing bad hosts lookup cache.
c.badHosts = cache.New[string, struct{}](0, 1000, 0)
- c.badHosts.SetTTL(15*time.Minute, false)
+ c.badHosts.SetTTL(time.Hour, false)
if !c.badHosts.Start(time.Minute) {
log.Panic(nil, "failed to start transport controller cache")
}
@@ -165,7 +165,7 @@ func (c *Client) Do(r *http.Request) (*http.Response, error) {
}
// DoSigned ...
-func (c *Client) DoSigned(r *http.Request, sign SignFunc) (*http.Response, error) {
+func (c *Client) DoSigned(r *http.Request, sign SignFunc) (rsp *http.Response, err error) {
const (
// max no. attempts.
maxRetries = 5
@@ -182,10 +182,16 @@ func (c *Client) DoSigned(r *http.Request, sign SignFunc) (*http.Response, error
if !fastFail {
// Check if recently reached max retries for this host
// so we don't bother with a retry-backoff loop. The only
- // errors that are retried upon are server failure and
- // domain resolution type errors, so this cached result
+ // errors that are retried upon are server failure, TLS
+ // and domain resolution type errors, so this cached result
// indicates this server is likely having issues.
fastFail = c.badHosts.Has(host)
+ defer func() {
+ if err != nil {
+ // On error return mark as bad-host.
+ c.badHosts.Set(host, struct{}{})
+ }
+ }()
}
// Start a log entry for this request
@@ -218,7 +224,7 @@ func (c *Client) DoSigned(r *http.Request, sign SignFunc) (*http.Response, error
l.Infof("performing request")
// Perform the request.
- rsp, err := c.do(r)
+ rsp, err = c.do(r)
if err == nil { //nolint:gocritic
// TooManyRequest means we need to slow
@@ -249,20 +255,27 @@ func (c *Client) DoSigned(r *http.Request, sign SignFunc) (*http.Response, error
}
}
- } else if errorsv2.Is(err,
+ // Ensure unset.
+ rsp = nil
+
+ } else if errorsv2.Comparable(err,
context.DeadlineExceeded,
context.Canceled,
ErrBodyTooLarge,
ErrReservedAddr,
) {
- // Return on non-retryable errors
+ // Non-retryable errors.
+ return nil, err
+ } else if errorsv2.Assignable(err,
+ (*x509.CertificateInvalidError)(nil),
+ (*x509.HostnameError)(nil),
+ (*x509.UnknownAuthorityError)(nil),
+ ) {
+ // Non-retryable TLS errors.
return nil, err
} else if strings.Contains(err.Error(), "stopped after 10 redirects") {
// Don't bother if net/http returned after too many redirects
return nil, err
- } else if errors.As(err, &x509.UnknownAuthorityError{}) {
- // Unknown authority errors we do NOT recover from
- return nil, err
} else if dnserr := (*net.DNSError)(nil); // nocollapse
errors.As(err, &dnserr) && dnserr.IsNotFound {
// DNS lookup failure, this domain does not exist
@@ -292,10 +305,9 @@ func (c *Client) DoSigned(r *http.Request, sign SignFunc) (*http.Response, error
}
}
- // Add "bad" entry for this host.
- c.badHosts.Set(host, struct{}{})
-
- return nil, errors.New("transport reached max retries")
+ // Set error return to trigger setting "bad host".
+ err = errors.New("transport reached max retries")
+ return
}
// do ...