How to upload a file using Ktor client

Viewed 5596

I have read the docs about HTTP requests in Ktor clients, but it lacks of an example of file upload. It mentions PartData.FileItem, but it's unclear how to use it.

So, how do I prepare a multipart/form-data request for file upload in Ktor?

1 Answers

You should use submitFormWithBinaryData's formData parameter to provide a list of parts. There is a helper function with the same name to create such list.

HttpClient(Apache).use { client ->
    val parts: List<PartData> = formData {
        // Regular form parameter
        append("text", "Hello, world")

        // File upload. Param name is "file-1" and file's name is "file.csv"
        append("file-1", "file.csv", ContentType.Text.CSV) {
            this.append("1,2,3")
        }

        // Verbose DSL
        val headersBuilder = HeadersBuilder()
        headersBuilder[HttpHeaders.ContentType] = "application/java-archive"
        headersBuilder[HttpHeaders.ContentDisposition] = "filename=wrapper.jar"
        this.append(
                "file-2",
                InputProvider { File("gradle/wrapper/gradle-wrapper.jar").inputStream().asInput() },
                headersBuilder.build()
        )
    }

    client.submitFormWithBinaryData<Unit>(formData = parts /* prepared parts */) {
        url("https://hookb.in/XXX")

        // Query string parameters
        parameter("param-1", "value-1")
        parameter("param-2", "value-2-1")
        parameter("param-2", "value-2-2")

        // Headers
        headers {
            this["X-My-Header-1"] = "X-My-Header-1-Value"
            appendAll("X-My-Header-2", listOf("X-My-Header-2-Value-1", "X-My-Header-2-Value-2"))
        }
    }
}
Related