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 2026/09/20 20:06:40 UTC
(httpcomponents-core) branch master updated: Async data exchnage handlers to signal that the opposite endpoint requesed graceful outgoing data stream termination
This is an automated email from the ASF dual-hosted git repository.
ok2c pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git
The following commit(s) were added to refs/heads/master by this push:
new 53513fca9 Async data exchnage handlers to signal that the opposite endpoint requesed graceful outgoing data stream termination
53513fca9 is described below
commit 53513fca992633057ddb929305ba81b7d3a98a12
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Sun Sep 20 15:38:12 2026 +0200
Async data exchnage handlers to signal that the opposite endpoint requesed graceful outgoing data stream termination
---
.../apache/hc/core5/http2/impl/nio/ClientH2StreamHandler.java | 7 +++++++
.../hc/core5/http2/impl/nio/ClientPushH2StreamHandler.java | 4 ++++
.../main/java/org/apache/hc/core5/http2/impl/nio/H2Stream.java | 1 +
.../java/org/apache/hc/core5/http2/impl/nio/H2StreamHandler.java | 2 ++
.../org/apache/hc/core5/http2/impl/nio/NoopH2StreamHandler.java | 4 ++++
.../apache/hc/core5/http2/impl/nio/ServerH2StreamHandler.java | 7 +++++++
.../hc/core5/http2/impl/nio/ServerPushH2StreamHandler.java | 4 ++++
.../hc/core5/http2/impl/nio/TestAbstractH2StreamMultiplexer.java | 1 +
.../apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java | 1 +
.../org/apache/hc/core5/http/nio/AsyncDataExchangeHandler.java | 9 +++++++++
.../http/nio/support/BasicAsyncServerExpectationDecorator.java | 5 +++++
11 files changed, 45 insertions(+)
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2StreamHandler.java
index 7871dd4cb..6393e5991 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2StreamHandler.java
@@ -185,6 +185,13 @@ public void produceOutput() throws HttpException, IOException {
}
}
+ @Override
+ public void outputAborted() {
+ if (requestState.get() == MessageState.BODY) {
+ exchangeHandler.outputAborted();
+ }
+ }
+
@Override
public void consumePromise(final List<Header> headers) throws HttpException, IOException {
throw new ProtocolException("Unexpected message promise");
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushH2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushH2StreamHandler.java
index 3b32536ca..280be311f 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushH2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushH2StreamHandler.java
@@ -102,6 +102,10 @@ public boolean isOutputReady() {
public void produceOutput() throws HttpException, IOException {
}
+ @Override
+ public void outputAborted() {
+ }
+
@Override
public void consumePromise(final List<Header> headers) throws HttpException, IOException {
if (requestState == MessageState.HEADERS) {
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2Stream.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2Stream.java
index 7bd10613d..f946a3665 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2Stream.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2Stream.java
@@ -288,6 +288,7 @@ boolean abort() {
boolean abortGracefully() throws IOException {
if (!isLocalClosed() && isRemoteClosed()) {
channel.endStream();
+ handler.outputAborted();
releaseResources();
return true;
} else {
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2StreamHandler.java
index 488727df4..316d65930 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2StreamHandler.java
@@ -54,6 +54,8 @@ interface H2StreamHandler extends ResourceHolder {
void failed(Exception cause);
+ void outputAborted();
+
void handle(final HttpException ex, final boolean endStream) throws HttpException, IOException;
}
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/NoopH2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/NoopH2StreamHandler.java
index 5bbc3d47a..7bc975135 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/NoopH2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/NoopH2StreamHandler.java
@@ -48,6 +48,10 @@ public boolean isOutputReady() {
public void produceOutput() throws HttpException, IOException {
}
+ @Override
+ public void outputAborted() {
+ }
+
@Override
public void consumePromise(final List<Header> headers) throws HttpException, IOException {
}
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerH2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerH2StreamHandler.java
index a51aea1e6..3eefa0d27 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerH2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerH2StreamHandler.java
@@ -333,6 +333,13 @@ public void produceOutput() throws HttpException, IOException {
}
}
+ @Override
+ public void outputAborted() {
+ if (responseState.get() == MessageState.BODY) {
+ exchangeHandler.outputAborted();
+ }
+ }
+
@Override
public void handle(final HttpException ex, final boolean endStream) throws HttpException, IOException {
if (done.get()) {
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerPushH2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerPushH2StreamHandler.java
index 6e4fc9d89..37a5c29d0 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerPushH2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerPushH2StreamHandler.java
@@ -236,6 +236,10 @@ public void terminateExchange() {
}
}
+ @Override
+ public void outputAborted() {
+ }
+
@Override
public void handle(final HttpException ex, final boolean endStream) throws HttpException, IOException {
throw ex;
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/TestAbstractH2StreamMultiplexer.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/TestAbstractH2StreamMultiplexer.java
index 5eef30f19..7c7ad7919 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/TestAbstractH2StreamMultiplexer.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/TestAbstractH2StreamMultiplexer.java
@@ -957,6 +957,7 @@ static final class PriorityHeaderSender implements H2StreamHandler {
sent = true;
}
}
+ @Override public void outputAborted() { }
@Override public void consumePromise(final List<Header> headers) { }
@Override public void consumeHeader(final List<Header> headers, final boolean endStream) { }
@Override public void updateInputCapacity() { }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
index 8206fd3f7..f750c2a73 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
@@ -246,6 +246,7 @@ void consumeHeader(final HttpResponse response, final EntityDetails entityDetail
if (status >= HttpStatus.SC_REDIRECTION) {
requestState.set(MessageState.COMPLETE);
if (!outputChannel.abortGracefully()) {
+ exchangeHandler.outputAborted();
keepAlive = false;
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncDataExchangeHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncDataExchangeHandler.java
index e942e3909..ba53e4950 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncDataExchangeHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncDataExchangeHandler.java
@@ -41,4 +41,13 @@ public interface AsyncDataExchangeHandler extends AsyncDataConsumer, AsyncDataPr
*/
void failed(Exception cause);
+ /**
+ * Triggered to signal the opposite endpoint requesed graceful
+ * termination of the outgoing data stream.
+ *
+ * @since 5.5
+ */
+ default void outputAborted() {
+ }
+
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicAsyncServerExpectationDecorator.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicAsyncServerExpectationDecorator.java
index 326e61839..76aed1629 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicAsyncServerExpectationDecorator.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicAsyncServerExpectationDecorator.java
@@ -141,6 +141,11 @@ public final void produce(final DataStreamChannel channel) throws IOException {
}
}
+ @Override
+ public void outputAborted() {
+ handler.outputAborted();
+ }
+
@Override
public final void failed(final Exception cause) {
if (exceptionCallback != null) {