diff options
Diffstat (limited to 'internal/transport/transport.go')
-rw-r--r-- | internal/transport/transport.go | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/internal/transport/transport.go b/internal/transport/transport.go index 18c40f79f..b0f68f707 100644 --- a/internal/transport/transport.go +++ b/internal/transport/transport.go @@ -32,6 +32,7 @@ import ( "sync" "time" + "codeberg.org/gruf/go-byteutil" errorsv2 "codeberg.org/gruf/go-errors/v2" "codeberg.org/gruf/go-kv" "github.com/go-fed/httpsig" @@ -84,7 +85,7 @@ type transport struct { signerMu sync.Mutex } -// GET will perform given http request using transport client, retrying on certain preset errors, or if status code is among retryOn. +// GET will perform given http request using transport client, retrying on certain preset errors. func (t *transport) GET(r *http.Request) (*http.Response, error) { if r.Method != http.MethodGet { return nil, errors.New("must be GET request") @@ -94,7 +95,7 @@ func (t *transport) GET(r *http.Request) (*http.Response, error) { }) } -// POST will perform given http request using transport client, retrying on certain preset errors, or if status code is among retryOn. +// POST will perform given http request using transport client, retrying on certain preset errors. func (t *transport) POST(r *http.Request, body []byte) (*http.Response, error) { if r.Method != http.MethodPost { return nil, errors.New("must be POST request") @@ -116,18 +117,17 @@ func (t *transport) do(r *http.Request, signer func(*http.Request) error) (*http // Get request hostname host := r.URL.Hostname() - // Check if recently reached max retries for this host - // so we don't need to bother reattempting it. The only - // errors that are retried upon are server failure and - // domain resolution type errors, so this cached result - // indicates this server is likely having issues. - if t.controller.badHosts.Has(host) { - return nil, errors.New("too many failed attempts") - } - // Check whether request should fast fail, we check this // before loop as each context.Value() requires mutex lock. fastFail := IsFastfail(r.Context()) + 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 + // indicates this server is likely having issues. + fastFail = t.controller.badHosts.Has(host) + } // Start a log entry for this request l := log.WithContext(r.Context()). @@ -148,6 +148,12 @@ func (t *transport) do(r *http.Request, signer func(*http.Request) error) (*http r.Header.Del("Signature") r.Header.Del("Digest") + // Rewind body reader and content-length if set. + if rc, ok := r.Body.(*byteutil.ReadNopCloser); ok { + r.ContentLength = int64(rc.Len()) + rc.Rewind() + } + // Perform request signing if err := signer(r); err != nil { return nil, err @@ -226,7 +232,7 @@ func (t *transport) do(r *http.Request, signer func(*http.Request) error) (*http } } - // Add "bad" entry for this host + // Add "bad" entry for this host. t.controller.badHosts.Set(host, struct{}{}) return nil, errors.New("transport reached max retries") |