Skip to content
/ ecf Public
forked from eclipse-ecf/ecf

Commit 718b1b2

Browse files
Copilotlaeubi
andcommitted
Add HTTP/1.1 fallback handler and debug logging for h2c upgrade
Co-authored-by: laeubi <1331477+laeubi@users.noreply.github.com>
1 parent 63d159c commit 718b1b2

File tree

1 file changed

+67
-3
lines changed
  • tests/bundles/org.eclipse.ecf.tests.filetransfer.httpclientjava/src/org/eclipse/ecf/tests/filetransfer/httpclientjava/http2

1 file changed

+67
-3
lines changed

tests/bundles/org.eclipse.ecf.tests.filetransfer.httpclientjava/src/org/eclipse/ecf/tests/filetransfer/httpclientjava/http2/Http2ServerWithGoaway.java

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,15 @@
2828
import io.netty.channel.nio.NioEventLoopGroup;
2929
import io.netty.channel.socket.SocketChannel;
3030
import io.netty.channel.socket.nio.NioServerSocketChannel;
31+
import io.netty.handler.codec.http.DefaultFullHttpResponse;
32+
import io.netty.handler.codec.http.FullHttpRequest;
33+
import io.netty.handler.codec.http.HttpHeaderNames;
34+
import io.netty.handler.codec.http.HttpHeaderValues;
3135
import io.netty.handler.codec.http.HttpObjectAggregator;
3236
import io.netty.handler.codec.http.HttpResponseStatus;
3337
import io.netty.handler.codec.http.HttpServerCodec;
3438
import io.netty.handler.codec.http.HttpServerUpgradeHandler;
39+
import io.netty.handler.codec.http.HttpVersion;
3540
import io.netty.handler.codec.http2.DefaultHttp2DataFrame;
3641
import io.netty.handler.codec.http2.DefaultHttp2GoAwayFrame;
3742
import io.netty.handler.codec.http2.DefaultHttp2Headers;
@@ -164,12 +169,14 @@ public Http2ServerInitializer(Http2ServerHandler serverHandler) {
164169
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
165170
ChannelPipeline pipeline = ctx.pipeline();
166171

172+
System.out.println("Setting up HTTP/2 server pipeline with upgrade support");
173+
167174
// HTTP/1.1 codec for initial handshake and upgrade
168175
HttpServerCodec sourceCodec = new HttpServerCodec();
169-
pipeline.addLast(sourceCodec);
176+
pipeline.addLast("http-codec", sourceCodec);
170177

171178
// Aggregator for HTTP/1.1 messages (needed for upgrade)
172-
pipeline.addLast(new HttpObjectAggregator(Integer.MAX_VALUE));
179+
pipeline.addLast("aggregator", new HttpObjectAggregator(Integer.MAX_VALUE));
173180

174181
// Build HTTP/2 codec
175182
Http2FrameCodecBuilder http2Builder = Http2FrameCodecBuilder.forServer()
@@ -179,20 +186,73 @@ public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
179186
HttpServerUpgradeHandler upgradeHandler = new HttpServerUpgradeHandler(
180187
sourceCodec,
181188
protocol -> {
189+
System.out.println("Upgrade requested for protocol: " + protocol);
182190
if (AsciiString.contentEquals(Http2CodecUtil.HTTP_UPGRADE_PROTOCOL_NAME, protocol)) {
183191
return new Http2ServerUpgradeCodec(http2Builder.build(), serverHandler);
184192
}
185193
return null;
186194
}
187195
);
188196

189-
pipeline.addLast(upgradeHandler);
197+
pipeline.addLast("upgrade-handler", upgradeHandler);
198+
199+
// Fallback handler for non-upgraded HTTP/1.1 requests
200+
pipeline.addLast("http1-fallback", new Http1FallbackHandler(serverHandler.goawayAfter));
190201

191202
// Remove this initializer
192203
pipeline.remove(this);
193204
}
194205
}
195206

207+
/**
208+
* Fallback handler for HTTP/1.1 requests that don't upgrade to HTTP/2
209+
*/
210+
private static final class Http1FallbackHandler extends ChannelInboundHandlerAdapter {
211+
private final AtomicInteger goawayAfter;
212+
213+
public Http1FallbackHandler(AtomicInteger goawayAfter) {
214+
this.goawayAfter = goawayAfter;
215+
}
216+
217+
@Override
218+
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
219+
if (msg instanceof FullHttpRequest) {
220+
System.out.println("Received HTTP/1.1 request (no upgrade): " + ((FullHttpRequest) msg).uri());
221+
FullHttpRequest request = (FullHttpRequest) msg;
222+
223+
// Send HTTP/1.1 response
224+
ByteBuf content = Unpooled.copiedBuffer("Hello from HTTP/2 server (HTTP/1.1 fallback)", CharsetUtil.UTF_8);
225+
DefaultFullHttpResponse response = new DefaultFullHttpResponse(
226+
HttpVersion.HTTP_1_1,
227+
HttpResponseStatus.OK,
228+
content
229+
);
230+
response.headers().set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN);
231+
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
232+
response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
233+
234+
ctx.writeAndFlush(response).addListener(future -> {
235+
if (goawayAfter.decrementAndGet() == 0) {
236+
System.out.println("Request count reached, closing connection");
237+
}
238+
ctx.close();
239+
});
240+
241+
request.release();
242+
} else {
243+
System.out.println("Passing through message of type: " + msg.getClass().getName());
244+
super.channelRead(ctx, msg);
245+
}
246+
}
247+
248+
@Override
249+
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
250+
System.err.println("Exception in HTTP/1.1 fallback handler: " + cause.getMessage());
251+
cause.printStackTrace();
252+
ctx.close();
253+
}
254+
}
255+
196256
private static final class Http2ServerHandler extends ChannelInboundHandlerAdapter {
197257

198258
private AtomicInteger goawayAfter;
@@ -211,13 +271,17 @@ public void channelActive(ChannelHandlerContext ctx) throws Exception {
211271

212272
@Override
213273
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
274+
System.out.println("Http2ServerHandler received message of type: " + msg.getClass().getName());
214275
if (msg instanceof Http2HeadersFrame) {
215276
Http2HeadersFrame headersFrame = (Http2HeadersFrame) msg;
216277
sendResponse(ctx, headersFrame);
217278
if (goawayAfter.decrementAndGet() == 0) {
218279
System.out.println("Request count reached , sending GOAWAY");
219280
sendGoaway(ctx);
220281
}
282+
} else {
283+
System.out.println("Http2ServerHandler: Not an Http2HeadersFrame, passing through");
284+
super.channelRead(ctx, msg);
221285
}
222286
}
223287

0 commit comments

Comments
 (0)