Skip to content

Commit

Permalink
KTOR-7904 Fix Servlet response body is corrupted due to the wrong off…
Browse files Browse the repository at this point in the history
…set (#4527)
  • Loading branch information
e5l authored Dec 3, 2024
1 parent bca1cc2 commit c927f5b
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private class ServletWriter(val output: ServletOutputStream) : WriteListener {
}

awaitReady()
output.write(buffer, 0, rc)
output.write(buffer, start, rc)
awaitReady()
rc
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

package io.ktor.tests.servlet.jakarta

import io.ktor.server.servlet.*
import io.ktor.server.servlet.jakarta.servletWriter
import io.ktor.utils.io.*
import io.ktor.utils.io.core.*
import jakarta.servlet.ServletOutputStream
import jakarta.servlet.WriteListener
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.runBlocking
import kotlinx.io.readByteArray
import kotlin.test.Test
import kotlin.test.assertEquals

class ServletWriterJakartaTest {

@Test
fun testWriteBufferWithPositivePosition() = runBlocking {
val content = withServletWriter {
val buffer = ByteReadPacket("1234567890".toByteArray())
buffer.readByte()

writeBuffer(buffer)
flushAndClose()
}

assertEquals("234567890", content.decodeToString())
}

suspend fun withServletWriter(block: suspend ByteWriteChannel.() -> Unit): ByteArray {
val content = BytePacketBuilder()
val output = object : ServletOutputStream() {
override fun isReady(): Boolean = true
override fun setWriteListener(writeListener: WriteListener) {
writeListener.onWritePossible()
}

override fun write(b: Int) {
content.writeByte((b and 0xff).toByte())
}
}

coroutineScope {
val channel = servletWriter(output).channel
block(channel)
channel.flushAndClose()
}

return content.build().readByteArray()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private class ServletWriter(val output: ServletOutputStream) : WriteListener {
}

awaitReady()
output.write(buffer, 0, rc)
output.write(buffer, start, rc)
awaitReady()
rc
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

package io.ktor.tests.servlet

import io.ktor.server.servlet.*
import io.ktor.utils.io.*
import io.ktor.utils.io.core.*
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.runBlocking
import kotlinx.io.readByteArray
import javax.servlet.ServletOutputStream
import javax.servlet.WriteListener
import kotlin.test.Test
import kotlin.test.assertEquals

class ServletWriterTest {

@Test
fun testWriteBufferWithPositivePosition() = runBlocking {
val content = withServletWriter {
val buffer = ByteReadPacket("1234567890".toByteArray())
buffer.readByte()

writeBuffer(buffer)
flushAndClose()
}

assertEquals("234567890", content.decodeToString())
}

suspend fun withServletWriter(block: suspend ByteWriteChannel.() -> Unit): ByteArray {
val content = BytePacketBuilder()
val output = object : ServletOutputStream() {
override fun isReady(): Boolean = true

override fun setWriteListener(writeListener: WriteListener) {
writeListener.onWritePossible()
}

override fun write(b: Int) {
content.writeByte((b and 0xff).toByte())
}
}

coroutineScope {
val channel = servletWriter(output).channel
block(channel)
channel.flushAndClose()
}

return content.build().readByteArray()
}
}
1 change: 1 addition & 0 deletions ktor-server/ktor-server-tests/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ kotlin.sourceSets {
jvmTest {
dependencies {
implementation(libs.jansi)
implementation(project(":ktor-client:ktor-client-plugins:ktor-client-encoding"))
api(project(":ktor-server:ktor-server-core", configuration = "testOutput"))
api(libs.logback.classic)
api(project(":ktor-server:ktor-server-plugins:ktor-server-sse"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,16 @@ import io.ktor.server.testing.*
import io.ktor.util.*
import io.ktor.utils.io.*
import io.ktor.utils.io.jvm.javaio.*
import kotlinx.coroutines.*
import kotlinx.io.*
import java.time.*
import java.util.zip.*
import kotlin.coroutines.*
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.io.readByteArray
import java.time.ZoneId
import java.time.ZonedDateTime
import java.util.zip.GZIPInputStream
import java.util.zip.Inflater
import java.util.zip.InflaterInputStream
import kotlin.coroutines.CoroutineContext
import kotlin.test.*

class CompressionTest {
Expand Down

0 comments on commit c927f5b

Please sign in to comment.