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