Skip to content

Commit

Permalink
Ensure responseWritten is called on discard (#10288)
Browse files Browse the repository at this point in the history
FullOutboundHandler needs to call responseWritten on discard, otherwise RoutingInboundHandler won't clean up request body. This can happen if the channel is closed while it's not writable, so there's a response backlog.
  • Loading branch information
yawkat committed Dec 19, 2023
1 parent 67e2b3d commit 97aeb96
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,8 @@ void writeSome() {

@Override
void discard() {
// pretend we wrote to clean up resources
requestHandler.responseWritten(outboundAccess.attachment);
message.release();
outboundHandler = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,45 @@ class PipeliningServerHandlerSpec extends Specification {
ch.readOutbound() == null
}

def 'responseWritten always called'() {
given:
int unwritten = 0
def ch = new EmbeddedChannel(new PipeliningServerHandler(new RequestHandler() {
@Override
void accept(ChannelHandlerContext ctx, HttpRequest request, PipeliningServerHandler.OutboundAccess outboundAccess) {
unwritten++
request.release()
outboundAccess.writeFull(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NO_CONTENT))
}

@Override
void responseWritten(Object attachment) {
unwritten--
}

@Override
void handleUnboundError(Throwable cause) {
cause.printStackTrace()
}
}))

when:
// note: this relies on channelReadComplete never being called, which is a bit unrealistic. channelReadComplete
// causes a flush, which for EmbeddedChannel, clears the outbound buffer and thus clears the backlog.
while (true) {
boolean writableBefore = ch.writable
ch.writeOneInbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"))
ch.checkException()
ch.runPendingTasks()
if (!writableBefore) {
break
}
}
ch.finishAndReleaseAll()
then:
unwritten == 0
}

static class MonitorHandler extends ChannelOutboundHandlerAdapter {
int flush = 0
int read = 0
Expand Down

0 comments on commit 97aeb96

Please sign in to comment.