A multi-threaded download engine for the JVM

TurboDL is a download core written from scratch in pure Kotlin: HTTP Range segments in parallel, resumable, with a plugin framework for everything that is not HTTP. No Android dependency — it runs in any JVM application, servers included.

v0.2.2.0
Requires
JVM 17+
License
MIT
Tested with
258 tests, 0 skipped, 0 failed

What it does

Six things that matter for a download engine — the rest is in the README.

Segmented parallel download

HTTP Range segments downloaded in parallel, with connection reuse (HTTP/2 multiplexing + keep-alive).

Dynamic segmentation + work stealing

Fine-grained pre-splitting plus work stealing, so one slow connection cannot drag the whole transfer down — and the "last segment on a single thread" long tail disappears.

Restrained adaptivity

Concurrency drops **only** on 429/503 or after consecutive failures. Ordinary jitter never touches the thread count — no AIMD oscillation.

Resume from real progress

Segments are persisted on disk; pause/resume continues from what actually landed, not from a remembered number.

Range tampering rejected

The bytes actually returned are checked against the Range that was requested — a server that ignores Range and sends the whole file is caught, not written as misplaced data.

Byte-level integrity check

Total size is verified after the merge step; a short or oversized result is rejected.

Nine engine capabilities

Every knob is a public config field — no hidden magic.

CapabilityConfig fieldNotes
Global speed limitglobalSpeedLimitBytesPerSec0 = unlimited
Thread countmaxConnectionsPerTask1..256
Concurrent tasksmaxConcurrentTasks1..64
Max retriesmaxRetries0..50
Dynamic segmentationdynamicSegmentationtrue / false
ProxyproxyDirect / System / Manual(HTTP,SOCKS,auth) / Pac(url)
DNSdnsSystem / StaticHosts / DoH(url)
Ignore SSLtrustAllCertspacket-capture debugging
Theming—upper-layer app's job; the SDK renders no UI

Modules

Only turbodl-core is required. Everything else is a plugin you add on purpose.

ArtifactRoleRequired?
turbodl-coreDownload engine SDK
Segmented parallel download, resume, retry, speed limit, DNS/proxy. Publishes fine on its own and has **no** plugin-framework dependency.
required
turbo-plugin-runtimePlugin runtime kernel
Lifecycle, cleanup (disposer), event bus, service registry, extension points, version handshake, diagnostics. Knows nothing about any specific protocol.
optional
turbo-plugin-bootstrapBootstrap wiring
One-call wiring of the base plugins (Kotlin loader + HTTP backend) and the bridge from the engine's event stream.
optional
turbo-plugin-hlsHLS VOD adapter
Resolves M3U8 playlists, downloads segments concurrently (with per-segment retry), decrypts AES-128, honors EXT-X-BYTERANGE. Live/DRM/fMP4 playlists are refused explicitly instead of producing corrupt output.
optional
turbo-plugin-jsJavaScript plugin loader
Loads TurboDL plugins written in JavaScript. Embeds QuickJS — one runtime and one context per script — and exposes a stable `host`/`plugin` ABI with coarse-grained capabilities.
optional
turbodl-cliCommand-line tool
A complete CLI built on the SDK: multi-threaded, resumable, batch mode, NDJSON output for scripts and agents. Shipped as a fat JAR.
optional

Quick start

Add one dependency, submit a request, collect events. The full API — pause / resume / cancel / batch / diagnostics — is in the docs.

Kotlin
val client = TurboClient(
    TurboConfig(
        maxConnectionsPerTask = 16,      // up to 256 / 最高 256
        globalSpeedLimitBytesPerSec = 0, // 0 = unlimited / 不限速
        dynamicSegmentation = true,
    )
)

val id = client.submit(
    DownloadRequest(url = "https://example.com/big.zip", destination = File("big.zip"))
)

client.events.collect { event ->
    when (event) {
        is TurboEvent.Progress  -> println("${event.progress.percent}%")
        is TurboEvent.Completed -> println("done: ${event.file}")
        is TurboEvent.Failed    -> println("failed: ${event.reason}")
        else -> {}
    }
}

val result = client.await(id)   // Result<File>
client.shutdown()

Plugin framework

TurboDL is a standalone engine and an optional plugin platform. The kernel knows no protocols: lifecycle, cleanup, event bus, service registry, extension points, a version handshake and diagnostics — that is the whole of it.

Kotlin · bootstrap
val boot = TurboBootstrap.create(
    config = TurboConfig(maxConnectionsPerTask = 16),
    extraPlugins = listOf(HlsPlugin()),
)

boot.host.loadSource(
    PluginSource(kind = "js", uri = "/opt/turbodl-plugins/acme-parser.js")
)

Written down, in one place

Everything a reader might want — how to write a plugin, what the manifest requires, which libraries ship along, what leaves your machine, and what the license actually says — is a page here and a file in the repository. Both are rendered from the same source, so they cannot drift apart.