package fr.leogomes.http2;
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
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;
import fr.leogomes.Html;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderUtil;
import io.netty.handler.codec.http.HttpRequest;
/**
* Handles the exceptional case where HTTP 1.x was negotiated under TLS
*
* @author Leonardo Gomes <http://leogomes.fr>
*/
public class FallbackRequestHandler extends SimpleChannelInboundHandler<HttpRequest> {
private static final String response = "<html><body>"
+ "<h2>To view the example you need a browser that supports HTTP/2</h2>"
+ "<p>Try with Chrome 40+ or Firefox 36+</p>" + Html.FOOTER;
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
if (HttpHeaderUtil.is100ContinueExpected(req)) {
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
}
ByteBuf content = ctx.alloc().buffer();
content.writeBytes(response.getBytes());
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, content);
response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8");
response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes());
ctx.write(response).addListener(ChannelFutureListener.CLOSE);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
// cause.printStackTrace(); FIXME log in debug mode
ctx.close();
}
}