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