diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c80766de6..5206e921af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ some default library * All proxy help methods was removed . They are will be replaced in separated project * `Ktor` version `1.1.3` -> `1.1.4` * Requests results now always decoding as `UTF-8` +* `AbstractRequestCallFactory` was added with cache of methods urls to avoid memory leaks +* Small refactoring of work with response in `KtorRequestsExecutor` ## 0.13.0 Telegram Polls diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/KtorRequestsExecutor.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/KtorRequestsExecutor.kt index 42827316ae..cc4e3a2643 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/KtorRequestsExecutor.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/KtorRequestsExecutor.kt @@ -60,7 +60,9 @@ class KtorRequestsExecutor( if (call == null) { throw IllegalArgumentException("Can't execute request: $request") } - val content = call.response.content.toByteArray().toString(Charsets.UTF_8) + val content = call.response.use { + it.content.toByteArray().toString(Charsets.UTF_8) + } val responseObject = jsonFormatter.parse( Response.serializer(request.resultSerializer()), content diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/AbstractRequestCallFactory.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/AbstractRequestCallFactory.kt new file mode 100644 index 0000000000..5076d173d2 --- /dev/null +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/AbstractRequestCallFactory.kt @@ -0,0 +1,41 @@ +package com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.base + +import com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.KtorCallFactory +import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request +import io.ktor.client.HttpClient +import io.ktor.client.call.HttpClientCall +import io.ktor.client.call.call +import io.ktor.client.request.accept +import io.ktor.client.request.url +import io.ktor.http.ContentType +import io.ktor.http.HttpMethod + +abstract class AbstractRequestCallFactory : KtorCallFactory { + private val methodsCache: MutableMap = mutableMapOf() + override suspend fun prepareCall( + client: HttpClient, + baseUrl: String, + request: Request + ): HttpClientCall? { + val preparedBody = prepareCallBody(client, baseUrl, request) ?: return null + + return client.call { + url( + methodsCache[request.method()] ?: "$baseUrl/${request.method()}".also { + methodsCache[request.method()] = it + } + ) + method = HttpMethod.Post + accept(ContentType.Application.Json) + + body = preparedBody + build() + } + } + + protected abstract fun prepareCallBody( + client: HttpClient, + baseUrl: String, + request: Request + ): Any? +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/MultipartRequestCallFactory.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/MultipartRequestCallFactory.kt index e7c16717e7..2f2e1015f0 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/MultipartRequestCallFactory.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/MultipartRequestCallFactory.kt @@ -1,48 +1,37 @@ package com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.base -import com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.KtorCallFactory import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.* import com.github.insanusmokrassar.TelegramBotAPI.utils.mapWithCommonValues import io.ktor.client.HttpClient -import io.ktor.client.call.HttpClientCall -import io.ktor.client.call.call -import io.ktor.client.request.accept import io.ktor.client.request.forms.MultiPartFormDataContent import io.ktor.client.request.forms.formData -import io.ktor.client.request.url import io.ktor.http.* -class MultipartRequestCallFactory : KtorCallFactory { - override suspend fun prepareCall( +class MultipartRequestCallFactory : AbstractRequestCallFactory() { + + override fun prepareCallBody( client: HttpClient, baseUrl: String, request: Request - ): HttpClientCall? = (request as? MultipartRequest) ?.let { - castedRequest -> - client.call { - url("$baseUrl/${castedRequest.method()}") - method = HttpMethod.Post - accept(ContentType.Application.Json) - body = MultiPartFormDataContent( - formData { - val params = castedRequest.paramsJson.mapWithCommonValues() - for ((key, value) in castedRequest.mediaMap + params) { - when (value) { - is MultipartFile -> append( - key, - value.file.asInput(), - Headers.build { - append(HttpHeaders.ContentType, value.mimeType) - append(HttpHeaders.ContentDisposition, "filename=${value.fileId}") - } - ) - is FileId -> append(key, value.fileId) - else -> append(key, value.toString()) - } + ): Any? = (request as? MultipartRequest) ?.let { castedRequest -> + MultiPartFormDataContent( + formData { + val params = castedRequest.paramsJson.mapWithCommonValues() + for ((key, value) in castedRequest.mediaMap + params) { + when (value) { + is MultipartFile -> append( + key, + value.file.asInput(), + Headers.build { + append(HttpHeaders.ContentType, value.mimeType) + append(HttpHeaders.ContentDisposition, "filename=${value.fileId}") + } + ) + is FileId -> append(key, value.fileId) + else -> append(key, value.toString()) } } - ) - build() - } + } + ) } } \ No newline at end of file diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/SimpleRequestCallFactory.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/SimpleRequestCallFactory.kt index 3e91948a34..94a72f0f01 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/SimpleRequestCallFactory.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/SimpleRequestCallFactory.kt @@ -1,36 +1,23 @@ package com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.base -import com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.KtorCallFactory import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.* import com.github.insanusmokrassar.TelegramBotAPI.utils.toJsonWithoutNulls import io.ktor.client.HttpClient -import io.ktor.client.call.HttpClientCall -import io.ktor.client.call.call -import io.ktor.client.request.accept -import io.ktor.client.request.url import io.ktor.http.ContentType -import io.ktor.http.HttpMethod import io.ktor.http.content.TextContent -class SimpleRequestCallFactory : KtorCallFactory { - override suspend fun prepareCall( +class SimpleRequestCallFactory : AbstractRequestCallFactory() { + override fun prepareCallBody( client: HttpClient, baseUrl: String, request: Request - ): HttpClientCall? = (request as? SimpleRequest) ?.let { - castedRequest -> - client.call { - url("$baseUrl/${castedRequest.method()}") - method = HttpMethod.Post - accept(ContentType.Application.Json) + ): Any? = (request as? SimpleRequest) ?.let { _ -> + val content = request.toJsonWithoutNulls(SimpleRequestSerializer).toString() - val content = request.toJsonWithoutNulls(SimpleRequestSerializer).toString() - - body = TextContent( - content, - ContentType.Application.Json - ) - build() - } + TextContent( + content, + ContentType.Application.Json + ) } + } \ No newline at end of file