Skip to content

Commit 9b60ca8

Browse files
authored
Merge pull request #5434 from square/jwilson.0909.race
Don't leak incoming bytes when we race incoming data and close
2 parents 2cdbbda + 510475a commit 9b60ca8

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

okhttp/src/main/java/okhttp3/internal/http2/Http2Connection.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ class Http2Connection internal constructor(builder: Builder) : Closeable {
178178

179179
@Synchronized internal fun updateConnectionFlowControl(read: Long) {
180180
readBytesTotal += read
181-
val readBytesToAcknowledge = (readBytesTotal - readBytesAcknowledged)
181+
val readBytesToAcknowledge = readBytesTotal - readBytesAcknowledged
182182
if (readBytesToAcknowledge >= okHttpSettings.initialWindowSize / 2) {
183183
writeWindowUpdateLater(0, readBytesToAcknowledge)
184184
readBytesAcknowledged += readBytesToAcknowledge

okhttp/src/main/java/okhttp3/internal/http2/Http2Stream.kt

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ class Http2Stream internal constructor(
360360
readBytesDelivered = readBuffer.read(sink, minOf(byteCount, readBuffer.size))
361361
readBytesTotal += readBytesDelivered
362362

363-
val unacknowledgedBytesRead = (readBytesTotal - readBytesAcknowledged)
363+
val unacknowledgedBytesRead = readBytesTotal - readBytesAcknowledged
364364
if (errorExceptionToDeliver == null &&
365365
unacknowledgedBytesRead >= connection.okHttpSettings.initialWindowSize / 2) {
366366
// Flow control: notify the peer that we're ready for more data! Only send a
@@ -407,6 +407,10 @@ class Http2Stream internal constructor(
407407
connection.updateConnectionFlowControl(read)
408408
}
409409

410+
/**
411+
* Accept bytes on the connection's reader thread. This function avoids holding locks while it
412+
* performs blocking reads for the incoming bytes.
413+
*/
410414
@Throws(IOException::class)
411415
internal fun receive(source: BufferedSource, byteCount: Long) {
412416
var byteCount = byteCount
@@ -438,14 +442,25 @@ class Http2Stream internal constructor(
438442
if (read == -1L) throw EOFException()
439443
byteCount -= read
440444

441-
// Move the received data to the read buffer to the reader can read it.
445+
// Move the received data to the read buffer to the reader can read it. If this source has
446+
// been closed since this read began we must discard the incoming data and tell the
447+
// connection we've done so.
448+
var bytesDiscarded = 0L
442449
synchronized(this@Http2Stream) {
443-
val wasEmpty = readBuffer.size == 0L
444-
readBuffer.writeAll(receiveBuffer)
445-
if (wasEmpty) {
446-
this@Http2Stream.notifyAll()
450+
if (closed) {
451+
bytesDiscarded = receiveBuffer.size
452+
receiveBuffer.clear()
453+
} else {
454+
val wasEmpty = readBuffer.size == 0L
455+
readBuffer.writeAll(receiveBuffer)
456+
if (wasEmpty) {
457+
this@Http2Stream.notifyAll()
458+
}
447459
}
448460
}
461+
if (bytesDiscarded > 0L) {
462+
updateConnectionFlowControl(bytesDiscarded)
463+
}
449464
}
450465
}
451466

0 commit comments

Comments
 (0)