1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.example.http2.helloworld.server;
17
18 import io.netty5.buffer.api.Buffer;
19 import io.netty5.channel.ChannelHandlerContext;
20 import io.netty5.handler.codec.http.FullHttpRequest;
21 import io.netty5.handler.codec.http.HttpHeaderNames;
22 import io.netty5.handler.codec.http.HttpMethod;
23 import io.netty5.handler.codec.http.HttpScheme;
24 import io.netty5.handler.codec.http.HttpServerUpgradeHandler;
25 import io.netty5.handler.codec.http2.DefaultHttp2Headers;
26 import io.netty5.handler.codec.http2.Http2ConnectionDecoder;
27 import io.netty5.handler.codec.http2.Http2ConnectionEncoder;
28 import io.netty5.handler.codec.http2.Http2ConnectionHandler;
29 import io.netty5.handler.codec.http2.Http2Flags;
30 import io.netty5.handler.codec.http2.Http2FrameListener;
31 import io.netty5.handler.codec.http2.Http2Headers;
32 import io.netty5.handler.codec.http2.Http2Settings;
33
34 import static io.netty5.handler.codec.http.HttpResponseStatus.OK;
35 import static io.netty5.util.CharsetUtil.US_ASCII;
36 import static io.netty5.util.CharsetUtil.UTF_8;
37
38
39
40
41 public final class HelloWorldHttp2Handler extends Http2ConnectionHandler implements Http2FrameListener {
42
43 static final byte[] RESPONSE_BYTES = "Hello World".getBytes(UTF_8);
44
45 HelloWorldHttp2Handler(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
46 Http2Settings initialSettings) {
47 super(decoder, encoder, initialSettings);
48 }
49
50 private static Http2Headers http1HeadersToHttp2Headers(FullHttpRequest request) {
51 CharSequence host = request.headers().get(HttpHeaderNames.HOST);
52 Http2Headers http2Headers = new DefaultHttp2Headers()
53 .method(HttpMethod.GET.asciiName())
54 .path(request.uri())
55 .scheme(HttpScheme.HTTP.name());
56 if (host != null) {
57 http2Headers.authority(host);
58 }
59 return http2Headers;
60 }
61
62
63
64
65
66 @Override
67 public void channelInboundEvent(ChannelHandlerContext ctx, Object evt) throws Exception {
68 if (evt instanceof HttpServerUpgradeHandler.UpgradeEvent) {
69 HttpServerUpgradeHandler.UpgradeEvent upgradeEvent =
70 (HttpServerUpgradeHandler.UpgradeEvent) evt;
71 onHeadersRead(ctx, 1, http1HeadersToHttp2Headers(upgradeEvent.upgradeRequest()), 0 , true);
72 }
73 super.channelInboundEvent(ctx, evt);
74 }
75
76 @Override
77 public void channelExceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
78 super.channelExceptionCaught(ctx, cause);
79 cause.printStackTrace();
80 ctx.close();
81 }
82
83
84
85
86 private void sendResponse(ChannelHandlerContext ctx, int streamId, Buffer payload) {
87
88 Http2Headers headers = new DefaultHttp2Headers().status(OK.codeAsText());
89 encoder().writeHeaders(ctx, streamId, headers, 0, false);
90 encoder().writeData(ctx, streamId, payload, 0, true);
91
92
93 }
94
95 @Override
96 public int onDataRead(ChannelHandlerContext ctx, int streamId, Buffer data, int padding, boolean endOfStream) {
97 int processed = data.readableBytes() + padding;
98 if (endOfStream) {
99 sendResponse(ctx, streamId, data);
100 }
101 return processed;
102 }
103
104 @Override
105 public void onHeadersRead(ChannelHandlerContext ctx, int streamId,
106 Http2Headers headers, int padding, boolean endOfStream) {
107 if (endOfStream) {
108 final byte[] viaBytes = " - via HTTP/2".getBytes(US_ASCII);
109 Buffer content = ctx.bufferAllocator().allocate(RESPONSE_BYTES.length + viaBytes.length)
110 .writeBytes(RESPONSE_BYTES).writeBytes(viaBytes);
111 sendResponse(ctx, streamId, content);
112 }
113 }
114
115 @Override
116 public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int streamDependency,
117 short weight, boolean exclusive, int padding, boolean endOfStream) {
118 onHeadersRead(ctx, streamId, headers, padding, endOfStream);
119 }
120
121 @Override
122 public void onPriorityRead(ChannelHandlerContext ctx, int streamId, int streamDependency,
123 short weight, boolean exclusive) {
124 }
125
126 @Override
127 public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) {
128 }
129
130 @Override
131 public void onSettingsAckRead(ChannelHandlerContext ctx) {
132 }
133
134 @Override
135 public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings) {
136 }
137
138 @Override
139 public void onPingRead(ChannelHandlerContext ctx, long data) {
140 }
141
142 @Override
143 public void onPingAckRead(ChannelHandlerContext ctx, long data) {
144 }
145
146 @Override
147 public void onPushPromiseRead(ChannelHandlerContext ctx, int streamId, int promisedStreamId,
148 Http2Headers headers, int padding) {
149 }
150
151 @Override
152 public void onGoAwayRead(ChannelHandlerContext ctx, int lastStreamId, long errorCode, Buffer debugData) {
153 }
154
155 @Override
156 public void onWindowUpdateRead(ChannelHandlerContext ctx, int streamId, int windowSizeIncrement) {
157 }
158
159 @Override
160 public void onUnknownFrame(ChannelHandlerContext ctx, byte frameType, int streamId,
161 Http2Flags flags, Buffer payload) {
162 }
163 }