MicroUtils/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/ServerRoutingShortcuts.kt

112 lines
3.8 KiB
Kotlin
Raw Normal View History

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.*
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
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 ->
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")
}
}