diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java
index 12815c225c..4251317457 100644
--- a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java
+++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java
@@ -478,11 +478,19 @@ public class DefaultHttp2Connection implements Http2Connection {
if (!createdBy().canOpenStream()) {
throw connectionError(PROTOCOL_ERROR, "Maximum active streams violated for this endpoint.");
}
+
activate();
return this;
}
void activate() {
+ // If the stream is opened in a half-closed state, the headers must have either
+ // been sent if this is a local stream, or received if it is a remote stream.
+ if (state == HALF_CLOSED_LOCAL) {
+ headersSent(/*isInformational*/ false);
+ } else if (state == HALF_CLOSED_REMOTE) {
+ headersReceived(/*isInformational*/ false);
+ }
activeStreams.activate(this);
}
diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2Stream.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2Stream.java
index 3b654425cf..6db9d78a80 100644
--- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2Stream.java
+++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2Stream.java
@@ -76,9 +76,9 @@ public interface Http2Stream {
*
* - {@link State#OPEN} if {@link #state()} is {@link State#IDLE} and {@code halfClosed} is {@code false}.
* - {@link State#HALF_CLOSED_LOCAL} if {@link #state()} is {@link State#IDLE} and {@code halfClosed}
- * is {@code true} and the stream is local.
+ * is {@code true} and the stream is local. In this state, {@link #isHeadersSent()} is {@code true}
* - {@link State#HALF_CLOSED_REMOTE} if {@link #state()} is {@link State#IDLE} and {@code halfClosed}
- * is {@code true} and the stream is remote.
+ * is {@code true} and the stream is remote. In this state, {@link #isHeadersReceived()} is {@code true}
* - {@link State#RESERVED_LOCAL} if {@link #state()} is {@link State#HALF_CLOSED_REMOTE}.
* - {@link State#RESERVED_REMOTE} if {@link #state()} is {@link State#HALF_CLOSED_LOCAL}.
*
diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionTest.java
index 966f668b40..ef385beed6 100644
--- a/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionTest.java
+++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionTest.java
@@ -294,12 +294,14 @@ public class DefaultHttp2ConnectionTest {
assertEquals(State.HALF_CLOSED_REMOTE, stream.state());
assertEquals(2, client.numActiveStreams());
assertEquals(4, client.remote().lastStreamCreated());
+ assertTrue(stream.isHeadersReceived());
stream = client.local().createStream(3, true);
assertEquals(3, stream.id());
assertEquals(State.HALF_CLOSED_LOCAL, stream.state());
assertEquals(3, client.numActiveStreams());
assertEquals(3, client.local().lastStreamCreated());
+ assertTrue(stream.isHeadersSent());
stream = client.local().createStream(5, false);
assertEquals(5, stream.id());