Fix retries
This commit is contained in:
@@ -11,7 +11,6 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -168,7 +167,7 @@ func (r *HTTPClient) Do(req *http.Request) (*http.Response, error) {
|
||||
|
||||
attempt := 0
|
||||
var origBody []byte
|
||||
if req.Method == "POST" {
|
||||
if req.Method == "POST" || req.Method == "PUT" || req.Method == "PATCH" {
|
||||
origBody, _ = io.ReadAll(req.Body)
|
||||
}
|
||||
|
||||
@@ -179,8 +178,12 @@ func (r *HTTPClient) Do(req *http.Request) (*http.Response, error) {
|
||||
if resp != nil && resp.Body != nil {
|
||||
resp.Body.Close()
|
||||
}
|
||||
r.replaceHostIfNeeded(req) // needed for ipv6
|
||||
|
||||
r.replaceWithIPv6Host(req) // needed for ipv6
|
||||
|
||||
resp, err = r.client.Do(req)
|
||||
|
||||
// http 4xx and 5xx errors
|
||||
if resp != nil && resp.StatusCode/100 >= 4 {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
if body != nil {
|
||||
@@ -192,6 +195,7 @@ func (r *HTTPClient) Do(req *http.Request) (*http.Response, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
incr := r.shouldRetry(resp, reqHasRangeHeader, err, r.cfg.GetRateLimitSleepSecs())
|
||||
if incr > 0 {
|
||||
attempt += incr
|
||||
@@ -213,34 +217,30 @@ func (r *HTTPClient) Do(req *http.Request) (*http.Response, error) {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (r *HTTPClient) replaceHostIfNeeded(req *http.Request) {
|
||||
if strings.HasSuffix(req.Host, "download.real-debrid.cloud") || !r.supportIPv6 || !r.cfg.ShouldForceIPv6() {
|
||||
func (r *HTTPClient) replaceWithIPv6Host(req *http.Request) {
|
||||
// don't replace host if IPv6 is not supported or not forced
|
||||
if !r.supportIPv6 || !r.cfg.ShouldForceIPv6() {
|
||||
return
|
||||
}
|
||||
// get subdomain of req.Host
|
||||
subdomain := strings.Split(req.Host, ".")[0]
|
||||
// check if subdomain is numeric
|
||||
_, err := strconv.Atoi(subdomain)
|
||||
if err == nil {
|
||||
// subdomain is numeric, replace it with .cloud
|
||||
req.Host = strings.Replace(req.Host, ".com", ".cloud", 1)
|
||||
req.URL.Host = req.Host
|
||||
// this host should be replaced
|
||||
if !strings.HasSuffix(req.Host, ".download.real-debrid.com") {
|
||||
return
|
||||
}
|
||||
// check if host is in the list of IPv6 hosts
|
||||
found := false
|
||||
|
||||
req.Host = strings.Replace(req.Host, ".com", ".cloud", 1)
|
||||
req.URL.Host = req.Host
|
||||
// check if this host is in the list of IPv6 hosts
|
||||
for _, h := range r.ipv6Hosts {
|
||||
if h == req.Host {
|
||||
found = true
|
||||
break
|
||||
return
|
||||
}
|
||||
}
|
||||
if !found && !r.CanFetchFirstByte(req.URL.String()) {
|
||||
req.Host = r.ipv6Hosts[rand.Intn(len(r.ipv6Hosts))]
|
||||
r.log.Debugf("Host %s is not a valid IPv6 host, assigning a random IPv6 host: %s", req.URL.Host, req.Host)
|
||||
req.URL.Host = req.Host
|
||||
} else {
|
||||
r.ipv6Hosts = append(r.ipv6Hosts, req.Host)
|
||||
}
|
||||
|
||||
// if not then just assign a random IPv6 host
|
||||
req.Host = r.ipv6Hosts[rand.Intn(len(r.ipv6Hosts))]
|
||||
req.URL.Host = req.Host
|
||||
r.log.Debugf("Host %s is not a valid IPv6 host, assigning a random IPv6 host: %s", req.URL.Host, req.Host)
|
||||
// if !found && !r.CanFetchFirstByte(req.URL.String()) {
|
||||
}
|
||||
|
||||
func (r *HTTPClient) proxyDialer(proxyURL *url.URL) (proxy.Dialer, error) {
|
||||
@@ -287,9 +287,19 @@ func (r *HTTPClient) shouldRetry(resp *http.Response, reqHasRangeHeader bool, er
|
||||
}
|
||||
if resp != nil {
|
||||
if resp.StatusCode == 429 {
|
||||
// Too many requests: retry infinitely
|
||||
time.Sleep(time.Duration(rateLimitSleep) * time.Second)
|
||||
return 0
|
||||
}
|
||||
if resp.StatusCode/100 == 4 {
|
||||
// other client errors: retry
|
||||
return 1
|
||||
}
|
||||
if resp.StatusCode/100 == 5 {
|
||||
// server errors: don't retry
|
||||
return -1
|
||||
}
|
||||
// if the request has a Range header but the server doesn't respond with a Content-Range header
|
||||
if resp.StatusCode/100 == 2 && resp.Header.Get("Content-Range") == "" && reqHasRangeHeader {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user