1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.netty5.example.http2.helloworld.multiplex.server;
18
19 import io.netty5.channel.ChannelHandler;
20 import io.netty5.channel.ChannelHandlerContext;
21 import io.netty5.channel.ChannelInitializer;
22 import io.netty5.channel.ChannelPipeline;
23 import io.netty5.channel.SimpleChannelInboundHandler;
24 import io.netty5.channel.socket.SocketChannel;
25 import io.netty5.example.http2.helloworld.server.HelloWorldHttp1Handler;
26 import io.netty5.handler.codec.http.HttpMessage;
27 import io.netty5.handler.codec.http.HttpObjectAggregator;
28 import io.netty5.handler.codec.http.HttpServerCodec;
29 import io.netty5.handler.codec.http.HttpServerUpgradeHandler;
30 import io.netty5.handler.codec.http.HttpServerUpgradeHandler.UpgradeCodecFactory;
31 import io.netty5.handler.codec.http2.Http2CodecUtil;
32 import io.netty5.handler.codec.http2.Http2FrameCodecBuilder;
33 import io.netty5.handler.codec.http2.Http2MultiplexHandler;
34 import io.netty5.handler.codec.http2.Http2ServerUpgradeCodec;
35 import io.netty5.handler.ssl.SslContext;
36 import io.netty5.util.AsciiString;
37 import io.netty5.util.ReferenceCountUtil;
38
39 import static io.netty5.util.internal.ObjectUtil.checkPositiveOrZero;
40
41
42
43
44
45 public class Http2ServerInitializer extends ChannelInitializer<SocketChannel> {
46
47 private static final UpgradeCodecFactory upgradeCodecFactory = protocol -> {
48 if (AsciiString.contentEquals(Http2CodecUtil.HTTP_UPGRADE_PROTOCOL_NAME, protocol)) {
49 return new Http2ServerUpgradeCodec(
50 Http2FrameCodecBuilder.forServer().build(),
51 new Http2MultiplexHandler(new HelloWorldHttp2Handler()));
52 } else {
53 return null;
54 }
55 };
56
57 private final SslContext sslCtx;
58 private final int maxHttpContentLength;
59
60 public Http2ServerInitializer(SslContext sslCtx) {
61 this(sslCtx, 16 * 1024);
62 }
63
64 public Http2ServerInitializer(SslContext sslCtx, int maxHttpContentLength) {
65 this.sslCtx = sslCtx;
66 this.maxHttpContentLength = checkPositiveOrZero(maxHttpContentLength, "maxHttpContentLength");
67 }
68
69 @Override
70 public void initChannel(SocketChannel ch) {
71 if (sslCtx != null) {
72 configureSsl(ch);
73 } else {
74 configureClearText(ch);
75 }
76 }
77
78
79
80
81 private void configureSsl(SocketChannel ch) {
82 ch.pipeline().addLast(sslCtx.newHandler(ch.bufferAllocator()), new Http2OrHttpHandler());
83 }
84
85
86
87
88 private void configureClearText(SocketChannel ch) {
89 final ChannelPipeline p = ch.pipeline();
90 final HttpServerCodec sourceCodec = new HttpServerCodec();
91
92 p.addLast(sourceCodec);
93 p.addLast(new HttpServerUpgradeHandler(sourceCodec, upgradeCodecFactory));
94 p.addLast(new SimpleChannelInboundHandler<HttpMessage>() {
95 @Override
96 protected void messageReceived(ChannelHandlerContext ctx, HttpMessage msg) throws Exception {
97
98 System.err.println("Directly talking: " + msg.protocolVersion() + " (no upgrade was attempted)");
99 ChannelPipeline pipeline = ctx.pipeline();
100 pipeline.addAfter(ctx.name(), null, new HelloWorldHttp1Handler("Direct. No Upgrade Attempted."));
101 pipeline.addAfter(ctx.name(), null, new HttpObjectAggregator(maxHttpContentLength));
102 ctx.fireChannelRead(ReferenceCountUtil.retain(msg));
103 pipeline.remove(this);
104 }
105 });
106
107 p.addLast(new UserEventLogger());
108 }
109
110
111
112
113 private static class UserEventLogger implements ChannelHandler {
114 @Override
115 public void channelInboundEvent(ChannelHandlerContext ctx, Object evt) {
116 System.out.println("User Event Triggered: " + evt);
117 ctx.fireChannelInboundEvent(evt);
118 }
119 }
120 }