Skip to content

Commit

Permalink
Merge #3000 into 1.1.15
Browse files Browse the repository at this point in the history
  • Loading branch information
violetagg committed Dec 14, 2023
2 parents 57ff06c + 57ac377 commit d3029a3
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,9 @@ protected void onInboundNext(ChannelHandlerContext ctx, Object msg) {
log.debug(format(channel(), "Received last HTTP packet"));
}
if (msg != LastHttpContent.EMPTY_LAST_CONTENT) {
if (redirecting != null) {
// When there is HTTP/2 response with INBOUND HEADERS(endStream=false) followed by INBOUND DATA(endStream=true length=0),
// Netty sends LastHttpContent with empty buffer instead of EMPTY_LAST_CONTENT
if (redirecting != null || ((LastHttpContent) msg).content().readableBytes() == 0) {
ReferenceCountUtil.release(msg);
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package reactor.netty.http;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http2.Http2Connection;
import io.netty.handler.codec.http2.Http2FrameCodec;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
Expand Down Expand Up @@ -44,6 +45,7 @@
import reactor.util.annotation.Nullable;
import reactor.util.function.Tuple2;

import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.time.Duration;
import java.util.List;
Expand Down Expand Up @@ -695,4 +697,40 @@ private void doTestMaxStreams(HttpServer server, HttpClient client) {
.expectComplete()
.verify(Duration.ofSeconds(5));
}

@ParameterizedTest
@MethodSource("h2cCompatibleCombinations")
void testEmptyDataFrameH2C(HttpProtocol[] serverProtocols, HttpProtocol[] clientProtocols) {
doTestEmptyDataFrame(createServer().protocol(serverProtocols),
createClient(() -> disposableServer.address()).protocol(clientProtocols));
}

@ParameterizedTest
@MethodSource("h2CompatibleCombinations")
void testEmptyDataFrameH2(HttpProtocol[] serverProtocols, HttpProtocol[] clientProtocols) {
Http2SslContextSpec serverCtx = Http2SslContextSpec.forServer(ssc.certificate(), ssc.privateKey());
Http2SslContextSpec clientCtx =
Http2SslContextSpec.forClient()
.configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE));

doTestEmptyDataFrame(createServer().protocol(serverProtocols).secure(spec -> spec.sslContext(serverCtx)),
createClient(() -> disposableServer.address()).protocol(clientProtocols).secure(spec -> spec.sslContext(clientCtx)));
}

private void doTestEmptyDataFrame(HttpServer server, HttpClient client) {
disposableServer =
// Intentionality sends Flux with empty strings as we want to have
// OUTBOUND HEADERS(endStream=false) followed by OUTBOUND DATA(endStream=true length=0)
server.handle((req, res) -> res.sendString(Flux.just("", "")))
.bindNow();

String expectation = "EMPTY";
client.get()
.uri("/")
.response((res, bytes) -> bytes.defaultIfEmpty(Unpooled.wrappedBuffer(expectation.getBytes(Charset.defaultCharset()))))
.as(StepVerifier::create)
.expectNextMatches(buf -> expectation.equals(buf.toString(Charset.defaultCharset())))
.expectComplete()
.verify(Duration.ofSeconds(5));
}
}

0 comments on commit d3029a3

Please sign in to comment.