Olivier Patry
11/04/2024, 3:00 PMMultiPartFormDataContent
and ContentType.MultiPart.Mixed.withParameter("boundary", boundary)
but I'm a bit lost on the next steps.
Does anyone achieve this already?Olivier Patry
11/04/2024, 3:01 PMOlivier Patry
11/04/2024, 3:02 PMMultiPartFormDataContent
Olivier Patry
11/04/2024, 3:23 PMval response = httpClient.post("<https://tasks.googleapis.com/batch>") {
// FIXME what would be a better boundary name?
val boundary = "batch_${Clock.System.now().toEpochMilliseconds().toString().encodeBase64()}"
val contentType = ContentType.MultiPart.Mixed.withParameter("boundary", boundary)
setBody(
MultiPartFormDataContent(
listOf(
PartData.FormItem(
value = "GET /tasks/v1/users/@me/lists HTTP/1.1",
dispose = {},
partHeaders = headersOf("Content-Type", "application/http"),
),
PartData.FormItem(
value = "GET /tasks/v1/users/@me/liPLOPsts HTTP/1.1",
dispose = {},
partHeaders = headersOf("Content-Type", "application/http"),
),
),
boundary,
contentType
)
)
}
Olivier Patry
11/04/2024, 4:08 PMif (response.status.isSuccess()) {
val contentType = response.headers["Content-Type"]
?: error("No Content-Type header")
println("Content-Type: $contentType")
when {
contentType.startsWith("multipart/mixed") -> {
val boundary = contentType
.split("; ")
.onEach(::println)
.find { it.startsWith("boundary=") }
?.removePrefix("boundary=")
?: error("No boundary in Content-Type header")
val batchBody = response.bodyAsText().removeSuffix("--$boundary--\r\n")
val parts = batchBody.split("--$boundary").mapNotNull { part ->
if (part.isBlank()) return@mapNotNull null // Skip empty segments
val partData = part.trim().split("\r\n\r\n", limit = 3)
// TODO check status line
val body = partData.getOrElse(2) { "" }
Json.decodeFromString<ResourceListResponse<TaskList>>(body)
}
.onEach { println(it) }
}
else -> error("Unexpected Content-Type: $contentType")
}
} else {
throw ClientRequestException(response, response.bodyAsText())
}
Olivier Patry
11/04/2024, 4:53 PMHttpResponse
from each batch subpart, but can't figure out how to do so.Olivier Patry
11/04/2024, 8:44 PMMultipart.kt
impl but struggle to use it for my needs.
I also found https://youtrack.jetbrains.com/issue/KTOR-6632/Support-receiving-multipart-data-with-Ktor-client which goes in the same direction, but using an internal APIOlivier Patry
11/04/2024, 8:45 PMOsip Fatkullin
11/06/2024, 1:10 PMe5l
11/06/2024, 1:11 PMe5l
11/06/2024, 2:15 PM