add server part of uniUpload, fill changelog

This commit is contained in:
InsanusMokrassar 2022-11-22 13:38:36 +06:00
parent 844a129094
commit 2b5380f8d6
5 changed files with 63 additions and 29 deletions

View File

@ -2,6 +2,14 @@
## 0.14.3
* `Common`:
* New type `Progress`
* `Ktor`:
* `Client`:
* New universal `uniUpload` extension for `HttpClient`
* `Server`:
* New universal `handleUniUpload` extension for `ApplicationCall`
## 0.14.2
* `Versions`:

View File

@ -21,7 +21,7 @@ data class UniUploadFileInfo(
* [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
*/
expect suspend fun <T> HttpClient.uniupload(
expect suspend fun <T> HttpClient.uniUpload(
url: String,
data: Map<String, Any>,
resultDeserializer: DeserializationStrategy<T>,

View File

@ -25,7 +25,7 @@ import org.w3c.xhr.XMLHttpRequestResponseType
* [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
*/
actual suspend fun <T> HttpClient.uniupload(
actual suspend fun <T> HttpClient.uniUpload(
url: String,
data: Map<String, Any>,
resultDeserializer: DeserializationStrategy<T>,
@ -55,6 +55,9 @@ actual suspend fun <T> HttpClient.uniupload(
}
val request = XMLHttpRequest()
headers.forEach { s, strings ->
request.setRequestHeader(s, strings.joinToString())
}
request.responseType = XMLHttpRequestResponseType.TEXT
request.upload.onprogress = {
onUpload(it.loaded.toLong(), it.total.toLong())

View File

@ -2,11 +2,14 @@ package dev.inmo.micro_utils.ktor.client
import dev.inmo.micro_utils.common.Progress
import io.ktor.client.HttpClient
import io.ktor.client.engine.mergeHeaders
import io.ktor.client.plugins.onUpload
import io.ktor.client.request.HttpRequestBuilder
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.request.headers
import io.ktor.client.statement.bodyAsText
import io.ktor.http.Headers
import io.ktor.http.HttpHeaders
@ -25,7 +28,7 @@ import java.io.File
* [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
*/
actual suspend fun <T> HttpClient.uniupload(
actual suspend fun <T> HttpClient.uniUpload(
url: String,
data: Map<String, Any>,
resultDeserializer: DeserializationStrategy<T>,
@ -62,15 +65,21 @@ actual suspend fun <T> HttpClient.uniupload(
}
}
val response = if (withBinary) {
submitFormWithBinaryData(
url,
formData
) {
val requestBuilder: HttpRequestBuilder.() -> Unit = {
headers {
appendAll(headers)
}
onUpload { bytesSentTotal, contentLength ->
onUpload(bytesSentTotal, contentLength)
}
}
val response = if (withBinary) {
submitFormWithBinaryData(
url,
formData,
block = requestBuilder
)
} else {
submitForm(
url,
@ -79,12 +88,9 @@ actual suspend fun <T> HttpClient.uniupload(
val formItem = (it as PartData.FormItem)
append(it.name!!, it.value)
}
}
) {
onUpload { bytesSentTotal, contentLength ->
onUpload(bytesSentTotal, contentLength)
}
}
},
block = requestBuilder
)
}
return if (response.status == HttpStatusCode.OK) {

View File

@ -7,29 +7,46 @@ import io.ktor.server.application.ApplicationCall
import io.ktor.server.request.receiveMultipart
import io.ktor.utils.io.core.*
/**
* Server-side part which receives [dev.inmo.micro_utils.ktor.client.uniUpload] request
*/
suspend fun ApplicationCall.handleUniUpload(
onFormItem: (PartData.FormItem) -> Unit = {},
onFileItem: (PartData.FileItem) -> Unit = {},
onBinaryChannelItem: (PartData.BinaryChannelItem) -> Unit = {},
onBinaryContent: (PartData.BinaryItem) -> Unit = {}
) {
val multipartData = receiveMultipart()
multipartData.forEachPart {
when (it) {
is PartData.FormItem -> onFormItem(it)
is PartData.FileItem -> onFileItem(it)
is PartData.BinaryItem -> onBinaryContent(it)
is PartData.BinaryChannelItem -> onBinaryChannelItem(it)
}
}
}
suspend fun ApplicationCall.uniloadMultipart(
onFormItem: (PartData.FormItem) -> Unit = {},
onCustomFileItem: (PartData.FileItem) -> Unit = {},
onBinaryChannelItem: (PartData.BinaryChannelItem) -> Unit = {},
onBinaryContent: (PartData.BinaryItem) -> Unit = {}
) = safely {
val multipartData = receiveMultipart()
var resultInput: Input? = null
multipartData.forEachPart {
when (it) {
is PartData.FormItem -> onFormItem(it)
is PartData.FileItem -> {
handleUniUpload(
onFormItem,
{
when (it.name) {
"bytes" -> resultInput = it.provider()
else -> onCustomFileItem(it)
}
}
is PartData.BinaryItem -> onBinaryContent(it)
is PartData.BinaryChannelItem -> onBinaryChannelItem(it)
}
}
},
onBinaryChannelItem,
onBinaryContent
)
resultInput ?: error("Bytes has not been received")
}