ktorio / ktor

Framework for quickly creating connected applications in Kotlin with minimal effort
https://ktor.io
Apache License 2.0
12.84k stars 1.04k forks source link

Problem in post method that receive<T>() or receiveText() #842

Open yumeTsukiiii opened 5 years ago

yumeTsukiiii commented 5 years ago

Ktor Version

1.0.0

Ktor Engine Used(client or server and name)

netty

JVM Version, Operating System and Relevant Context

jdk 11

Feedback

When I use the post method to send a long piece of json data to the server, the receiveText method can only receive the previous part of the data. Usually the post method should not limit the transfer word length. How can I solve this problem?

cy6erGn0m commented 5 years ago

Sorry, I don't get what exactly happens

the receiveText method can only receive the previous part of the data

Could you please clarify what "previous part" means? receiveText should receive the whole text content and could be only called once per call

yumeTsukiiii commented 5 years ago

Sorry, I don't get what exactly happens

the receiveText method can only receive the previous part of the data

Could you please clarify what "previous part" means? receiveText should receive the whole text content and could be only called once per call

Thanks for your answer! At First I used vertx for request forwarding.For example, the request is { "token": "long text" }, but when I use function "receiveText()" after vertx's request forward, I can just get "{ "token": "lon ".

Recently, I find maybe I mistakenly use vertx's request. When I use pure ktor, this problem will not happen.

Before "receiveText()", there are some code:

private suspend fun dispatch(call: ApplicationCall, newPath: String, client: io.vertx.core.http.HttpClient){
    val deferred = CompletableDeferred<Pair<HttpStatusCode, String>>()
    val c = client.request(HttpMethod.valueOf(call.request.httpMethod.value), newPath){
        it.bodyHandler { buffer ->
            deferred.complete(Pair(HttpStatusCode.fromValue(it.statusCode()), buffer.toString()))
        }
        it.exceptionHandler {
            deferred.completeExceptionally(it)
        }
    }

    val headers = call.request.headers
    headers.names().forEach {
        c.putHeader(it, headers[it])
    }
    c.end(call.receiveText())

    val result = deferred.await()
    call.respond(result.first, result.second)
    ServiceDiscovery.releaseServiceObject(discovery, client)
}

This problem occurs in the following code:

        post("/createActivity") {
            val text = call.receiveText() //can only get part of request data
//            call.receiveOrNull<CreateActivityReq>()?.run {
//                copy(openid = openid.decrypt())
//            }?.apply {
//                service.addActivity(openid, topic, limit).await()
//                call.respond(BaseResponse(0, "create success", ""))
//            }?:call.respond(HttpStatusCode.BadRequest)
        }
cy6erGn0m commented 5 years ago

Well, I'd introduce several printlns to see what is going on. At least I'd try to see what buffer size in the bodyHandler and what call.receiveText() return before sending it to c.end(String) function to isolate the problem

yumeTsukiiii commented 5 years ago

Well, I'd introduce several printlns to see what is going on. At least I'd try to see what buffer size in the bodyHandler and what call.receiveText() return before sending it to c.end(String) function to isolate the problem

Ok, thank you very much.

oleg-larshin commented 4 years ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.