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:
parent
ecacd11b06
commit
a7f83aa23e
@ -15,28 +15,29 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.example.http2.helloworld.server;
|
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.CONNECTION;
|
||||||
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
|
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.HttpHeaderNames.CONTENT_TYPE;
|
||||||
import static io.netty.handler.codec.http.HttpResponseStatus.CONTINUE;
|
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.HttpResponseStatus.OK;
|
||||||
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
|
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"
|
* HTTP handler that responds with a "Hello World"
|
||||||
*/
|
*/
|
||||||
public class HelloWorldHttp1Handler extends SimpleChannelInboundHandler<HttpRequest> {
|
public class HelloWorldHttp1Handler extends SimpleChannelInboundHandler<FullHttpRequest> {
|
||||||
private final String establishApproach;
|
private final String establishApproach;
|
||||||
|
|
||||||
public HelloWorldHttp1Handler(String establishApproach) {
|
public HelloWorldHttp1Handler(String establishApproach) {
|
||||||
@ -44,7 +45,7 @@ public class HelloWorldHttp1Handler extends SimpleChannelInboundHandler<HttpRequ
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelRead0(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
|
public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
|
||||||
if (HttpHeaderUtil.is100ContinueExpected(req)) {
|
if (HttpHeaderUtil.is100ContinueExpected(req)) {
|
||||||
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
|
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import io.netty.channel.ChannelPipeline;
|
|||||||
import io.netty.channel.SimpleChannelInboundHandler;
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
import io.netty.channel.socket.SocketChannel;
|
import io.netty.channel.socket.SocketChannel;
|
||||||
import io.netty.handler.codec.http.HttpMessage;
|
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.HttpServerCodec;
|
||||||
import io.netty.handler.codec.http.HttpServerUpgradeHandler;
|
import io.netty.handler.codec.http.HttpServerUpgradeHandler;
|
||||||
import io.netty.handler.codec.http.HttpServerUpgradeHandler.UpgradeCodec;
|
import io.netty.handler.codec.http.HttpServerUpgradeHandler.UpgradeCodec;
|
||||||
@ -49,9 +50,18 @@ public class Http2ServerInitializer extends ChannelInitializer<SocketChannel> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private final SslContext sslCtx;
|
private final SslContext sslCtx;
|
||||||
|
private final int maxHttpContentLength;
|
||||||
|
|
||||||
public Http2ServerInitializer(SslContext sslCtx) {
|
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.sslCtx = sslCtx;
|
||||||
|
this.maxHttpContentLength = maxHttpContentLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 ChannelPipeline p = ch.pipeline();
|
||||||
final HttpServerCodec sourceCodec = new HttpServerCodec();
|
final HttpServerCodec sourceCodec = new HttpServerCodec();
|
||||||
|
|
||||||
@ -84,8 +94,10 @@ public class Http2ServerInitializer extends ChannelInitializer<SocketChannel> {
|
|||||||
protected void channelRead0(ChannelHandlerContext ctx, HttpMessage msg) throws Exception {
|
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.
|
// 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)");
|
System.err.println("Directly talking: " + msg.protocolVersion() + " (no upgrade was attempted)");
|
||||||
ctx.pipeline().replace(this, "http-hello-world",
|
ChannelPipeline pipeline = ctx.pipeline();
|
||||||
new HelloWorldHttp1Handler("Direct. No Upgrade Attempted."));
|
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);
|
ctx.fireChannelRead(msg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user