Skip to content

Commit

Permalink
Fixed serialization of empty body (#1952)
Browse files Browse the repository at this point in the history
* Fixed serialization of empty body

* Moved EmptyContent serialization logic to JsonFeature

* Check Content-Type header in unit tests

* Handle Unit explicitly
  • Loading branch information
wkornewald authored Jun 18, 2020
1 parent 7e5642a commit 0aea426
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package io.ktor.client.features.json

import io.ktor.client.*
import io.ktor.client.features.*
import io.ktor.client.features.json.JsonFeature.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.client.utils.*
Expand Down Expand Up @@ -109,7 +110,8 @@ class JsonFeature internal constructor(val config: Config) {
context.headers.remove(HttpHeaders.ContentType)

val serializedContent = when (payload) {
is EmptyContent -> config.serializer.write(Unit, contentType)
Unit -> EmptyContent
is EmptyContent -> EmptyContent
else -> config.serializer.write(payload, contentType)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,15 @@ class KotlinxSerializerTest : ClientLoader() {
val response = client.post<String>("$TEST_SERVER/echo-with-content-type") {
body = "Hello"
}

assertEquals("Hello", response)

val textResponse = client.post<String>("$TEST_SERVER/echo") {
body = "Hello"
}

assertEquals("\"Hello\"", textResponse)

val emptyResponse = client.post<String>("$TEST_SERVER/echo")
assertEquals("", emptyResponse)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import io.ktor.utils.io.core.*
* [JsonSerializer] using [Gson] as backend.
*/
class GsonSerializer(block: GsonBuilder.() -> Unit = {}) : JsonSerializer {

private val backend: Gson = GsonBuilder().apply(block).create()

override fun write(data: Any, contentType: ContentType): OutgoingContent =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import io.ktor.http.content.*
import io.ktor.utils.io.core.*

class JacksonSerializer(jackson: ObjectMapper = jacksonObjectMapper(), block: ObjectMapper.() -> Unit = {}) : JsonSerializer {

private val backend = jackson.apply(block)

override fun write(data: Any, contentType: ContentType): OutgoingContent =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,22 @@
package io.ktor.client.features.json.tests

import io.ktor.application.*
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.engine.cio.*
import io.ktor.client.engine.mock.*
import io.ktor.client.features.*
import io.ktor.client.features.json.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.client.tests.utils.*
import io.ktor.client.utils.*
import io.ktor.features.*
import io.ktor.gson.*
import io.ktor.http.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.response.respond
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.jetty.*
Expand Down Expand Up @@ -69,22 +74,45 @@ abstract class JsonTest : TestWithKtor() {

protected fun TestClientBuilder<*>.configClient() {
config {
install(JsonFeature) {
serializerImpl?.let {
serializer = it
}
configJsonFeature()
}
}

private fun HttpClientConfig<*>.configJsonFeature(block: JsonFeature.Config.() -> Unit = {}) {
install(JsonFeature) {
serializerImpl?.let {
serializer = it
}
block()
}
}

private fun TestClientBuilder<*>.configCustomContentTypeClient(block: JsonFeature.Config.() -> Unit) {
config {
install(JsonFeature) {
serializerImpl?.let {
serializer = it
configJsonFeature(block)
}
}

@org.junit.Test
fun testEmptyBody() = testWithEngine(MockEngine) {
config {
engine {
addHandler { request ->
respond(request.body.toByteReadPacket().readText(), headers = buildHeaders {
append("X-ContentType", request.body.contentType.toString())
})
}
}
block()
}
defaultRequest {
contentType(ContentType.Application.Json)
}
configJsonFeature()
}

test { client ->
val response: HttpResponse = client.get("https://test.com")
assertEquals("", response.readText())
assertEquals("null", response.headers["X-ContentType"])
}
}

Expand Down

0 comments on commit 0aea426

Please sign in to comment.