Skip to content

Releases: goshitsarch-eng/gosh-dl

v0.5.0

Choose a tag to compare

@goshitsarch-eng goshitsarch-eng released this 09 Jun 20:10

Added

  • Batch operations: pause_all(), resume_all(), and cancel_all() engine APIs with per-download outcomes reported via the new BatchResult type (#11)
  • Pluggable persistence: DownloadEngine::with_storage() accepts any custom Storage implementation, enabling resume-from-breakpoint without the built-in SQLite storage or the storage feature (#11)
  • FileStorage: built-in file-based storage using one JSON sidecar per download (aria2 control-file analog) with atomic temp-file writes
  • Segment and SegmentState now derive Serialize/Deserialize, and async_trait is re-exported from gosh_dl::storage, making third-party Storage implementations easier

Changed

  • pause() (and pause_all()) now accepts downloads in the Queued state, so pausing the whole queue no longer lets waiting downloads get promoted into freed slots
  • Recursive discovery now fetches pages concurrently, honoring the previously unused RecursiveOptions::max_discovery_concurrency option (#10)
  • Updated transitive dependencies to pick up security fixes: quinn-proto 0.11.14, aws-lc-rs 1.17.0 / aws-lc-sys 0.41.0, rustls 0.23.40, rustls-webpki 0.103.13, reqwest 0.13.4, rand 0.9.4 / 0.10.1

Fixed

  • Pausing or cancelling a queued download no longer leaves an orphaned entry in the priority queue that could later acquire a download slot
  • CI workflow now declares least-privilege permissions: contents: read

v0.4.0

Choose a tag to compare

@goshitsarch-eng goshitsarch-eng released this 11 Apr 16:23

Added

  • Recursive HTTP directory mirroring behind the recursive-http feature flag
  • discover_http_recursive() and add_http_recursive() engine APIs
  • Recursive boundary types: RecursiveOptions, RecursiveManifest, RecursiveJob, TrackedRecursiveJob, RecursiveJobStatus, and RecursiveJobEvent
  • Recursive parent job lifecycle APIs: list_recursive_jobs(), recursive_job(), cancel_recursive_job(), remove_recursive_job(), and subscribe_recursive_jobs()
  • Dedicated recursive parent event stream separate from DownloadEvent
  • SQLite schema v4 support for persisted tracked recursive jobs
  • Regression coverage for HTTP limiter accounting, mirror failover, magnet preference retention, live config updates, and recursive parent-job behavior

Changed

  • Recursive HTTP child downloads now reuse the standard HTTP pipeline while carrying redirect-scope and fail-fast runtime metadata through persistence/restart
  • Runtime configuration updates now propagate to live HTTP bandwidth limits and download queue concurrency
  • Torrent downloads now derive runtime transport, webseed, and scheduling settings from EngineConfig::torrent

Fixed

  • Recursive enqueue is now transactional: if child creation fails partway through, already-added children are rolled back instead of being left orphaned
  • Recursive redirect scope is enforced during discovery, child downloads, and resumed child downloads restored from storage
  • HTTP rate limiting now charges exact byte counts instead of incorrect fixed-size chunks
  • Per-download HTTP mirrors and max_connections are now wired into execution
  • Resume now preserves priority, checksum, and mirrors
  • Magnet selected_files and sequential preferences now persist until metadata is available
  • Torrent webseed, transport policy, and encryption settings are now wired through without regressing plaintext/TCP defaults
  • Recursive HTTP child downloads no longer deadlock in Queued during state-transition updates

Documentation

  • Updated the README, technical spec, and recursive design/checklist docs to match the current shipped recursive feature set and remaining follow-up work

v0.3.2

Choose a tag to compare

@goshitsarch-eng goshitsarch-eng released this 11 Mar 22:15

Fixed

  • Downloads bombing out on mid-stream connection drops: body/decode errors from reqwest were classified as non-retryable, making the retry loop dead code for the most common failure mode — now correctly classified as retryable ConnectionReset
  • Double retryability bug in From<reqwest::Error>: the From impl computed a narrow retryable set instead of using the standard constructor which also covers ConnectionReset, Unreachable, 408, 429, and 5xx
  • Segment errors hardcoded as non-retryable: segment request send and stream errors now classify correctly via proper reqwest error conversion
  • Segmented download aggregate error always non-retryable: now preserves retryability from underlying segment errors
  • Single-stream downloads never retrying on stream errors: added automatic retry with resume (Range requests) or restart from byte 0 (no range support)
  • Segment progress lost on failure: segment progress is now saved to both memory cache and database before marking failure
  • Sibling segments wasting bandwidth after fatal error: added child cancellation token that stops siblings promptly on non-retryable errors

Changed

  • Default max_retries increased from 3 to 5

Added

  • 6 new integration tests for retry/resume edge cases

v0.3.1

Choose a tag to compare

@goshitsarch-eng goshitsarch-eng released this 08 Mar 18:34

Fixed

  • Segmented HTTP downloads now downgrade to a single stream and restart safely from byte 0 when a server or CDN stops honoring Range requests mid-transfer.
  • Single-connection HTTP resumes now restart cleanly from byte 0 when a server returns a full-body response instead of an appendable partial response.
  • Ranged-response validation now reports restart-required If-Range and validator mismatch cases more clearly without reintroducing over-100% progress.

v0.3.0

Choose a tag to compare

@goshitsarch-eng goshitsarch-eng released this 08 Mar 17:52

Fixed

  • Disabled transparent gzip/brotli decoding for engine-managed downloads and now force Accept-Encoding: identity so HTTP progress tracks transferred wire bytes.
  • Single-connection downloads now prefer the GET response length over HEAD, warn on mismatches, and fail early if streamed bytes exceed the expected total.
  • WebSeed requests now use the same identity-encoding behavior so torrent-backed web downloads keep progress aligned with transferred bytes.

v0.2.9

Choose a tag to compare

@goshitsarch-eng goshitsarch-eng released this 08 Mar 17:05

[0.2.9] - 2026-03-08

Fixed

  • HTTP progress exceeding 100%: resumed and segmented downloads now reject 200 OK responses to Range requests and require valid 206 Partial Content + Content-Range, preventing duplicate byte accounting when servers falsely advertise range support
  • Segment retry policy not honoring retryable HTTP statuses: 408, 429, and 5xx responses are now marked retryable so segmented downloads actually retry transient server failures before surfacing an error
  • Progress invariant coverage: added regression tests for lying range support, segmented retry/resume edge cases, and torrent progress bounds so completed_size no longer silently drifts past total_size

v0.2.8

Choose a tag to compare

@goshitsarch-eng goshitsarch-eng released this 07 Mar 04:51

Changed

  • Updated rand from 0.9 to 0.10 — avoids duplicate dependencies in downstream projects
    • Migrated from Rng trait to RngExt trait (renamed in 0.10)
  • Tightened mainline version from "6" to "6.1.0" to prevent resolving unexpectedly old versions

v0.2.7

Choose a tag to compare

@goshitsarch-eng goshitsarch-eng released this 14 Feb 19:43

Fixed

  • CI formatting failure: rustfmt required line-wrapping on tracing::debug! macro calls added in v0.2.6

v0.2.6

Choose a tag to compare

@goshitsarch-eng goshitsarch-eng released this 14 Feb 19:41

Fixed

  • Completed downloads lost on restart: persist_active_downloads() only saved downloads where is_active() returned true (Downloading/Seeding/Connecting), so completed state was never written to the database — added event-driven persistence that saves state immediately when a download completes
  • Completed downloads invisible after reload: load_persisted_downloads() had an explicit continue that skipped any download with Completed state, making completed downloads vanish from the UI on restart — removed the skip so completed downloads load as inert entries
  • Error state not persisted: downloads that failed were also never persisted (same is_active() filter), so error state and messages were lost on restart — added persistence at all five error transition sites

v0.2.5

Choose a tag to compare

@goshitsarch-eng goshitsarch-eng released this 14 Feb 17:37

Fixed

  • CI failures across all jobs: removed phantom test_http_large example entry from Cargo.toml that referenced a file not committed to the repository
  • Clippy too_many_arguments lint: added #[allow] on SegmentedDownload::start() which grew to 8 parameters after the retry policy addition
  • Code formatting: ran cargo fmt on files modified in v0.2.4 (engine.rs, segment.rs, webseed.rs)