Add context deadline to request

This commit is contained in:
Ben Sarmiento
2024-01-27 21:09:00 +01:00
parent 1aabcfd322
commit ce4b794098
4 changed files with 54 additions and 40 deletions

View File

@@ -28,7 +28,6 @@ type HTTPClient struct {
maxRetries int
timeoutSecs int
backoff func(attempt int) time.Duration
shouldRetry func(resp *http.Response, reqHasRangeHeader bool, err error, rateLimitSleep int) int
bearerToken string
ensureIPv6Host bool
cfg config.ConfigInterface
@@ -58,7 +57,6 @@ func NewHTTPClient(token string, maxRetries int, timeoutSecs int, ensureIPv6Host
maxRetries: maxRetries,
timeoutSecs: timeoutSecs,
backoff: backoffFunc,
shouldRetry: shouldRetryFunc,
ensureIPv6Host: ensureIPv6Host,
cfg: cfg,
ipv6: cmap.New[string](),
@@ -148,7 +146,20 @@ func (r *HTTPClient) Do(req *http.Request) (*http.Response, error) {
attempt := 0
for {
r.replaceHostIfNeeded(req) // needed for ipv6
r.log.Debugf("downloading %s", req.URL)
timeout := time.Duration(r.cfg.GetRealDebridTimeout()) * time.Second
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
req = req.WithContext(ctx)
resp, err = r.client.Do(req)
// check if error is context deadline exceeded
if r.ensureIPv6Host && r.cfg.ShouldForceIPv6() && err != nil && strings.Contains(err.Error(), "context deadline exceeded") {
attempt += 1
if attempt > r.maxRetries {
break
}
continue
}
if resp != nil && resp.StatusCode/100 >= 4 {
body, _ := io.ReadAll(resp.Body)
if body != nil {
@@ -161,6 +172,7 @@ func (r *HTTPClient) Do(req *http.Request) (*http.Response, error) {
}
}
incr := r.shouldRetry(resp, reqHasRangeHeader, err, r.cfg.GetRateLimitSleepSeconds())
r.log.Debugf("got %s incr %d/%d", req.URL, incr, attempt)
if incr > 0 {
attempt += incr
if attempt > r.maxRetries {
@@ -217,7 +229,10 @@ func (r *HTTPClient) proxyDialer(proxyURL *url.URL) (proxy.Dialer, error) {
return nil, fmt.Errorf("unsupported proxy scheme: %s", proxyURL.Scheme)
}
func shouldRetryFunc(resp *http.Response, reqHasRangeHeader bool, err error, rateLimitSleep int) int {
func (r *HTTPClient) shouldRetry(resp *http.Response, reqHasRangeHeader bool, err error, rateLimitSleep int) int {
if err != nil {
r.log.Errorf("http error +%v", err)
}
if err != nil && strings.HasPrefix(err.Error(), "api response error:") {
if apiErr, ok := err.(*ApiErrorResponse); ok {
switch apiErr.Code {
@@ -270,13 +285,15 @@ func backoffFunc(attempt int) time.Duration {
}
func (r *HTTPClient) CanFetchFirstByte(url string) bool {
timeout := time.Duration(r.cfg.GetRealDebridTimeout()) * time.Second
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return false
}
req.Header.Set("Range", "bytes=0-0")
req = req.WithContext(ctx)
resp, err := r.client.Do(req)
if err != nil {
return false