diff --git a/internal/universal/downloader.go b/internal/universal/downloader.go index e7f1c8e..56acd47 100644 --- a/internal/universal/downloader.go +++ b/internal/universal/downloader.go @@ -79,7 +79,7 @@ func (dl *Downloader) DownloadFile(directory, torrentName, fileName string, resp } if cfg.ShouldServeFromRclone() { if cfg.ShouldVerifyDownloadLink() { - if !torMgr.Api.CanFetchFirstByte(unrestrict.Download) { + if !dl.client.CanFetchFirstByte(unrestrict.Download) { log.Warnf("File %s is not available", fileName) http.Error(resp, "File is not available", http.StatusNotFound) return @@ -123,7 +123,7 @@ func (dl *Downloader) DownloadLink(fileName, link string, resp http.ResponseWrit } if cfg.ShouldServeFromRclone() { if cfg.ShouldVerifyDownloadLink() { - if !torMgr.Api.CanFetchFirstByte(unrestrict.Download) { + if !dl.client.CanFetchFirstByte(unrestrict.Download) { log.Warnf("File %s is not available", fileName) http.Error(resp, "File is not available", http.StatusNotFound) return diff --git a/pkg/http/client.go b/pkg/http/client.go index d04b3ca..4cae707 100644 --- a/pkg/http/client.go +++ b/pkg/http/client.go @@ -198,11 +198,12 @@ func (r *HTTPClient) replaceHostIfNeeded(req *http.Request) { break } } - if !found { - r.log.Debug("Not found, assigning random IPv6 host") - // random IPv6 host + if !found && !r.CanFetchFirstByte(req.URL.String()) { req.Host = r.ipv6Hosts[rand.Intn(len(r.ipv6Hosts))] req.URL.Host = req.Host + r.log.Debugf("Host is not a valid IPv6 host, assigning a random IPv6 host: %s", req.Host) + } else { + r.ipv6Hosts = append(r.ipv6Hosts, req.Host) } } @@ -267,3 +268,28 @@ func backoffFunc(attempt int) time.Duration { } return time.Duration(backoff) * time.Second } + +func (r *HTTPClient) CanFetchFirstByte(url string) bool { + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return false + } + + req.Header.Set("Range", "bytes=0-0") + + resp, err := r.client.Do(req) + if err != nil { + return false + } + defer resp.Body.Close() + + // If server supports partial content + if resp.StatusCode/100 == 2 { + buffer := make([]byte, 1) + _, err = resp.Body.Read(buffer) + if err == nil { + return true + } + } + return false +} diff --git a/pkg/realdebrid/api.go b/pkg/realdebrid/api.go index 6ef5eae..b13be9c 100644 --- a/pkg/realdebrid/api.go +++ b/pkg/realdebrid/api.go @@ -308,7 +308,7 @@ func (rd *RealDebrid) UnrestrictLink(link string, checkFirstByte bool) (*Downloa return nil, fmt.Errorf("undecodable response: %v", err) } - if checkFirstByte && !rd.CanFetchFirstByte(response.Download) { + if checkFirstByte && !rd.client.CanFetchFirstByte(response.Download) { return nil, fmt.Errorf("can't fetch first byte") } diff --git a/pkg/realdebrid/unrestrict.go b/pkg/realdebrid/unrestrict.go deleted file mode 100644 index 45dad97..0000000 --- a/pkg/realdebrid/unrestrict.go +++ /dev/null @@ -1,30 +0,0 @@ -package realdebrid - -import ( - "net/http" -) - -func (rd *RealDebrid) CanFetchFirstByte(url string) bool { - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return false - } - - req.Header.Set("Range", "bytes=0-0") - - resp, err := rd.client.Do(req) - if err != nil { - return false - } - defer resp.Body.Close() - - // If server supports partial content - if resp.StatusCode/100 == 2 { - buffer := make([]byte, 1) - _, err = resp.Body.Read(buffer) - if err == nil { - return true - } - } - return false -}