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

@ -171,6 +171,34 @@ func TestToStatusUpdate(t *testing.T) {
}
}
func TestToStatusUpdateGranularStates(t *testing.T) {
tests := []struct {
status TaskStatus
wantAPI string
}{
{StatusResolving, "resolving"},
{StatusDownloading, "downloading"},
{StatusVerifying, "verifying"},
{StatusOrganizing, "organizing"},
{StatusCompleted, "completed"},
{StatusFailed, "failed"},
{StatusSeeding, "downloading"}, // seeding maps to downloading for backwards compat
}
for _, tt := range tests {
t.Run(string(tt.status), func(t *testing.T) {
task := &Task{
ID: "task-1",
Status: tt.status,
}
update := task.ToStatusUpdate()
if update.Status != tt.wantAPI {
t.Errorf("ToStatusUpdate().Status for %s = %q, want %q", tt.status, update.Status, tt.wantAPI)
}
})
}
}
func TestMagnetURI(t *testing.T) {
task := &Task{InfoHash: "abc123"}
m := task.MagnetURI()