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