2020-09-22 02:20:22 +00:00
|
|
|
package dev.inmo.micro_utils.ktor.server
|
|
|
|
|
2021-12-14 12:01:41 +00:00
|
|
|
import dev.inmo.micro_utils.common.*
|
2020-09-26 15:42:05 +00:00
|
|
|
import dev.inmo.micro_utils.coroutines.safely
|
|
|
|
import dev.inmo.micro_utils.ktor.common.*
|
2022-03-04 14:16:59 +00:00
|
|
|
import io.ktor.http.*
|
2022-04-27 08:39:21 +00:00
|
|
|
import io.ktor.http.content.*
|
|
|
|
import io.ktor.server.application.ApplicationCall
|
|
|
|
import io.ktor.server.application.call
|
|
|
|
import io.ktor.server.request.receive
|
|
|
|
import io.ktor.server.request.receiveMultipart
|
|
|
|
import io.ktor.server.response.respond
|
|
|
|
import io.ktor.server.response.respondBytes
|
|
|
|
import io.ktor.server.routing.Route
|
|
|
|
import io.ktor.server.websocket.WebSocketServerSession
|
2020-11-27 08:35:00 +00:00
|
|
|
import io.ktor.util.pipeline.PipelineContext
|
2022-04-27 12:24:51 +00:00
|
|
|
import io.ktor.utils.io.core.*
|
2020-11-27 08:35:00 +00:00
|
|
|
import kotlinx.coroutines.flow.Flow
|
2022-04-27 08:39:21 +00:00
|
|
|
import kotlinx.serialization.DeserializationStrategy
|
|
|
|
import kotlinx.serialization.SerializationStrategy
|
2020-11-27 08:35:00 +00:00
|
|
|
|
2021-12-14 12:01:41 +00:00
|
|
|
suspend fun ApplicationCall.uniloadMultipart(
|
|
|
|
onFormItem: (PartData.FormItem) -> Unit = {},
|
|
|
|
onCustomFileItem: (PartData.FileItem) -> Unit = {},
|
2022-08-04 03:59:05 +00:00
|
|
|
onBinaryChannelItem: (PartData.BinaryChannelItem) -> Unit = {},
|
2021-12-14 12:01:41 +00:00
|
|
|
onBinaryContent: (PartData.BinaryItem) -> Unit = {}
|
|
|
|
) = safely {
|
|
|
|
val multipartData = receiveMultipart()
|
|
|
|
|
|
|
|
var resultInput: Input? = null
|
|
|
|
|
|
|
|
multipartData.forEachPart {
|
|
|
|
when (it) {
|
|
|
|
is PartData.FormItem -> onFormItem(it)
|
|
|
|
is PartData.FileItem -> {
|
|
|
|
when (it.name) {
|
2022-04-27 12:24:51 +00:00
|
|
|
"bytes" -> resultInput = it.provider()
|
2021-12-14 12:01:41 +00:00
|
|
|
else -> onCustomFileItem(it)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
is PartData.BinaryItem -> onBinaryContent(it)
|
2022-08-04 03:59:05 +00:00
|
|
|
is PartData.BinaryChannelItem -> onBinaryChannelItem(it)
|
2021-12-14 12:01:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
resultInput ?: error("Bytes has not been received")
|
|
|
|
}
|
|
|
|
|
|
|
|
suspend fun ApplicationCall.uniloadMultipartFile(
|
|
|
|
onFormItem: (PartData.FormItem) -> Unit = {},
|
|
|
|
onCustomFileItem: (PartData.FileItem) -> Unit = {},
|
2022-08-04 03:59:05 +00:00
|
|
|
onBinaryChannelItem: (PartData.BinaryChannelItem) -> Unit = {},
|
2021-12-14 12:01:41 +00:00
|
|
|
onBinaryContent: (PartData.BinaryItem) -> Unit = {},
|
|
|
|
) = safely {
|
|
|
|
val multipartData = receiveMultipart()
|
|
|
|
|
|
|
|
var resultInput: MPPFile? = null
|
|
|
|
|
|
|
|
multipartData.forEachPart {
|
|
|
|
when (it) {
|
|
|
|
is PartData.FormItem -> onFormItem(it)
|
|
|
|
is PartData.FileItem -> {
|
|
|
|
if (it.name == "bytes") {
|
|
|
|
val name = FileName(it.originalFileName ?: error("File name is unknown for default part"))
|
|
|
|
resultInput = MPPFile.createTempFile(
|
2021-12-27 09:55:05 +00:00
|
|
|
name.nameWithoutExtension.let {
|
|
|
|
var resultName = it
|
|
|
|
while (resultName.length < 3) {
|
|
|
|
resultName += "_"
|
|
|
|
}
|
|
|
|
resultName
|
|
|
|
},
|
2021-12-14 12:01:41 +00:00
|
|
|
".${name.extension}"
|
2021-12-14 15:13:11 +00:00
|
|
|
).apply {
|
2021-12-14 16:03:29 +00:00
|
|
|
outputStream().use { fileStream ->
|
2022-04-27 08:39:21 +00:00
|
|
|
it.streamProvider().use {
|
|
|
|
it.copyTo(fileStream)
|
|
|
|
}
|
2021-12-14 16:03:29 +00:00
|
|
|
}
|
2021-12-14 15:13:11 +00:00
|
|
|
}
|
2021-12-14 12:01:41 +00:00
|
|
|
} else {
|
|
|
|
onCustomFileItem(it)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
is PartData.BinaryItem -> onBinaryContent(it)
|
2022-08-04 03:59:05 +00:00
|
|
|
is PartData.BinaryChannelItem -> onBinaryChannelItem(it)
|
2021-12-14 12:01:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
resultInput ?: error("Bytes has not been received")
|
|
|
|
}
|
|
|
|
|
2020-09-22 02:20:22 +00:00
|
|
|
suspend fun ApplicationCall.getParameterOrSendError(
|
|
|
|
field: String
|
|
|
|
) = parameters[field].also {
|
|
|
|
if (it == null) {
|
|
|
|
respond(HttpStatusCode.BadRequest, "Request must contains $field")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun ApplicationCall.getQueryParameter(
|
|
|
|
field: String
|
|
|
|
) = request.queryParameters[field]
|
|
|
|
|
|
|
|
suspend fun ApplicationCall.getQueryParameterOrSendError(
|
|
|
|
field: String
|
|
|
|
) = getQueryParameter(field).also {
|
|
|
|
if (it == null) {
|
|
|
|
respond(HttpStatusCode.BadRequest, "Request query parameters must contains $field")
|
|
|
|
}
|
|
|
|
}
|