tuskt
0.1.0indexedResumable tus protocol implementation offering a client, embeddable server library, standalone runnable server jar, shared protocol primitives, and end-to-end integration tests.
Resumable tus protocol implementation offering a client, embeddable server library, standalone runnable server jar, shared protocol primitives, and end-to-end integration tests.
Tuskt is a Kotlin implementation of the tus resumable upload protocol.
The repository currently contains:
:tuskt-client: a Kotlin Multiplatform tus client:tuskt-server: a Ktor-based tus server library:tuskt-server-standalone: a runnable server fat jar:shared: shared tus protocol constants and primitives:integration-tests: end-to-end client/server interoperability testsPublished library modules:
dev.phillipslabs:tuskt-clientdev.phillipslabs:tuskt-serverdev.phillipslabs:tuskt-sharedChoose the module based on how you want to consume the project:
tuskt-client: add a multiplatform tus client to your applicationtuskt-server: embed tus endpoints in a Ktor servertuskt-shared: use protocol constants and shared primitives directlytuskt-server-standalone: build and run the fat jar instead of adding a library dependencyGradle Kotlin DSL examples:
dependencies {
implementation("dev.phillipslabs:tuskt-client:<version>")
implementation("dev.phillipslabs:tuskt-server:<version>")
implementation("dev.phillipslabs:tuskt-shared:<version>")
}
For Kotlin Multiplatform, the client dependency typically belongs in commonMain:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("dev.phillipslabs:tuskt-client:<version>")
}
}
}
Tuskt is early-stage and currently implements the core resumable upload flow around:
OPTIONS for server capability discoveryHEAD for upload offset lookupPATCH for resuming/appending upload bytesThe current server does not yet implement tus extensions such as creation. You can see that reflected in the ignored server tests and TODOs in the codebase.
The multiplatform client currently supports:
OPTIONSHEADPATCHTargets currently configured in Gradle:
linuxX64, linuxArm64mingwX64The Ktor server library currently supports:
OPTIONS {basePath} returning Tus-VersionHEAD {basePath}/{id} returning The shared module exposes protocol headers and constants used by both the client and server, including TusHeaders, TUS_VERSION, and TUS_RESUME_VERSION.
The project currently uses:
2.3.203.4.2From the repository root:
./gradlew build
Useful module-level commands:
./gradlew :tuskt-client:build
./gradlew :tuskt-server:build
./gradlew :shared:build
./gradlew :integration-tests:build
Run the full verification suite:
./gradlew check test
Common targeted commands:
./gradlew :tuskt-server:test
./gradlew :tuskt-client:jvmTest
./gradlew :shared:jvmTest
./gradlew :integration-tests:test
./gradlew ktlintCheck detekt
TusktClient wraps a Ktor HttpClient and configures the required tus headers after initialization:
import dev.phillipslabs.tuskt.client.TusktClient
import io.ktor.client.*
import io.ktor.client.engine.cio.*
suspend fun example() {
val client =
TusktClient.initialize(
client =
HttpClient(CIO) {
expectSuccess = false
},
baseUrl = ,
)
client.use { tus ->
offset = tus.getUploadOffset()
result = tus.uploadBytes(.encodeToByteArray(), id = , offset = )
}
}
Today, uploadBytes assumes the upload resource already exists on the server.
You can embed the server in a Ktor engine using embeddedTusktServer:
import dev.phillipslabs.tuskt.TusktServerConfiguration
import dev.phillipslabs.tuskt.embeddedTusktServer
import io.ktor.server.netty.*
import kotlin.io.path.Path
fun main() {
embeddedTusktServer(
factory = Netty,
configuration =
TusktServerConfiguration(
host = "127.0.0.1",
port = 8080,
basePath = "/files",
storagePath = Path("files"),
),
).start(wait = true)
}
Defaults:
0.0.0.08080/files<repo-or-process-working-dir>/filesBuild the fat jar:
./gradlew :tuskt-server-standalone:shadowJar
Run it:
java -jar tuskt-server-standalone/build/libs/tuskt-server-standalone-0.1.0-SNAPSHOT.jar
Configuration is available through either system properties or environment variables:
tuskt.host or TUSKT_HOSTtuskt.port or TUSKT_PORTtuskt.basePath or TUSKT_BASE_PATHtuskt.storagePath or Example:
TUSKT_STORAGE_PATH=/tmp/tuskt-files TUSKT_PORT=9000 \
java -jar tuskt-server-standalone/build/libs/tuskt-server-standalone-0.1.0-SNAPSHOT.jar
dev.phillipslabs:tuskt-client: Kotlin Multiplatform tus clientdev.phillipslabs:tuskt-server: Ktor server librarydev.phillipslabs:tuskt-shared: shared protocol constants and primitivesSee CONTRIBUTING.md for local setup, coding conventions, and test guidance.
Upload-OffsetPATCH {basePath}/{id} with application/offset+octet-streamTus-Resumable version enforcementX-HTTP-Method-Override support via Ktor's method override pluginTUSKT_STORAGE_PATHSurfaced from shared tags and platforms — no rankings paid for.