Addings helper methods to HTTP/2 handler

Motivation:

Subclasses of AbstractHttp2ConnectionHandler have to implement all frame
handler methods, many of which can be ignored in many cases.  Also there
is no easy way to access the connection object.

Modifications:

Added default implementations for frame handler methods to
AbstractHttp2ConnectionHandler, and added an accessor for the
connection.

Also fixed example test for HTTP/2 with cleartext upgrade. It must have
been broken by recent commits.

Result:

AbstractHttp2ConnectionHandler is more subclass-friendly.
This commit is contained in:
nmittler 2014-06-12 10:28:54 -07:00 committed by Norman Maurer
parent c4d585420f
commit 1d8c7ff52e
5 changed files with 124 additions and 153 deletions

View File

@ -174,10 +174,6 @@ public abstract class AbstractHttp2ConnectionHandler extends ByteToMessageDecode
freeResources();
}
protected final ChannelHandlerContext ctx() {
return ctx;
}
@Override
public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
// Avoid NotYetConnectedException
@ -227,10 +223,129 @@ public abstract class AbstractHttp2ConnectionHandler extends ByteToMessageDecode
return settings;
}
/**
* Default implementation. Does nothing.
*/
@Override
public void onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding,
boolean endOfStream, boolean endOfSegment, boolean compressed) throws Http2Exception {
}
/**
* This will never actually be called, so marked as final. All received headers frames will be
* handled by
* {@link #onHeadersRead(ChannelHandlerContext, int, Http2Headers, int, short, boolean, int, boolean, boolean)}.
*/
@Override
public final void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
int padding, boolean endStream, boolean endSegment) throws Http2Exception {
}
/**
* Default implementation. Does nothing.
*/
@Override
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
int streamDependency, short weight, boolean exclusive, int padding, boolean endStream,
boolean endSegment) throws Http2Exception {
}
/**
* Default implementation. Does nothing.
*/
@Override
public void onPriorityRead(ChannelHandlerContext ctx, int streamId, int streamDependency,
short weight, boolean exclusive) throws Http2Exception {
}
/**
* Default implementation. Does nothing.
*/
@Override
public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode)
throws Http2Exception {
}
/**
* Default implementation. Does nothing.
*/
@Override
public void onSettingsAckRead(ChannelHandlerContext ctx) throws Http2Exception {
}
/**
* Default implementation. Does nothing.
*/
@Override
public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings)
throws Http2Exception {
}
/**
* Default implementation. Does nothing.
*/
@Override
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
}
/**
* Default implementation. Does nothing.
*/
@Override
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
}
/**
* Default implementation. Does nothing.
*/
@Override
public void onPushPromiseRead(ChannelHandlerContext ctx, int streamId, int promisedStreamId,
Http2Headers headers, int padding) throws Http2Exception {
}
/**
* Default implementation. Does nothing.
*/
@Override
public void onGoAwayRead(ChannelHandlerContext ctx, int lastStreamId, long errorCode,
ByteBuf debugData) throws Http2Exception {
}
/**
* Default implementation. Does nothing.
*/
@Override
public void onWindowUpdateRead(ChannelHandlerContext ctx, int streamId, int windowSizeIncrement)
throws Http2Exception {
}
/**
* Default implementation. Does nothing.
*/
@Override
public void onAltSvcRead(ChannelHandlerContext ctx, int streamId, long maxAge, int port,
ByteBuf protocolId, String host, String origin) throws Http2Exception {
}
/**
* Default implementation. Does nothing.
*/
@Override
public void onBlockedRead(ChannelHandlerContext ctx, int streamId) throws Http2Exception {
}
protected final ChannelHandlerContext ctx() {
return ctx;
}
protected final Http2Connection connection() {
return connection;
}
/**
* Gets the next stream ID that can be created by the local endpoint.
*/
protected int nextStreamId() {
protected final int nextStreamId() {
return connection.local().nextStreamId();
}

View File

@ -119,12 +119,6 @@ public class DelegatingHttp2ConnectionHandler extends AbstractHttp2ConnectionHan
observer.onDataRead(ctx, streamId, data, padding, endOfStream, endOfSegment, compressed);
}
@Override
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
int padding, boolean endStream, boolean endSegment) throws Http2Exception {
observer.onHeadersRead(ctx, streamId, headers, padding, endStream, endSegment);
}
@Override
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
int streamDependency, short weight, boolean exclusive, int padding, boolean endStream,

View File

@ -149,11 +149,6 @@ public class Http2ClientConnectionHandler extends AbstractHttp2ConnectionHandler
}
}
@Override
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
int padding, boolean endStream, boolean endSegment) throws Http2Exception {
}
@Override
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
int streamDependency, short weight, boolean exclusive, int padding, boolean endStream,
@ -163,20 +158,6 @@ public class Http2ClientConnectionHandler extends AbstractHttp2ConnectionHandler
}
}
@Override
public void onPriorityRead(ChannelHandlerContext ctx, int streamId, int streamDependency,
short weight, boolean exclusive) throws Http2Exception {
}
@Override
public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode)
throws Http2Exception {
}
@Override
public void onSettingsAckRead(ChannelHandlerContext ctx) throws Http2Exception {
}
@Override
public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings) throws Http2Exception {
if (!initPromise.isDone()) {
@ -184,38 +165,6 @@ public class Http2ClientConnectionHandler extends AbstractHttp2ConnectionHandler
}
}
@Override
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
}
@Override
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
}
@Override
public void onPushPromiseRead(ChannelHandlerContext ctx, int streamId, int promisedStreamId,
Http2Headers headers, int padding) throws Http2Exception {
}
@Override
public void onGoAwayRead(ChannelHandlerContext ctx, int lastStreamId, long errorCode,
ByteBuf debugData) throws Http2Exception {
}
@Override
public void onWindowUpdateRead(ChannelHandlerContext ctx, int streamId, int windowSizeIncrement)
throws Http2Exception {
}
@Override
public void onAltSvcRead(ChannelHandlerContext ctx, int streamId, long maxAge, int port,
ByteBuf protocolId, String host, String origin) throws Http2Exception {
}
@Override
public void onBlockedRead(ChannelHandlerContext ctx, int streamId) throws Http2Exception {
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (!initPromise.isDone()) {

View File

@ -15,6 +15,8 @@
package io.netty.example.http2.server;
import static io.netty.example.http2.Http2ExampleUtil.UPGRADE_RESPONSE_HEADER;
import static io.netty.util.internal.logging.InternalLogLevel.INFO;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.example.http2.client.Http2ClientConnectionHandler;
@ -32,11 +34,8 @@ import io.netty.handler.codec.http2.Http2FrameLogger;
import io.netty.handler.codec.http2.Http2Headers;
import io.netty.handler.codec.http2.Http2InboundFrameLogger;
import io.netty.handler.codec.http2.Http2OutboundFrameLogger;
import io.netty.handler.codec.http2.Http2Settings;
import io.netty.util.CharsetUtil;
import io.netty.util.internal.logging.InternalLoggerFactory;
import static io.netty.example.http2.Http2ExampleUtil.*;
import static io.netty.util.internal.logging.InternalLogLevel.*;
/**
* A simple handler that responds with the message "Hello World!".
@ -84,18 +83,6 @@ public class HelloWorldHttp2Handler extends AbstractHttp2ConnectionHandler {
}
}
/**
* If receive a frame with end-of-stream set, send a pre-canned response.
*/
@Override
public void onHeadersRead(ChannelHandlerContext ctx, int streamId,
Http2Headers headers, int padding, boolean endStream,
boolean endSegment) throws Http2Exception {
if (endStream) {
sendResponse(ctx(), streamId);
}
}
/**
* If receive a frame with end-of-stream set, send a pre-canned response.
*/
@ -109,57 +96,6 @@ public class HelloWorldHttp2Handler extends AbstractHttp2ConnectionHandler {
}
}
@Override
public void onPriorityRead(ChannelHandlerContext ctx, int streamId, int streamDependency,
short weight, boolean exclusive) throws Http2Exception {
}
@Override
public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode)
throws Http2Exception {
}
@Override
public void onSettingsAckRead(ChannelHandlerContext ctx) throws Http2Exception {
}
@Override
public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings)
throws Http2Exception {
}
@Override
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
}
@Override
public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
}
@Override
public void onPushPromiseRead(ChannelHandlerContext ctx, int streamId, int promisedStreamId,
Http2Headers headers, int padding) throws Http2Exception {
}
@Override
public void onGoAwayRead(ChannelHandlerContext ctx, int lastStreamId, long errorCode,
ByteBuf debugData) throws Http2Exception {
}
@Override
public void onWindowUpdateRead(ChannelHandlerContext ctx, int streamId, int windowSizeIncrement)
throws Http2Exception {
}
@Override
public void onAltSvcRead(ChannelHandlerContext ctx, int streamId, long maxAge, int port,
ByteBuf protocolId, String host, String origin) throws Http2Exception {
}
@Override
public void onBlockedRead(ChannelHandlerContext ctx, int streamId) throws Http2Exception {
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();

View File

@ -17,13 +17,10 @@
package io.netty.example.http2.server;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerAppender;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.HttpServerUpgradeHandler;
import io.netty.handler.codec.http2.Http2ServerUpgradeCodec;
import io.netty.handler.ssl.SslContext;
@ -61,7 +58,7 @@ public class Http2ServerInitializer extends ChannelInitializer<SocketChannel> {
* Configure the pipeline for a cleartext upgrade from HTTP to HTTP/2.
*/
private static void configureClearText(SocketChannel ch) {
HttpCodec sourceCodec = new HttpCodec();
HttpServerCodec sourceCodec = new HttpServerCodec();
HttpServerUpgradeHandler.UpgradeCodec upgradeCodec =
new Http2ServerUpgradeCodec(new HelloWorldHttp2Handler());
HttpServerUpgradeHandler upgradeHandler =
@ -72,26 +69,6 @@ public class Http2ServerInitializer extends ChannelInitializer<SocketChannel> {
ch.pipeline().addLast(new UserEventLogger());
}
/**
* Source codec for HTTP cleartext upgrade.
*/
private static final class HttpCodec
extends ChannelHandlerAppender implements HttpServerUpgradeHandler.SourceCodec {
HttpCodec() {
add("httpRequestDecoder", new HttpRequestDecoder());
add("httpResponseEncoder", new HttpResponseEncoder());
add("httpRequestAggregator", new HttpObjectAggregator(65536));
}
@Override
public void upgradeFrom(ChannelHandlerContext ctx) {
System.out.println("removing HTTP handlers");
ctx.pipeline().remove("httpRequestAggregator");
ctx.pipeline().remove("httpResponseEncoder");
ctx.pipeline().remove("httpRequestDecoder");
}
}
/**
* Class that logs any User Events triggered on this channel.
*/