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