Unrestrict uses download timeout
This commit is contained in:
@@ -44,11 +44,27 @@ func MainApp(configPath string) {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
apiClient := http.NewHTTPClient(config.GetToken(), config.GetRetriesUntilFailed(), config.GetApiTimeoutSecs(), false, config, log.Named("httpclient"))
|
apiClient := http.NewHTTPClient(
|
||||||
|
config.GetToken(),
|
||||||
|
config.GetRetriesUntilFailed(),
|
||||||
|
config.GetApiTimeoutSecs(),
|
||||||
|
false,
|
||||||
|
config,
|
||||||
|
log.Named("api_client"),
|
||||||
|
)
|
||||||
|
|
||||||
rd := realdebrid.NewRealDebrid(apiClient, log.Named("realdebrid"))
|
unrestrictClient := http.NewHTTPClient(
|
||||||
|
config.GetToken(),
|
||||||
|
config.GetRetriesUntilFailed(),
|
||||||
|
config.GetDownloadTimeoutSecs(),
|
||||||
|
false,
|
||||||
|
config,
|
||||||
|
log.Named("unrestrict_client"),
|
||||||
|
)
|
||||||
|
|
||||||
premium.MonitorPremiumStatus(rd, zurglog)
|
api := realdebrid.NewRealDebrid(apiClient, unrestrictClient, log.Named("realdebrid"))
|
||||||
|
|
||||||
|
premium.MonitorPremiumStatus(api, zurglog)
|
||||||
|
|
||||||
workerPool, err := ants.NewPool(config.GetNumOfWorkers())
|
workerPool, err := ants.NewPool(config.GetNumOfWorkers())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -58,13 +74,13 @@ func MainApp(configPath string) {
|
|||||||
defer workerPool.Release()
|
defer workerPool.Release()
|
||||||
|
|
||||||
utils.EnsureDirExists("data") // Ensure the data directory exists
|
utils.EnsureDirExists("data") // Ensure the data directory exists
|
||||||
torrentMgr := torrent.NewTorrentManager(config, rd, workerPool, log.Named("manager"))
|
torrentMgr := torrent.NewTorrentManager(config, api, workerPool, log.Named("manager"))
|
||||||
|
|
||||||
downloadClient := http.NewHTTPClient(config.GetToken(), config.GetRetriesUntilFailed(), config.GetDownloadTimeoutSecs(), true, config, log.Named("dlclient"))
|
downloadClient := http.NewHTTPClient(config.GetToken(), config.GetRetriesUntilFailed(), config.GetDownloadTimeoutSecs(), true, config, log.Named("download_client"))
|
||||||
downloader := universal.NewDownloader(downloadClient)
|
downloader := universal.NewDownloader(downloadClient)
|
||||||
|
|
||||||
router := chi.NewRouter()
|
router := chi.NewRouter()
|
||||||
handlers.AttachHandlers(router, downloader, torrentMgr, config, rd, workerPool, log.Named("router"))
|
handlers.AttachHandlers(router, downloader, torrentMgr, config, api, workerPool, log.Named("router"))
|
||||||
|
|
||||||
// go func() {
|
// go func() {
|
||||||
// if err := netHttp.ListenAndServe(":6060", nil); err != nil && err != netHttp.ErrServerClosed {
|
// if err := netHttp.ListenAndServe(":6060", nil); err != nil && err != netHttp.ErrServerClosed {
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ func (z *ZurgConfig) EnableDownloadMount() bool {
|
|||||||
|
|
||||||
func (z *ZurgConfig) GetApiTimeoutSecs() int {
|
func (z *ZurgConfig) GetApiTimeoutSecs() int {
|
||||||
if z.ApiTimeoutSecs == 0 {
|
if z.ApiTimeoutSecs == 0 {
|
||||||
return 15
|
return 60
|
||||||
}
|
}
|
||||||
return z.ApiTimeoutSecs
|
return z.ApiTimeoutSecs
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -249,6 +249,9 @@ func (r *HTTPClient) shouldRetry(resp *http.Response, reqHasRangeHeader bool, er
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil && strings.Contains(err.Error(), "timeout") {
|
if err != nil && strings.Contains(err.Error(), "timeout") {
|
||||||
|
if resp.Request.URL.Host == "api.real-debrid.com" && !strings.Contains(resp.Request.URL.Path, "unrestrict/") {
|
||||||
|
r.log.Warnf("Request timed out, adjust the timeout value in the config")
|
||||||
|
}
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
if resp != nil {
|
if resp != nil {
|
||||||
|
|||||||
@@ -14,14 +14,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type RealDebrid struct {
|
type RealDebrid struct {
|
||||||
log *logutil.Logger
|
client *zurghttp.HTTPClient
|
||||||
client *zurghttp.HTTPClient
|
unrestrictClient *zurghttp.HTTPClient
|
||||||
|
log *logutil.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRealDebrid(client *zurghttp.HTTPClient, log *logutil.Logger) *RealDebrid {
|
func NewRealDebrid(client, unrestrictClient *zurghttp.HTTPClient, log *logutil.Logger) *RealDebrid {
|
||||||
return &RealDebrid{
|
return &RealDebrid{
|
||||||
log: log,
|
client: client,
|
||||||
client: client,
|
unrestrictClient: unrestrictClient,
|
||||||
|
log: log,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +38,7 @@ func (rd *RealDebrid) UnrestrictCheck(link string) (*Download, error) {
|
|||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
resp, err := rd.client.Do(req)
|
resp, err := rd.unrestrictClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rd.log.Errorf("Error when executing the unrestrict check request: %v", err)
|
rd.log.Errorf("Error when executing the unrestrict check request: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -60,6 +62,52 @@ func (rd *RealDebrid) UnrestrictCheck(link string) (*Download, error) {
|
|||||||
return &response, nil
|
return &response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rd *RealDebrid) UnrestrictLink(link string, checkFirstByte bool) (*Download, error) {
|
||||||
|
data := url.Values{}
|
||||||
|
data.Set("link", link)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", "https://api.real-debrid.com/rest/1.0/unrestrict/link", bytes.NewBufferString(data.Encode()))
|
||||||
|
if err != nil {
|
||||||
|
rd.log.Errorf("Error when creating a unrestrict link request: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
|
// at this point, any errors mean that the link has expired and we need to repair it
|
||||||
|
resp, err := rd.unrestrictClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
// rd.log.Errorf("Error when executing the unrestrict link request: %v", err)
|
||||||
|
return nil, fmt.Errorf("unrestrict link request failed: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
rd.log.Errorf("Unrestrict link request returned status code %d for link %s", resp.StatusCode, link)
|
||||||
|
// return nil, fmt.Errorf("unrestrict link request returned status code %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
// rd.log.Errorf("Error when reading the body of unrestrict link response: %v", err)
|
||||||
|
return nil, fmt.Errorf("unreadable body: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var response Download
|
||||||
|
err = json.Unmarshal(body, &response)
|
||||||
|
if err != nil {
|
||||||
|
// rd.log.Errorf("Error when decoding unrestrict link JSON: %v", err)
|
||||||
|
return nil, fmt.Errorf("undecodable response: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if checkFirstByte && !rd.client.CanFetchFirstByte(response.Download) {
|
||||||
|
return nil, fmt.Errorf("can't fetch first byte")
|
||||||
|
}
|
||||||
|
|
||||||
|
// rd.log.Debugf("Unrestricted link %s into %s", link, response.Download)
|
||||||
|
return &response, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetTorrents returns all torrents, paginated
|
// GetTorrents returns all torrents, paginated
|
||||||
// if customLimit is 0, the default limit of 1000 is used
|
// if customLimit is 0, the default limit of 1000 is used
|
||||||
func (rd *RealDebrid) GetTorrents(customLimit int, active bool) ([]Torrent, int, error) {
|
func (rd *RealDebrid) GetTorrents(customLimit int, active bool) ([]Torrent, int, error) {
|
||||||
@@ -270,52 +318,6 @@ func (rd *RealDebrid) GetActiveTorrentCount() (*ActiveTorrentCountResponse, erro
|
|||||||
return &response, nil
|
return &response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rd *RealDebrid) UnrestrictLink(link string, checkFirstByte bool) (*Download, error) {
|
|
||||||
data := url.Values{}
|
|
||||||
data.Set("link", link)
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", "https://api.real-debrid.com/rest/1.0/unrestrict/link", bytes.NewBufferString(data.Encode()))
|
|
||||||
if err != nil {
|
|
||||||
rd.log.Errorf("Error when creating a unrestrict link request: %v", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
|
|
||||||
// at this point, any errors mean that the link has expired and we need to repair it
|
|
||||||
resp, err := rd.client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
// rd.log.Errorf("Error when executing the unrestrict link request: %v", err)
|
|
||||||
return nil, fmt.Errorf("unrestrict link request failed: %v", err)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
rd.log.Errorf("Unrestrict link request returned status code %d for link %s", resp.StatusCode, link)
|
|
||||||
// return nil, fmt.Errorf("unrestrict link request returned status code %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
// rd.log.Errorf("Error when reading the body of unrestrict link response: %v", err)
|
|
||||||
return nil, fmt.Errorf("unreadable body: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var response Download
|
|
||||||
err = json.Unmarshal(body, &response)
|
|
||||||
if err != nil {
|
|
||||||
// rd.log.Errorf("Error when decoding unrestrict link JSON: %v", err)
|
|
||||||
return nil, fmt.Errorf("undecodable response: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if checkFirstByte && !rd.client.CanFetchFirstByte(response.Download) {
|
|
||||||
return nil, fmt.Errorf("can't fetch first byte")
|
|
||||||
}
|
|
||||||
|
|
||||||
// rd.log.Debugf("Unrestricted link %s into %s", link, response.Download)
|
|
||||||
return &response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDownloads returns all torrents, paginated
|
// GetDownloads returns all torrents, paginated
|
||||||
func (rd *RealDebrid) GetDownloads(page, offset int) ([]Download, int, error) {
|
func (rd *RealDebrid) GetDownloads(page, offset int) ([]Download, int, error) {
|
||||||
baseURL := "https://api.real-debrid.com/rest/1.0/downloads"
|
baseURL := "https://api.real-debrid.com/rest/1.0/downloads"
|
||||||
|
|||||||
Reference in New Issue
Block a user