MockWebServer can send extra HTTP/2 stream resets before consuming queued responses
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- kotlin
- Domain
- networking
Research direction
Start by reading Http2SocketHandler.onStream() and dispatchBookkeepingRequest() in MockWebServer.kt, then run HttpOverHttp2Test.recoverFromMultipleRefusedStreamsRequiresNewConnection. Trace when dispatcher.dispatch(request) consumes each queued response relative to sending REFUSED_STREAM. Done means the two scripted refusals are consumed once and the retry receives "abc"; the report says the debugger was needed to reproduce the failure.
Written by the indexing model from the issue text.
Description
Related to #9816
I was investigating HttpOverHttp2Test.recoverFromMultipleRefusedStreamsRequiresNewConnection at 67c4f34e7. The test queues two responses that reset the stream with REFUSED_STREAM, followed by a successful response containing "abc".
In Http2SocketHandler.onStream(), MockWebServer reads dispatcher.peek() and applies onRequestStart before calling dispatchBookkeepingRequest(). For CloseStream, this sends the reset before dispatcher.dispatch(request) consumes the queued response.
Since stream handlers run concurrently, a client can receive the reset and retry while the previous handler has not yet consumed its response. The retry can then observe the same queued response.
I reproduced this with a debugger:
- Run
recoverFromMultipleRefusedStreamsRequiresNewConnection. - Set a breakpoint on
requestQueue.add(request)insidedispatchBookkeepingRequest()inMockWebServer.kt. - Set the breakpoint to suspend only the current thread.
- Leave the handler suspended so the client can retry.
The client received two refusals on the original connection, opened another connection, and received a third refusal there. The call then failed with StreamResetException: REFUSED_STREAM, even though only two refusals were queued.
I would expect each scripted refusal to be consumed once, with the third attempt receiving "abc".
The breakpoint deliberately forces a delay between sending the reset and consuming the response. I haven’t reproduced this exact failure without the debugger or established whether it explains the Windows CI failure that prompted the investigation.
Environment: Arch Linux x86_64, Java 21, Gradle 9.8.2.
- Dominant language
- Kotlin
- Stars
- 47.1k
- Forks
- 9.3k
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 29
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from lysine-dev/okhttp
-
OkHttp versions 5.4.0+ no longer include baseline-prof.txtPossibly taken A pull request linked to this issue is open or already merged. Openbug
Difficulty 1/5 Under an hour Newbie friendliness 83/100
lysine-dev/okhttp#9828 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
lysine-dev/okhttp#9817 ·
Maintainers usually reply within 1 day
-
Cannot add Content-Length header to a multipart partPossibly taken @Amir-Golmoradi claimed this 11 days ago. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
lysine-dev/okhttp#9814 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
lysine-dev/okhttp#9761 · 3 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 30/100
lysine-dev/okhttp#9838 ·
Maintainers usually reply within 1 day
All issues in lysine-dev/okhttp
Similar issues
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 3 days
-
afk-ok area:ci size:S
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
enorm-labs/event-junkie#4518 ·
Maintainers usually reply within 1 day
-
android:player
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
[Docs] Replace hardcoded Axelix versions in docs with the version placeholderPossibly taken @sergeycherkasovv claimed this today. Opendocs
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
axelixlabs/axelix#1934 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day