Handling HTTP Uploads

Ktor supports handling HTTP Uploads. As well as receiving any other kind of content.

You can check out the Youkube example for a full example of this in action.

Receiving files using multipart

1. val multipart = call.receiveMultipart()
2. multipart.forEachPart { part ->
3. when (part) {
4. is PartData.FormItem -> {
5. if (part.name == "title") {
6. title = part.value
7. }
8. }
9. is PartData.FileItem -> {
10. val ext = File(part.originalFileName).extension
11. val file = File(uploadDir, "upload-${System.currentTimeMillis()}-${session.userId.hashCode()}-${title.hashCode()}.$ext")
12. part.streamProvider().use { input -> file.outputStream().buffered().use { output -> input.copyToSuspend(output) } }
13. videoFile = file
14. }
15. }

17. part.dispose()
18. }

21. suspend fun InputStream.copyToSuspend(
22. out: OutputStream,
23. bufferSize: Int = DEFAULT_BUFFER_SIZE,
24. yieldSize: Int = 4 * 1024 * 1024,
25. dispatcher: CoroutineDispatcher = Dispatchers.IO
26. ): Long {
27. return withContext(dispatcher) {
28. val buffer = ByteArray(bufferSize)
29. var bytesCopied = 0L
30. var bytesAfterYield = 0L
31. while (true) {
32. val bytes = read(buffer).takeIf { it >= 0 } ?: break
33. out.write(buffer, 0, bytes)
34. if (bytesAfterYield >= yieldSize) {
35. yield()
36. bytesAfterYield %= yieldSize
37. }
38. bytesCopied += bytes
39. bytesAfterYield += bytes
40. }
41. return@withContext bytesCopied
42. }
43. }