refactor of Ktor calls

This commit is contained in:
InsanusMokrassar 2019-04-26 11:12:01 +08:00
parent 711410c426
commit c12d08eda8
5 changed files with 76 additions and 55 deletions

View File

@ -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

View File

@ -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

View File

@ -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<String, String> = mutableMapOf()
override suspend fun <T : Any> prepareCall(
client: HttpClient,
baseUrl: String,
request: Request<T>
): 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 <T : Any> prepareCallBody(
client: HttpClient,
baseUrl: String,
request: Request<T>
): Any?
}

View File

@ -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 <T: Any> prepareCall(
class MultipartRequestCallFactory : AbstractRequestCallFactory() {
override fun <T : Any> prepareCallBody(
client: HttpClient,
baseUrl: String,
request: Request<T>
): 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()
}
}
)
}
}

View File

@ -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 <T: Any> prepareCall(
class SimpleRequestCallFactory : AbstractRequestCallFactory() {
override fun <T : Any> prepareCallBody(
client: HttpClient,
baseUrl: String,
request: Request<T>
): HttpClientCall? = (request as? SimpleRequest<T>) ?.let {
castedRequest ->
client.call {
url("$baseUrl/${castedRequest.method()}")
method = HttpMethod.Post
accept(ContentType.Application.Json)
): Any? = (request as? SimpleRequest<T>) ?.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
)
}
}