From 5104e3a2e71bd944d104888826268828f0a065c5 Mon Sep 17 00:00:00 2001 From: peterbanda Date: Thu, 21 Dec 2023 09:55:14 +0100 Subject: [PATCH] MultipartWritable - adding an extension-implied content type (expected by Azure file upload) --- .../service/ws/MultipartWritable.scala | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/openai-client/src/main/scala/io/cequence/openaiscala/service/ws/MultipartWritable.scala b/openai-client/src/main/scala/io/cequence/openaiscala/service/ws/MultipartWritable.scala index 3f25a1d0..335d2e50 100644 --- a/openai-client/src/main/scala/io/cequence/openaiscala/service/ws/MultipartWritable.scala +++ b/openai-client/src/main/scala/io/cequence/openaiscala/service/ws/MultipartWritable.scala @@ -19,6 +19,27 @@ object MultipartWritable { val CONTENT_TYPE = "content-type" } + private val fileExtensionContentTypeMap = Map( + "txt" -> "text/plain", + "csv" -> "text/csv", + "json" -> "application/json", + "xml" -> "application/xml", + "pdf" -> "application/pdf", + "zip" -> "application/zip", + "tar" -> "application/x-tar", + "gz" -> "application/x-gzip", + "ogg" -> "application/ogg", + "mp3" -> "audio/mpeg", + "wav" -> "audio/x-wav", + "mp4" -> "video/mp4", + "webm" -> "video/webm", + "png" -> "image/png", + "jpg" -> "image/jpeg", + "jpeg" -> "image/jpeg", + "gif" -> "image/gif", + "svg" -> "image/svg+xml" + ) + /** * `Writeable` for `MultipartFormData`. */ @@ -45,13 +66,21 @@ object MultipartWritable { def filePartHeader(file: FilePart) = { val name = s""""${file.key}"""" - val filename = s""""${file.headerFileName.getOrElse(file.path)}"""" - val contentType = file.contentType.map { ct => + val filenameAux = file.headerFileName.getOrElse(file.path) + val filenamePart = s""""${filenameAux}"""" + + val contentTypeAux = file.contentType.orElse { + val extension = filenameAux.split('.').last + // Azure expects an explicit content type for files + fileExtensionContentTypeMap.get(extension) + } + + val contentTypePart = contentTypeAux.map { ct => s"${HttpHeaderNames.CONTENT_TYPE}: $ct\r\n" }.getOrElse("") encode( - s"--$boundary\r\n${HttpHeaderNames.CONTENT_DISPOSITION}: form-data; name=$name; filename=$filename\r\n$contentType\r\n" + s"--$boundary\r\n${HttpHeaderNames.CONTENT_DISPOSITION}: form-data; name=$name; filename=$filenamePart\r\n$contentTypePart\r\n" ) }