mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-11-17 13:53:49 +00:00
add uniupload for JVM
This commit is contained in:
parent
b7b5159e9c
commit
a3090cca9d
@ -1,15 +1,18 @@
|
|||||||
package dev.inmo.micro_utils.ktor.client
|
package dev.inmo.micro_utils.ktor.client
|
||||||
|
|
||||||
import dev.inmo.micro_utils.common.FileName
|
import dev.inmo.micro_utils.common.FileName
|
||||||
|
import dev.inmo.micro_utils.ktor.common.LambdaInputProvider
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.http.Headers
|
import io.ktor.http.Headers
|
||||||
import io.ktor.utils.io.core.Input
|
import io.ktor.utils.io.core.Input
|
||||||
import kotlinx.serialization.DeserializationStrategy
|
import kotlinx.serialization.DeserializationStrategy
|
||||||
import kotlinx.serialization.StringFormat
|
import kotlinx.serialization.StringFormat
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
data class UniUploadFileInfo(
|
data class UniUploadFileInfo(
|
||||||
val fileName: FileName,
|
val fileName: FileName,
|
||||||
val bytesAllocator: Input
|
val mimeType: String,
|
||||||
|
val inputAllocator: LambdaInputProvider
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,7 +25,7 @@ data class UniUploadFileInfo(
|
|||||||
expect suspend fun <T> HttpClient.uniupload(
|
expect suspend fun <T> HttpClient.uniupload(
|
||||||
url: String,
|
url: String,
|
||||||
data: Map<String, Any>,
|
data: Map<String, Any>,
|
||||||
stringFormat: StringFormat,
|
|
||||||
resultDeserializer: DeserializationStrategy<T>,
|
resultDeserializer: DeserializationStrategy<T>,
|
||||||
headers: Headers = Headers.Empty
|
headers: Headers = Headers.Empty,
|
||||||
|
stringFormat: StringFormat = Json.Default
|
||||||
): T?
|
): T?
|
||||||
|
@ -4,6 +4,8 @@ import dev.inmo.micro_utils.common.MPPFile
|
|||||||
import io.ktor.client.request.forms.InputProvider
|
import io.ktor.client.request.forms.InputProvider
|
||||||
import io.ktor.utils.io.streams.asInput
|
import io.ktor.utils.io.streams.asInput
|
||||||
|
|
||||||
actual suspend fun MPPFile.inputProvider(): InputProvider = InputProvider(length()) {
|
fun MPPFile.inputProviderSync(): InputProvider = InputProvider(length()) {
|
||||||
inputStream().asInput()
|
inputStream().asInput()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actual suspend fun MPPFile.inputProvider(): InputProvider = inputProviderSync()
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
package dev.inmo.micro_utils.ktor.client
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.common.input
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.request.forms.InputProvider
|
||||||
|
import io.ktor.client.request.forms.formData
|
||||||
|
import io.ktor.client.request.forms.submitForm
|
||||||
|
import io.ktor.client.request.forms.submitFormWithBinaryData
|
||||||
|
import io.ktor.client.statement.bodyAsText
|
||||||
|
import io.ktor.http.Headers
|
||||||
|
import io.ktor.http.HttpHeaders
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.http.Parameters
|
||||||
|
import io.ktor.http.content.PartData
|
||||||
|
import kotlinx.serialization.DeserializationStrategy
|
||||||
|
import kotlinx.serialization.InternalSerializationApi
|
||||||
|
import kotlinx.serialization.StringFormat
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
|
import kotlinx.serialization.serializer
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will execute submitting of multipart data request
|
||||||
|
*
|
||||||
|
* @param data [Map] where keys will be used as names for multipart parts and values as values. If you will pass
|
||||||
|
* [dev.inmo.micro_utils.common.MPPFile] (File from JS or JVM platform). Also you may pass [UniUploadFileInfo] as value
|
||||||
|
* in case you wish to pass other source of multipart binary data than regular file
|
||||||
|
*/
|
||||||
|
@OptIn(InternalSerializationApi::class)
|
||||||
|
actual suspend fun <T> HttpClient.uniupload(
|
||||||
|
url: String,
|
||||||
|
data: Map<String, Any>,
|
||||||
|
resultDeserializer: DeserializationStrategy<T>,
|
||||||
|
headers: Headers,
|
||||||
|
stringFormat: StringFormat
|
||||||
|
): T? {
|
||||||
|
val withBinary = data.values.any { it is File || it is UniUploadFileInfo }
|
||||||
|
|
||||||
|
val formData = formData {
|
||||||
|
data.forEach { (k, v) ->
|
||||||
|
when (v) {
|
||||||
|
is File -> append(
|
||||||
|
k,
|
||||||
|
v.inputProviderSync(),
|
||||||
|
Headers.build {
|
||||||
|
append(HttpHeaders.ContentType, v.mimeType)
|
||||||
|
append(HttpHeaders.ContentDisposition, "filename=\"${v.name}\"")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
is UniUploadFileInfo -> append(
|
||||||
|
k,
|
||||||
|
InputProvider(block = v.inputAllocator),
|
||||||
|
Headers.build {
|
||||||
|
append(HttpHeaders.ContentType, v.mimeType)
|
||||||
|
append(HttpHeaders.ContentDisposition, "filename=\"${v.fileName.name}\"")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else -> append(
|
||||||
|
k,
|
||||||
|
stringFormat.encodeToString(v)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val response = if (withBinary) {
|
||||||
|
submitFormWithBinaryData(
|
||||||
|
url,
|
||||||
|
formData
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
submitForm(
|
||||||
|
url,
|
||||||
|
Parameters.build {
|
||||||
|
formData.forEach {
|
||||||
|
val formItem = (it as PartData.FormItem)
|
||||||
|
append(it.name!!, it.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (response.status == HttpStatusCode.OK) {
|
||||||
|
stringFormat.decodeFromString(resultDeserializer, response.bodyAsText())
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package dev.inmo.micro_utils.ktor.common
|
||||||
|
|
||||||
|
import io.ktor.utils.io.core.Input
|
||||||
|
|
||||||
|
typealias LambdaInputProvider = () -> Input
|
Loading…
Reference in New Issue
Block a user