HTTP/2 Server Example No Response for HTTP/1.x Only Clients
Motiviation: The HTTP/2 server example just hangs when a client is using only HTTP with no ALPN or upgrade attempts. We should still send some kind of response. Modifications: The HTTP/2 server example has a special handler to detect no upgrade HTTP clients and generate a response. Result: Clients that just use HTTP with no upgrade will no appear hung when interacting with the HTTP/2 server example.
This commit is contained in:
parent
9bf636076a
commit
04c0d77287
@ -15,7 +15,9 @@
|
||||
*/
|
||||
package io.netty.example.http2.server;
|
||||
|
||||
import static io.netty.util.internal.ObjectUtil.checkNotNull;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
@ -31,11 +33,15 @@ import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE;
|
||||
import static io.netty.handler.codec.http.HttpResponseStatus.CONTINUE;
|
||||
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
|
||||
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
|
||||
|
||||
/**
|
||||
* HTTP handler that responds with a "Hello World"
|
||||
*/
|
||||
public class HelloWorldHttp1Handler extends SimpleChannelInboundHandler<HttpRequest> {
|
||||
private final String establishApproach;
|
||||
|
||||
public HelloWorldHttp1Handler(String establishApproach) {
|
||||
this.establishApproach = checkNotNull(establishApproach, "establishApproach");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
|
||||
@ -46,6 +52,7 @@ public class HelloWorldHttp1Handler extends SimpleChannelInboundHandler<HttpRequ
|
||||
|
||||
ByteBuf content = ctx.alloc().buffer();
|
||||
content.writeBytes(HelloWorldHttp2Handler.RESPONSE_BYTES.duplicate());
|
||||
ByteBufUtil.writeAscii(content, " - via " + req.protocolVersion() + " (" + establishApproach + ")");
|
||||
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, content);
|
||||
response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");
|
||||
|
@ -21,6 +21,7 @@ import static io.netty.example.http2.Http2ExampleUtil.UPGRADE_RESPONSE_HEADER;
|
||||
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
|
||||
import static io.netty.handler.logging.LogLevel.INFO;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.HttpServerUpgradeHandler;
|
||||
import io.netty.handler.codec.http2.DefaultHttp2Connection;
|
||||
@ -112,7 +113,10 @@ public class HelloWorldHttp2Handler extends Http2ConnectionHandler {
|
||||
Http2Headers headers, int streamDependency, short weight,
|
||||
boolean exclusive, int padding, boolean endStream) throws Http2Exception {
|
||||
if (endStream) {
|
||||
sendResponse(ctx, streamId, RESPONSE_BYTES.duplicate());
|
||||
ByteBuf content = ctx.alloc().buffer();
|
||||
content.writeBytes(HelloWorldHttp2Handler.RESPONSE_BYTES.duplicate());
|
||||
ByteBufUtil.writeAscii(content, " - via HTTP/2");
|
||||
sendResponse(ctx, streamId, content);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ public class Http2OrHttpHandler extends Http2OrHttpChooser {
|
||||
|
||||
@Override
|
||||
protected ChannelHandler createHttp1RequestHandler() {
|
||||
return new HelloWorldHttp1Handler();
|
||||
return new HelloWorldHttp1Handler("ALPN Negotiation");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,7 +19,9 @@ package io.netty.example.http2.server;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.codec.http.HttpMessage;
|
||||
import io.netty.handler.codec.http.HttpServerCodec;
|
||||
import io.netty.handler.codec.http.HttpServerUpgradeHandler;
|
||||
import io.netty.handler.codec.http2.Http2ServerUpgradeCodec;
|
||||
@ -66,6 +68,16 @@ public class Http2ServerInitializer extends ChannelInitializer<SocketChannel> {
|
||||
|
||||
ch.pipeline().addLast(sourceCodec);
|
||||
ch.pipeline().addLast(upgradeHandler);
|
||||
ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpMessage>() {
|
||||
@Override
|
||||
protected void messageReceived(ChannelHandlerContext ctx, HttpMessage msg) throws Exception {
|
||||
// If this handler is hit then no upgrade has been attempted and the client is just talking HTTP.
|
||||
System.err.println("Directly talking: " + msg.protocolVersion() + " (no upgrade was attempted)");
|
||||
ctx.pipeline().replace(this, "http-hello-world",
|
||||
new HelloWorldHttp1Handler("Direct. No Upgrade Attempted."));
|
||||
ctx.fireChannelRead(msg);
|
||||
}
|
||||
});
|
||||
ch.pipeline().addLast(new UserEventLogger());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user