HTTP/2 Example Needs FullHttpRequest

Motivation:
The HTTP/2 hello world example server should be expecting a FullHttpRequest when falling back to HTTP/1.x mode.

Modifications:
- HelloWorldHttp1Handler should process FullHttpRequestObjects
- Http2ServerInitializer should insert an HttpObjectAggregator into the pipeline if no upgrade was attempted

Result:
Responses from the HelloWorldHttp1Handler should only come after full HTTP requests are received.
This commit is contained in:
Scott Mitchell 2015-06-23 09:25:03 -07:00
parent ecacd11b06
commit a7f83aa23e
2 changed files with 31 additions and 18 deletions

View File

@ -15,28 +15,29 @@
*/
package io.netty.example.http2.helloworld.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;
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.HttpHeaderValues;
import io.netty.handler.codec.http.HttpRequest;
import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION;
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 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;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderUtil;
import io.netty.handler.codec.http.HttpHeaderValues;
/**
* HTTP handler that responds with a "Hello World"
*/
public class HelloWorldHttp1Handler extends SimpleChannelInboundHandler<HttpRequest> {
public class HelloWorldHttp1Handler extends SimpleChannelInboundHandler<FullHttpRequest> {
private final String establishApproach;
public HelloWorldHttp1Handler(String establishApproach) {
@ -44,7 +45,7 @@ public class HelloWorldHttp1Handler extends SimpleChannelInboundHandler<HttpRequ
}
@Override
public void channelRead0(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
if (HttpHeaderUtil.is100ContinueExpected(req)) {
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
}

View File

@ -23,6 +23,7 @@ import io.netty.channel.ChannelPipeline;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpMessage;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.HttpServerUpgradeHandler;
import io.netty.handler.codec.http.HttpServerUpgradeHandler.UpgradeCodec;
@ -49,9 +50,18 @@ public class Http2ServerInitializer extends ChannelInitializer<SocketChannel> {
};
private final SslContext sslCtx;
private final int maxHttpContentLength;
public Http2ServerInitializer(SslContext sslCtx) {
this(sslCtx, 16 * 1024);
}
public Http2ServerInitializer(SslContext sslCtx, int maxHttpContentLength) {
if (maxHttpContentLength < 0) {
throw new IllegalArgumentException("maxHttpContentLength (expected >= 0): " + maxHttpContentLength);
}
this.sslCtx = sslCtx;
this.maxHttpContentLength = maxHttpContentLength;
}
@Override
@ -71,9 +81,9 @@ public class Http2ServerInitializer extends ChannelInitializer<SocketChannel> {
}
/**
* Configure the pipeline for a cleartext upgrade from HTTP to HTTP/2.
* Configure the pipeline for a cleartext upgrade from HTTP to HTTP/2.0
*/
private static void configureClearText(SocketChannel ch) {
private void configureClearText(SocketChannel ch) {
final ChannelPipeline p = ch.pipeline();
final HttpServerCodec sourceCodec = new HttpServerCodec();
@ -84,8 +94,10 @@ public class Http2ServerInitializer extends ChannelInitializer<SocketChannel> {
protected void channelRead0(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."));
ChannelPipeline pipeline = ctx.pipeline();
ChannelHandlerContext thisCtx = pipeline.context(this);
pipeline.addAfter(thisCtx.name(), null, new HelloWorldHttp1Handler("Direct. No Upgrade Attempted."));
pipeline.replace(this, null, new HttpObjectAggregator(maxHttpContentLength));
ctx.fireChannelRead(msg);
}
});