You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2020/11/05 21:06:41 UTC

[httpcomponents-core] 05/06: Make `ReactiveDataConsumer#failed` a no-op if it has already been marked as complete (#227)

This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch 5.0.x
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git

commit 91367a9df023d6eb3f67f53889551378c524ff1e
Author: cweld510 <54...@users.noreply.github.com>
AuthorDate: Thu Oct 29 01:00:35 2020 -0700

    Make `ReactiveDataConsumer#failed` a no-op if it has already been marked as complete (#227)
    
    Co-authored-by: ColinWeld <c_...@backblaze.com>
---
 .../hc/core5/reactive/ReactiveDataConsumer.java      |  6 ++++--
 .../hc/core5/reactive/TestReactiveDataConsumer.java  | 20 ++++++++++++++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/httpcore5-reactive/src/main/java/org/apache/hc/core5/reactive/ReactiveDataConsumer.java b/httpcore5-reactive/src/main/java/org/apache/hc/core5/reactive/ReactiveDataConsumer.java
index 6db7d80..1818c69 100644
--- a/httpcore5-reactive/src/main/java/org/apache/hc/core5/reactive/ReactiveDataConsumer.java
+++ b/httpcore5-reactive/src/main/java/org/apache/hc/core5/reactive/ReactiveDataConsumer.java
@@ -67,8 +67,10 @@ final class ReactiveDataConsumer implements AsyncDataConsumer, Publisher<ByteBuf
     private volatile Subscriber<? super ByteBuffer> subscriber;
 
     public void failed(final Exception cause) {
-        exception = cause;
-        flushToSubscriber();
+        if (!completed) {
+            exception = cause;
+            flushToSubscriber();
+        }
     }
 
     @Override
diff --git a/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/TestReactiveDataConsumer.java b/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/TestReactiveDataConsumer.java
index 2473061..47fff1d 100644
--- a/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/TestReactiveDataConsumer.java
+++ b/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/TestReactiveDataConsumer.java
@@ -206,4 +206,24 @@ public class TestReactiveDataConsumer {
             .blockingGet();
         Assert.assertSame(ex, result.getError());
     }
+
+    @Test
+    public void testFailAfterCompletion() {
+        // Calling consumer.failed() after consumer.streamEnd() must be a no-op.
+        // The exception must be discarded, and the subscriber must see that
+        // the stream was successfully completed.
+        final ReactiveDataConsumer consumer = new ReactiveDataConsumer();
+
+        consumer.streamEnd(null);
+
+        final RuntimeException ex = new RuntimeException();
+        consumer.failed(ex);
+
+        final Notification<ByteBuffer> result = Flowable.fromPublisher(consumer)
+                .materialize()
+                .singleOrError()
+                .blockingGet();
+        Assert.assertFalse(result.isOnError());
+        Assert.assertTrue(result.isOnComplete());
+    }
 }