Home > Software engineering >  Post multipart via ktor-client
Post multipart via ktor-client

Time:04-06

I have to make a multipart request via ktor-client. Request method:

    suspend fun uploadPhoto(userId: String, bitmapPhoto: BitmapPhoto) {
        kotlin.runCatching {
            val response: HttpResponse = httpClient.submitFormWithBinaryData(
                url = BASE_URL.plus("$userId/${bitmapPhoto.name}"),
                formData = formData {
                    append("file", bitmapPhoto.bitmap.toByteArray(),
                        Headers.build {
                            append(HttpHeaders.ContentType, "multipart/form-data; boundary=boundary")
                            append(HttpHeaders.ContentDisposition, "form-data; name=file; filename=${bitmapPhoto.name}")
                        }
                    )
                }
            )
}

When executing request the server returns an error. There is the example of correct request

POST https://host-name.com
Content-Type: multipart/form-data; boundary=boundary;

--boundary
Content-Disposition: form-data; name="file"; filename="image.png"

< C:/path/image.png
--boundary

So i don't understand where is my kotlin method incorrect

UPDATE The 1st variant of method was

    suspend fun uploadPhoto(userId: String, bitmapPhoto: BitmapPhoto) {
        kotlin.runCatching {
            val response: HttpResponse = httpClient.submitFormWithBinaryData(
                url = BASE_URL.plus("$userId/${bitmapPhoto.name}"),
                formData = formData {
                    append("file", bitmapPhoto.bitmap.toByteArray(),
                        Headers.build {
                            append(HttpHeaders.ContentType, "image/png")
                            append(HttpHeaders.ContentDisposition, "filename=${bitmapPhoto.name}")
                        }
                    )
                }
            )
}

But it wasn't work so

CodePudding user response:

The problem is in the following headers:

append(HttpHeaders.ContentType, "multipart/form-data; boundary=boundary")
append(HttpHeaders.ContentDisposition, "form-data; name=file; filename=${bitmapPhoto.name}")

The Content-Type header should have a MIME type of the contents of your file (bitmapPhoto), not a type of the request body (Ktor adds it automatically), e.g. image/png. The Content-Disposition header should have only filename=${bitmapPhoto.name} value for your case because Ktor adds form-data; name=file; automatically. So your code should look like this:

append(HttpHeaders.ContentType, "image/png")
append(HttpHeaders.ContentDisposition, "filename=${bitmapPhoto.name}")

For more information, please refer to the Ktor documentation.

  • Related