Skip to content

Commit

Permalink
Merge branch 'main' into whyoleg/curl-ws
Browse files Browse the repository at this point in the history
  • Loading branch information
e5l authored Feb 7, 2025
2 parents ef6380a + d845e36 commit f2a9b03
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1

FROM eclipse-temurin:21.0.5_11-jdk-noble AS dev
FROM eclipse-temurin:21.0.6_7-jdk-noble AS dev

ARG USERNAME=developer
ARG USER_UID=1001
Expand Down
19 changes: 8 additions & 11 deletions ktor-io/jvm/src/io/ktor/utils/io/ByteReadChannelOperations.jvm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,8 @@ public suspend fun ByteReadChannel.copyTo(channel: WritableByteChannel, limit: L
}
}

while (copied < limit) {
while (copied < limit && !isClosedForRead) {
read(min = 0, consumer = copy)
if (isClosedForRead) break
}

closedCause?.let { throw it }
Expand Down Expand Up @@ -184,19 +183,17 @@ public fun ByteReadChannel.readAvailable(block: (ByteBuffer) -> Int): Int {
*
* @param min amount of bytes available for read, should be positive or zero
* @param consumer to be invoked when at least [min] bytes available for read
* @throws EOFException when there are less than [min] bytes available after the channel is closed
*/
@OptIn(InternalAPI::class)
public suspend inline fun ByteReadChannel.read(min: Int = 1, noinline consumer: (ByteBuffer) -> Unit) {
require(min >= 0) { "min should be positive or zero" }
if (availableForRead > 0 && availableForRead >= min) {
if (min > 0) {
if (!awaitContent(min)) {
throw EOFException("Not enough bytes available: required $min but $availableForRead available")
}
readBuffer.read(consumer)
} else if (awaitContent()) {
readBuffer.read(consumer)
return
}

awaitContent()
if (isClosedForRead && min > 0) {
throw EOFException("Not enough bytes available: required $min but $availableForRead available")
}

if (availableForRead > 0) readBuffer.read(consumer)
}
16 changes: 16 additions & 0 deletions ktor-io/jvm/test/ByteReadChannelOperationsJvmTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

import io.ktor.utils.io.*
import kotlinx.coroutines.*
import kotlinx.coroutines.test.runTest
import kotlinx.io.EOFException
import org.junit.jupiter.api.assertThrows
import kotlin.test.*
import kotlin.test.Test
import kotlin.time.Duration.Companion.seconds
import kotlin.time.measureTime

Expand Down Expand Up @@ -100,4 +104,16 @@ class ByteReadChannelOperationsJvmTest {
assertTrue(time < 5.seconds, "Expected I/O to be complete in a reasonable time, but it took $time")
assertEquals(2_088_890, out.length)
}

@Test
fun readWithGreaterMinThrows() = runTest {
val channel = ByteChannel()
channel.writeByte(1)
channel.close()
assertThrows<EOFException> {
channel.read(2) {
fail("There is only one byte in the channel")
}
}
}
}

0 comments on commit f2a9b03

Please sign in to comment.