Configures HTTP2 pipeline with more proper way
Motivation: When we use pipeline.replace and we still had ongoing inbound, then there will be some problem that inbound message would go to wrong handlers. So we add handler first, and remove self after add, so that the next handler will be the correct one. Modifications: Uses remove after addAfter instead of replace. Result: Fixed #6881
This commit is contained in:
parent
6ab9c177ac
commit
8320a45c15
@ -89,8 +89,11 @@ public final class CleartextHttp2ServerUpgradeHandler extends ChannelHandlerAdap
|
|||||||
// following network traffic
|
// following network traffic
|
||||||
ctx.pipeline()
|
ctx.pipeline()
|
||||||
.remove(httpServerCodec)
|
.remove(httpServerCodec)
|
||||||
.remove(httpServerUpgradeHandler)
|
.remove(httpServerUpgradeHandler);
|
||||||
.replace(this, null, http2ServerHandler);
|
|
||||||
|
ctx.pipeline().addAfter(ctx.name(), null, http2ServerHandler);
|
||||||
|
ctx.pipeline().remove(this);
|
||||||
|
|
||||||
ctx.fireUserEventTriggered(PriorKnowledgeUpgradeEvent.INSTANCE);
|
ctx.fireUserEventTriggered(PriorKnowledgeUpgradeEvent.INSTANCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,10 @@ package io.netty.handler.codec.http2;
|
|||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
import io.netty.channel.embedded.EmbeddedChannel;
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
import io.netty.handler.codec.http.DefaultHttpHeaders;
|
import io.netty.handler.codec.http.DefaultHttpHeaders;
|
||||||
import io.netty.handler.codec.http.HttpMethod;
|
import io.netty.handler.codec.http.HttpMethod;
|
||||||
@ -35,7 +37,6 @@ import io.netty.handler.codec.http2.Http2Stream.State;
|
|||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -56,8 +57,7 @@ public class CleartextHttp2ServerUpgradeHandlerTest {
|
|||||||
|
|
||||||
private List<Object> userEvents;
|
private List<Object> userEvents;
|
||||||
|
|
||||||
@Before
|
private void setUpServerChannel() {
|
||||||
public void setUp() {
|
|
||||||
frameListener = mock(Http2FrameListener.class);
|
frameListener = mock(Http2FrameListener.class);
|
||||||
|
|
||||||
http2ConnectionHandler = new Http2ConnectionHandlerBuilder().frameListener(frameListener).build();
|
http2ConnectionHandler = new Http2ConnectionHandlerBuilder().frameListener(frameListener).build();
|
||||||
@ -91,6 +91,8 @@ public class CleartextHttp2ServerUpgradeHandlerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void priorKnowledge() throws Exception {
|
public void priorKnowledge() throws Exception {
|
||||||
|
setUpServerChannel();
|
||||||
|
|
||||||
channel.writeInbound(Http2CodecUtil.connectionPrefaceBuf());
|
channel.writeInbound(Http2CodecUtil.connectionPrefaceBuf());
|
||||||
|
|
||||||
ByteBuf settingsFrame = settingsFrameBuf();
|
ByteBuf settingsFrame = settingsFrameBuf();
|
||||||
@ -109,6 +111,8 @@ public class CleartextHttp2ServerUpgradeHandlerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void upgrade() throws Exception {
|
public void upgrade() throws Exception {
|
||||||
|
setUpServerChannel();
|
||||||
|
|
||||||
String upgradeString = "GET / HTTP/1.1\r\n" +
|
String upgradeString = "GET / HTTP/1.1\r\n" +
|
||||||
"Host: example.com\r\n" +
|
"Host: example.com\r\n" +
|
||||||
"Connection: Upgrade, HTTP2-Settings\r\n" +
|
"Connection: Upgrade, HTTP2-Settings\r\n" +
|
||||||
@ -138,6 +142,8 @@ public class CleartextHttp2ServerUpgradeHandlerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void priorKnowledgeInFragments() throws Exception {
|
public void priorKnowledgeInFragments() throws Exception {
|
||||||
|
setUpServerChannel();
|
||||||
|
|
||||||
ByteBuf connectionPreface = Http2CodecUtil.connectionPrefaceBuf();
|
ByteBuf connectionPreface = Http2CodecUtil.connectionPrefaceBuf();
|
||||||
assertFalse(channel.writeInbound(connectionPreface.readBytes(5), connectionPreface));
|
assertFalse(channel.writeInbound(connectionPreface.readBytes(5), connectionPreface));
|
||||||
|
|
||||||
@ -156,6 +162,8 @@ public class CleartextHttp2ServerUpgradeHandlerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void downgrade() throws Exception {
|
public void downgrade() throws Exception {
|
||||||
|
setUpServerChannel();
|
||||||
|
|
||||||
String requestString = "GET / HTTP/1.1\r\n" +
|
String requestString = "GET / HTTP/1.1\r\n" +
|
||||||
"Host: example.com\r\n\r\n";
|
"Host: example.com\r\n\r\n";
|
||||||
ByteBuf inbound = Unpooled.buffer().writeBytes(requestString.getBytes(CharsetUtil.US_ASCII));
|
ByteBuf inbound = Unpooled.buffer().writeBytes(requestString.getBytes(CharsetUtil.US_ASCII));
|
||||||
@ -175,6 +183,45 @@ public class CleartextHttp2ServerUpgradeHandlerTest {
|
|||||||
assertNull(channel.readInbound());
|
assertNull(channel.readInbound());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void usedHttp2Codec() throws Exception {
|
||||||
|
final Http2Codec http2Codec = new Http2CodecBuilder(true, new ChannelInitializer<Channel>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(Channel ch) throws Exception {
|
||||||
|
}
|
||||||
|
}).build();
|
||||||
|
UpgradeCodecFactory upgradeCodecFactory = new UpgradeCodecFactory() {
|
||||||
|
@Override
|
||||||
|
public UpgradeCodec newUpgradeCodec(CharSequence protocol) {
|
||||||
|
return new Http2ServerUpgradeCodec(http2Codec);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
http2ConnectionHandler = http2Codec.frameCodec().connectionHandler();
|
||||||
|
|
||||||
|
userEvents = new ArrayList<Object>();
|
||||||
|
|
||||||
|
HttpServerCodec httpServerCodec = new HttpServerCodec();
|
||||||
|
HttpServerUpgradeHandler upgradeHandler = new HttpServerUpgradeHandler(httpServerCodec, upgradeCodecFactory);
|
||||||
|
|
||||||
|
CleartextHttp2ServerUpgradeHandler handler = new CleartextHttp2ServerUpgradeHandler(
|
||||||
|
httpServerCodec, upgradeHandler, http2Codec);
|
||||||
|
channel = new EmbeddedChannel(handler, new ChannelInboundHandlerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
|
||||||
|
userEvents.add(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assertFalse(channel.writeInbound(Http2CodecUtil.connectionPrefaceBuf()));
|
||||||
|
|
||||||
|
ByteBuf settingsFrame = settingsFrameBuf();
|
||||||
|
|
||||||
|
assertFalse(channel.writeInbound(settingsFrame));
|
||||||
|
|
||||||
|
assertEquals(1, userEvents.size());
|
||||||
|
assertTrue(userEvents.get(0) instanceof PriorKnowledgeUpgradeEvent);
|
||||||
|
}
|
||||||
|
|
||||||
private static ByteBuf settingsFrameBuf() {
|
private static ByteBuf settingsFrameBuf() {
|
||||||
ByteBuf settingsFrame = Unpooled.buffer();
|
ByteBuf settingsFrame = Unpooled.buffer();
|
||||||
settingsFrame.writeMedium(12); // Payload length
|
settingsFrame.writeMedium(12); // Payload length
|
||||||
|
Loading…
x
Reference in New Issue
Block a user