diff --git a/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/ktor/client/OnUploadCallback.kt b/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/ktor/client/OnUploadCallback.kt index abd79c93b2b..86c7d065b09 100644 --- a/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/ktor/client/OnUploadCallback.kt +++ b/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/ktor/client/OnUploadCallback.kt @@ -1,3 +1,3 @@ package dev.inmo.micro_utils.ktor.client -typealias OnUploadCallback = suspend (uploaded: Long, count: Long) -> Unit +typealias OnUploadCallback = suspend (uploaded: Long, count: Long?) -> Unit diff --git a/ktor/common/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/common/CreateTempFileFromInput.kt b/ktor/common/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/common/CreateTempFileFromInput.kt index 3ec4ee47bff..d49edd0c0d8 100644 --- a/ktor/common/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/common/CreateTempFileFromInput.kt +++ b/ktor/common/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/common/CreateTempFileFromInput.kt @@ -1,10 +1,9 @@ package dev.inmo.micro_utils.ktor.common -import io.ktor.utils.io.core.* +import io.ktor.utils.io.core.Input import kotlinx.io.asSink import java.io.File import java.util.UUID -import kotlin.io.use fun Input.downloadToTempFile( fileName: String = UUID.randomUUID().toString(), @@ -15,8 +14,8 @@ fun Input.downloadToTempFile( fileExtension, folder ).apply { - outputStream().use { output -> - this@downloadToTempFile.transferTo(output.asSink()) + outputStream().use { + this@downloadToTempFile.transferTo(it.asSink()) } deleteOnExit() } diff --git a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/ApplicationCallRespondWithTypeInfo.kt b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/ApplicationCallRespondWithTypeInfo.kt index 207dde73a63..5c1ce621af9 100644 --- a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/ApplicationCallRespondWithTypeInfo.kt +++ b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/ApplicationCallRespondWithTypeInfo.kt @@ -1,8 +1,9 @@ package dev.inmo.micro_utils.ktor.server import io.ktor.server.application.ApplicationCall +import io.ktor.server.http.* import io.ktor.server.response.responseType -import io.ktor.util.InternalAPI +import io.ktor.utils.io.InternalAPI import io.ktor.util.reflect.TypeInfo @InternalAPI @@ -11,5 +12,5 @@ suspend fun ApplicationCall.respond( typeInfo: TypeInfo ) { response.responseType = typeInfo - response.pipeline.execute(this, message as Any) + respond(message, typeInfo) } diff --git a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/DownloadFileItem.kt b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/DownloadFileItem.kt index 2abdddd2e0c..d2f367644db 100644 --- a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/DownloadFileItem.kt +++ b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/DownloadFileItem.kt @@ -2,22 +2,19 @@ package dev.inmo.micro_utils.ktor.server import com.benasher44.uuid.uuid4 import io.ktor.http.content.PartData -import io.ktor.utils.io.copyTo -import io.ktor.utils.io.core.copyTo -import io.ktor.utils.io.jvm.javaio.* -import io.ktor.utils.io.streams.* +import io.ktor.util.cio.* +import io.ktor.utils.io.* +import io.ktor.utils.io.jvm.javaio.copyTo import kotlinx.io.asSink import java.io.File -fun PartData.FileItem.download(target: File) { - provider().toInputStream().asInput().use { input -> - target.outputStream().use { output -> - input.transferTo(output.asSink()) - } - } +suspend fun PartData.FileItem.download(target: File) { + provider().copyAndClose( + target.writeChannel() + ) } -fun PartData.FileItem.downloadToTemporalFile(): File { +suspend fun PartData.FileItem.downloadToTemporalFile(): File { val outputFile = File.createTempFile(uuid4().toString(), ".temp").apply { deleteOnExit() } @@ -27,8 +24,8 @@ fun PartData.FileItem.downloadToTemporalFile(): File { fun PartData.BinaryItem.download(target: File) { provider().use { input -> - target.outputStream().use { output -> - input.transferTo(output.asSink()) + target.outputStream().use { + input.transferTo(it.asSink()) } } } diff --git a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/NewFlowsWebsocket.kt b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/NewFlowsWebsocket.kt index e51cb579fb3..0240a55fc5e 100644 --- a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/NewFlowsWebsocket.kt +++ b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/NewFlowsWebsocket.kt @@ -6,7 +6,7 @@ import io.ktor.http.URLProtocol import io.ktor.server.application.install import io.ktor.server.application.pluginOrNull import io.ktor.server.routing.Routing -import io.ktor.server.routing.* +import io.ktor.server.routing.application import io.ktor.server.websocket.* import io.ktor.websocket.send import kotlinx.coroutines.flow.Flow diff --git a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/StartServer.kt b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/StartServer.kt index f5d8fc35add..8ad61980db2 100644 --- a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/StartServer.kt +++ b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/StartServer.kt @@ -1,7 +1,7 @@ package dev.inmo.micro_utils.ktor.server import dev.inmo.micro_utils.ktor.server.configurators.KtorApplicationConfigurator -import io.ktor.server.application.Application +import io.ktor.server.application.* import io.ktor.server.cio.CIO import io.ktor.server.cio.CIOApplicationEngine import io.ktor.server.engine.* @@ -11,20 +11,22 @@ fun , host: String = "localhost", port: Int = Random.nextInt(1024, 65535), - additionalEngineEnvironmentConfigurator: ApplicationEnvironmentBuilder.() -> Unit = {}, + additionalEngineEnvironmentConfigurator: EngineConnectorBuilder.() -> Unit = {}, additionalConfigurationConfigurator: TConfiguration.() -> Unit = {}, + environment: ApplicationEnvironment = applicationEnvironment(), block: Application.() -> Unit -): TEngine = embeddedServer( +): EmbeddedServer = embeddedServer( engine, - applicationEnvironment { - module(block) + environment, + { connector { this.host = host this.port = port + additionalEngineEnvironmentConfigurator() } - additionalEngineEnvironmentConfigurator() + additionalConfigurationConfigurator() }, - additionalConfigurationConfigurator + module = block ) /** @@ -35,15 +37,17 @@ fun Unit = {}, + additionalEngineEnvironmentConfigurator: EngineConnectorBuilder.() -> Unit = {}, additionalConfigurationConfigurator: CIOApplicationEngine.Configuration.() -> Unit = {}, + environment: ApplicationEnvironment = applicationEnvironment(), block: Application.() -> Unit -): CIOApplicationEngine = createKtorServer( +): EmbeddedServer = createKtorServer( CIO, host, port, additionalEngineEnvironmentConfigurator, additionalConfigurationConfigurator, + environment, block ) @@ -51,15 +55,17 @@ fun , host: String = "localhost", port: Int = Random.nextInt(1024, 65535), - additionalEngineEnvironmentConfigurator: ApplicationEnvironmentBuilder.() -> Unit = {}, + additionalEngineEnvironmentConfigurator: EngineConnectorBuilder.() -> Unit = {}, additionalConfigurationConfigurator: TConfiguration.() -> Unit = {}, + environment: ApplicationEnvironment = applicationEnvironment(), configurators: List -): TEngine = createKtorServer( +): EmbeddedServer = createKtorServer( engine, host, port, additionalEngineEnvironmentConfigurator, - additionalConfigurationConfigurator + additionalConfigurationConfigurator, + environment, ) { configurators.forEach { it.apply { configure() } } } @@ -73,6 +79,7 @@ fun createKtorServer( host: String = "localhost", port: Int = Random.nextInt(1024, 65535), configurators: List, - additionalEngineEnvironmentConfigurator: ApplicationEnvironmentBuilder.() -> Unit = {}, + additionalEngineEnvironmentConfigurator: EngineConnectorBuilder.() -> Unit = {}, additionalConfigurationConfigurator: CIOApplicationEngine.Configuration.() -> Unit = {}, -): ApplicationEngine = createKtorServer(CIO, host, port, additionalEngineEnvironmentConfigurator, additionalConfigurationConfigurator, configurators) + environment: ApplicationEnvironment = applicationEnvironment(), +): EmbeddedServer = createKtorServer(CIO, host, port, additionalEngineEnvironmentConfigurator, additionalConfigurationConfigurator, environment, configurators) diff --git a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/TemporalFilesRoutingConfigurator.kt b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/TemporalFilesRoutingConfigurator.kt index 2c5489e3545..dd3e4048d3d 100644 --- a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/TemporalFilesRoutingConfigurator.kt +++ b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/TemporalFilesRoutingConfigurator.kt @@ -17,6 +17,7 @@ import io.ktor.server.response.respondText import io.ktor.server.routing.Routing import io.ktor.server.routing.post import kotlinx.coroutines.* +import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock @@ -26,7 +27,10 @@ import java.nio.file.attribute.FileTime class TemporalFilesRoutingConfigurator( private val subpath: String = DefaultTemporalFilesSubPath, - private val temporalFilesUtilizer: TemporalFilesUtilizer = TemporalFilesUtilizer + private val temporalFilesUtilizer: TemporalFilesUtilizer = TemporalFilesUtilizer, + filesFlowReplay: Int = 0, + filesFlowExtraBufferCapacity: Int = Int.MAX_VALUE, + filesFlowOnBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND ) : ApplicationRoutingConfigurator.Element { interface TemporalFilesUtilizer { fun start(filesMap: MutableMap, filesMutex: Mutex, onNewFileFlow: Flow): Job @@ -74,7 +78,11 @@ class TemporalFilesRoutingConfigurator( private val temporalFilesMap = mutableMapOf() private val temporalFilesMutex = Mutex() - private val filesFlow = MutableSharedFlow() + private val filesFlow = MutableSharedFlow( + replay = filesFlowReplay, + extraBufferCapacity = filesFlowExtraBufferCapacity, + onBufferOverflow = filesFlowOnBufferOverflow + ) val utilizerJob = temporalFilesUtilizer.start(temporalFilesMap, temporalFilesMutex, filesFlow.asSharedFlow()) override fun Routing.invoke() { @@ -111,7 +119,7 @@ class TemporalFilesRoutingConfigurator( temporalFilesMap[fileId] = file } call.respondText(fileId.string) - launchSafelyWithoutExceptions { filesFlow.emit(fileId) } + filesFlow.emit(fileId) } ?: call.respond(HttpStatusCode.BadRequest) } } diff --git a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/UniloadMultipart.kt b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/UniloadMultipart.kt index 7898092e54d..0bf7828a49b 100644 --- a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/UniloadMultipart.kt +++ b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/UniloadMultipart.kt @@ -6,6 +6,7 @@ import dev.inmo.micro_utils.ktor.common.downloadToTempFile import io.ktor.http.content.* import io.ktor.server.application.ApplicationCall import io.ktor.server.request.receiveMultipart +import io.ktor.utils.io.* import io.ktor.utils.io.core.* import kotlinx.coroutines.currentCoroutineContext import kotlinx.coroutines.isActive @@ -47,7 +48,7 @@ suspend fun ApplicationCall.uniloadMultipart( onBinaryChannelItem ) { when (it.name) { - "bytes" -> resultInput = it.provider() + "bytes" -> resultInput = it.provider().readBuffer() else -> onCustomFileItem(it) } } diff --git a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/configurators/ApplicationRoutingConfigurator.kt b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/configurators/ApplicationRoutingConfigurator.kt index a583c9fca88..a9d896e23d0 100644 --- a/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/configurators/ApplicationRoutingConfigurator.kt +++ b/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/ktor/server/configurators/ApplicationRoutingConfigurator.kt @@ -2,8 +2,7 @@ package dev.inmo.micro_utils.ktor.server.configurators import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator.Element import io.ktor.server.application.* -import io.ktor.server.routing.Routing -import io.ktor.server.routing.Routing +import io.ktor.server.routing.* import kotlinx.serialization.Contextual import kotlinx.serialization.Serializable @@ -19,9 +18,7 @@ class ApplicationRoutingConfigurator( } override fun Application.configure() { - pluginOrNull(Routing) ?.apply { - rootInstaller.apply { invoke() } - } ?: install(Routing) { + routing { rootInstaller.apply { invoke() } } } diff --git a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key/value/KtorWriteKeyValueRepoClient.kt b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key/value/KtorWriteKeyValueRepoClient.kt index 12de3b5538a..04548c751ba 100644 --- a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key/value/KtorWriteKeyValueRepoClient.kt +++ b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key/value/KtorWriteKeyValueRepoClient.kt @@ -8,7 +8,7 @@ import dev.inmo.micro_utils.repos.ktor.common.key_value.* import io.ktor.client.HttpClient import io.ktor.client.request.post import io.ktor.http.* -import io.ktor.util.InternalAPI +import io.ktor.utils.io.InternalAPI import io.ktor.util.reflect.TypeInfo import io.ktor.util.reflect.typeInfo import kotlinx.coroutines.flow.Flow diff --git a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key/values/KtorWriteKeyValuesRepoClient.kt b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key/values/KtorWriteKeyValuesRepoClient.kt index 5fe28f0a7af..50225e60d9d 100644 --- a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key/values/KtorWriteKeyValuesRepoClient.kt +++ b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key/values/KtorWriteKeyValuesRepoClient.kt @@ -8,7 +8,7 @@ import dev.inmo.micro_utils.repos.ktor.common.one_to_many.* import io.ktor.client.HttpClient import io.ktor.client.request.post import io.ktor.http.* -import io.ktor.util.InternalAPI +import io.ktor.utils.io.InternalAPI import io.ktor.util.reflect.TypeInfo import io.ktor.util.reflect.typeInfo import kotlinx.coroutines.flow.Flow diff --git a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key/value/KtorReadKeyValueRepoRoutes.kt b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key/value/KtorReadKeyValueRepoRoutes.kt index ffab7f81624..f3e0104806a 100644 --- a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key/value/KtorReadKeyValueRepoRoutes.kt +++ b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key/value/KtorReadKeyValueRepoRoutes.kt @@ -16,7 +16,7 @@ import io.ktor.server.application.call import io.ktor.server.response.respond import io.ktor.server.routing.Routing import io.ktor.server.routing.get -import io.ktor.util.InternalAPI +import io.ktor.utils.io.InternalAPI import io.ktor.util.reflect.typeInfo import kotlinx.serialization.* diff --git a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key/values/KtorReadKeyValuesRepoRoutes.kt b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key/values/KtorReadKeyValuesRepoRoutes.kt index 7921f24d817..82df24d1c53 100644 --- a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key/values/KtorReadKeyValuesRepoRoutes.kt +++ b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key/values/KtorReadKeyValuesRepoRoutes.kt @@ -14,7 +14,7 @@ import io.ktor.server.application.call import io.ktor.server.response.respond import io.ktor.server.routing.Routing import io.ktor.server.routing.get -import io.ktor.util.InternalAPI +import io.ktor.utils.io.InternalAPI import io.ktor.util.reflect.typeInfo import kotlinx.serialization.*