Skip to content

Commit 7e4993d

Browse files
committed
#6949 Fix Netty streaming completion guard
Signed-off-by: Arnab Nandy <arnab_nandy7@yahoo.com>
1 parent fe65375 commit 7e4993d

3 files changed

Lines changed: 23 additions & 4 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "bugfix",
3+
"category": "Netty NIO Async HTTP Client",
4+
"contributor": "",
5+
"description": "Fix async streaming responses so channel-inactive errors are surfaced until the response has been finalized."
6+
}

http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/internal/ResponseHandler.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import static software.amazon.awssdk.http.nio.netty.internal.ChannelAttributeKey.RESPONSE_CONTENT_LENGTH;
2626
import static software.amazon.awssdk.http.nio.netty.internal.ChannelAttributeKey.RESPONSE_DATA_READ;
2727
import static software.amazon.awssdk.http.nio.netty.internal.ChannelAttributeKey.RESPONSE_STATUS_CODE;
28-
import static software.amazon.awssdk.http.nio.netty.internal.ChannelAttributeKey.STREAMING_COMPLETE_KEY;
2928
import static software.amazon.awssdk.http.nio.netty.internal.utils.ExceptionHandlingUtils.tryCatch;
3029
import static software.amazon.awssdk.http.nio.netty.internal.utils.ExceptionHandlingUtils.tryCatchFinally;
3130

@@ -462,10 +461,9 @@ public void cancel() {
462461
private void notifyIfResponseNotCompleted(ChannelHandlerContext handlerCtx) {
463462
RequestContext requestCtx = handlerCtx.channel().attr(REQUEST_CONTEXT_KEY).get();
464463
Boolean responseCompleted = handlerCtx.channel().attr(RESPONSE_COMPLETE_KEY).get();
465-
Boolean isStreamingComplete = handlerCtx.channel().attr(STREAMING_COMPLETE_KEY).get();
466464
handlerCtx.channel().attr(KEEP_ALIVE).set(false);
467465

468-
if (!Boolean.TRUE.equals(responseCompleted) && !Boolean.TRUE.equals(isStreamingComplete)) {
466+
if (!Boolean.TRUE.equals(responseCompleted)) {
469467
IOException err = new IOException(NettyUtils.closedChannelMessage(handlerCtx.channel()));
470468
runAndLogError(handlerCtx.channel(), () -> "Fail to execute SdkAsyncHttpResponseHandler#onError",
471469
() -> requestCtx.handler().onError(err));
@@ -514,4 +512,4 @@ public void onComplete() {
514512
});
515513
}
516514
}
517-
}
515+
}

http-clients/netty-nio-client/src/test/java/software/amazon/awssdk/http/nio/netty/internal/PublisherAdapterTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import static software.amazon.awssdk.http.nio.netty.internal.ChannelAttributeKey.EXECUTE_FUTURE_KEY;
2626
import static software.amazon.awssdk.http.nio.netty.internal.ChannelAttributeKey.PROTOCOL_FUTURE;
2727
import static software.amazon.awssdk.http.nio.netty.internal.ChannelAttributeKey.REQUEST_CONTEXT_KEY;
28+
import static software.amazon.awssdk.http.nio.netty.internal.ChannelAttributeKey.STREAMING_COMPLETE_KEY;
2829

2930
import io.netty.buffer.ByteBufAllocator;
3031
import io.netty.buffer.EmptyByteBuf;
@@ -315,6 +316,20 @@ public void onComplete() {
315316
verify(channelPool).release(channel);
316317
}
317318

319+
@Test
320+
public void channelInactive_streamingCompleteButResponseNotComplete_shouldInvokeResponseHandler() {
321+
channel.attr(STREAMING_COMPLETE_KEY).set(true);
322+
323+
nettyResponseHandler.channelInactive(ctx);
324+
325+
ArgumentCaptor<Throwable> errorCaptor = ArgumentCaptor.forClass(Throwable.class);
326+
verify(responseHandler).onError(errorCaptor.capture());
327+
assertThat(errorCaptor.getValue()).isInstanceOf(IOException.class);
328+
assertThat(executeFuture).isCompletedExceptionally();
329+
verify(ctx).close();
330+
verify(channelPool).release(channel);
331+
}
332+
318333
static final class TestSubscriber implements Subscriber<ByteBuffer> {
319334

320335
private Subscription subscription;

0 commit comments

Comments
 (0)