Really stuck with translating multipart request from retrofit to ktor client.
In retrofit I have following method:
@Multipart
@POST("rest/sendPhotos")
suspend fun sendPhotos(@Part files: List<MultipartBody.Part>): Response<ResultDto>
in datasource layer it's called as:
fun sendFiles(files: List<File>): Response<ResultDto> {
val parts = mutableListOf<MultipartBody.Part>()
files.forEachIndexed { index, file ->
val requestFile = file.asRequestBody("multipart/form-items".toMediaTypeOrNull())
val part = MultipartBody.Part.createFormData("image_$index", file.name, requestFile)
parts.add(part)
}
return mainApiService.sendPhotos(parts)
}
In ktor I'm trying to translate it as:
private suspend fun sendFiles(files: List<File>): HttpResponse {
val parts = mutableListOf<PartData>()
files.forEachIndexed { index, file ->
val part = formData {
append("content", InputProvider(file.length()) { file.inputStream().asInput() }, Headers.build {
append(HttpHeaders.ContentType, "multipart/form-items")
append(HttpHeaders.ContentDisposition, "filename=\"${file.name}\"; name=\"image_$index\"")
})
}
parts.addAll(part)
}
return httpClient.post("rest/sendPhotos") {
setBody(MultiPartFormDataContent(
parts = parts,
))
}
}
But it doesn't work... Tried zillion variants, but helpless. Trying to fix it several days, unfortunately ktor logging can't help me, since it doesn't show body, printing smth like: [request body omitted]
Can anyone please help me? Any ideas or clues?
Added Retrofit logger reads:
Content-Type: multipart/form-data; boundary=0574af17-6a38-4888-af48-b368c4ce0f79
17:57:03.773 D Content-Length: 209034
17:57:03.773 D ticket: 00204e0d1669ccee81e6410390e48e530ba80c0c
17:57:03.788 D
17:57:03.793 D --0574af17-6a38-4888-af48-b368c4ce0f79
Content-Disposition: form-data; name="image_0"; filename="2024-01-03-00-56-48-232.jpg"
Content-Type: multipart/form-items
Content-Length: 208249
I can't get similar logs from ktor, it shows nothing except logs omitted - it's ugly...
According to the Retrofit logs, the equivalent Ktor code should be the following:
client.post("rest/sendPhotos") {
setBody(MultiPartFormDataContent(formData {
files.forEachIndexed { index, file ->
append("image_$index", file.readBytes(), Headers.build {
append(HttpHeaders.ContentType, "multipart/form-items")
append(HttpHeaders.ContentDisposition, "filename=\"${file.name}\"")
})
}
}))
}