Environment
- MacOS
- JDK 11
- okhttp-4.9.0
The environment I'm working on is quite sensitive with the network bandwidth.
Sometimes, I don't need to read all the response body. A part of the response body could be enough to decide a result.
I want to close the response(=response body) without reading the body.
What do I want to do is like below
try (Response response = client.newCall(request).execute()) {
assertThat(response.code(), is(200))
// do nothing with the response body
}
But, when the connection is established with HTTP1, the ResponseBody::close
invokes Http1ExchangeCodec.FixedLengthSource::close
in the end.
Http1ExchangeCodec.FixedLengthSource::close
override fun close() {
if (closed) return
if (bytesRemaining != 0L &&
!discard(ExchangeCodec.DISCARD_STREAM_TIMEOUT_MILLIS, MILLISECONDS)) {
connection.noNewExchanges() // Unread bytes remain on the stream.
responseBodyComplete()
}
closed = true
}
Then, the discard
method reads all the response body source as below.
Util.kt
fun Source.discard(timeout: Int, timeUnit: TimeUnit): Boolean = try {
this.skipAll(timeout, timeUnit)
} catch (_: IOException) {
false
}
@Throws(IOException::class)
fun Source.skipAll(duration: Int, timeUnit: TimeUnit): Boolean {
val nowNs = System.nanoTime()
val originalDurationNs = if (timeout().hasDeadline()) {
timeout().deadlineNanoTime() - nowNs
} else {
Long.MAX_VALUE
}
timeout().deadlineNanoTime(nowNs + minOf(originalDurationNs, timeUnit.toNanos(duration.toLong())))
return try {
val skipBuffer = Buffer()
while (read(skipBuffer, 8192) != -1L) {
skipBuffer.clear()
}
true // Success! The source has been exhausted.
} catch (_: InterruptedIOException) {
false // We ran out of time before exhausting the source.
} finally {
if (originalDurationNs == Long.MAX_VALUE) {
timeout().clearDeadline()
} else {
timeout().deadlineNanoTime(nowNs + originalDurationNs)
}
}
}
It reads all the body and clears buffer. In my case, it's a waste of the CPU time and the network bandwidth.
Is there any way to just close it literally?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…