feat(debrid): add HTTPS downloader for debrid direct URLs

DebridDownloader receives directUrl from the server and downloads via
plain HTTPS with progress reporting, resume (Range), and pause/cancel.

- Add DirectURL, DirectFileName to agent Task and engine Task types
- Implement DebridDownloader: HTTPS download with progress, resume, cancel
- HTTP client with 30s ResponseHeaderTimeout
- Safe shortID helper to prevent slice panic on short IDs
- Validate 416 against Content-Range server size for resume integrity
- Register debridDl in daemon and one-shot download command
- Tests: available, download, resume, cancel, pause, fallback filename,
  expired URL (410), unauthorized (401), shutdown, task propagation
This commit is contained in:
Deivid Soto 2026-03-28 18:09:34 +01:00
parent 29cf0a0126
commit 5e80911501
7 changed files with 981 additions and 53 deletions

View file

@ -46,6 +46,8 @@ type Task struct {
ContentID *int
IMDbID string
PreferredMethod string // auto | torrent | debrid | usenet
DirectURL string // HTTPS download URL (debrid, etc.)
DirectFileName string // Original filename from direct URL
// Runtime state
Status TaskStatus
@ -80,6 +82,8 @@ func NewTaskFromAgent(at agent.Task) *Task {
ContentID: at.ContentID,
IMDbID: at.IMDbID,
PreferredMethod: at.PreferredMethod,
DirectURL: at.DirectURL,
DirectFileName: at.DirectFileName,
Mode: mode,
Status: StatusClaimed,
ClaimedAt: time.Now(),
@ -165,7 +169,15 @@ func (t *Task) ToStatusUpdate() agent.StatusUpdate {
apiStatus := ""
switch t.Status {
case StatusResolving, StatusDownloading, StatusVerifying, StatusOrganizing, StatusSeeding:
case StatusResolving:
apiStatus = "resolving"
case StatusDownloading:
apiStatus = "downloading"
case StatusVerifying:
apiStatus = "verifying"
case StatusOrganizing:
apiStatus = "organizing"
case StatusSeeding:
apiStatus = "downloading"
case StatusCompleted:
apiStatus = "completed"