Improves SelectedProtocol enum to avoid boilerplate on subclasses

NPN server providers return a String version of the negotiated protocol
and the getProtocolByName method allows to easily get an instance of
the SelectedProtocol enum and avoid the need for a switch statement in
each subclass to match the String against the enum value.
This commit is contained in:
Leonardo Freitas Gomes 2014-01-05 15:53:52 +01:00 committed by Norman Maurer
parent 56f8479b34
commit 7324ce6fde

View File

@ -25,24 +25,51 @@ import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder; import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.ssl.SslHandler; import io.netty.handler.ssl.SslHandler;
import javax.net.ssl.SSLEngine;
import java.util.List; import java.util.List;
import javax.net.ssl.SSLEngine;
/** /**
* {@link ChannelHandler} which is responsible to setup the {@link ChannelPipeline} either for * {@link ChannelHandler} which is responsible to setup the {@link ChannelPipeline} either for HTTP or SPDY. This offers
* HTTP or SPDY. This offers an easy way for users to support both at the same time while not care to * an easy way for users to support both at the same time while not care to much about the low-level details.
* much about the low-level details.
*/ */
public abstract class SpdyOrHttpChooser extends ByteToMessageDecoder { public abstract class SpdyOrHttpChooser extends ByteToMessageDecoder {
// TODO: Replace with generic NPN handler // TODO: Replace with generic NPN handler
public enum SelectedProtocol { public enum SelectedProtocol {
SPDY_3, SPDY_3("spdy/3"),
SPDY_3_1, SPDY_3_1("spdy/3.1"),
HTTP_1_1, HTTP_1_1("http/1.1"),
HTTP_1_0, HTTP_1_0("http/1.0"),
UNKNOWN UNKNOWN("Unknown");
private String name;
private SelectedProtocol(String defaultName) {
this.name = defaultName;
}
public String getName() {
return this.name;
}
/**
* Get an instance of this enum based on the protocol name returned by the NPN server provider
*
* @param name
* the protocol name
* @return the SelectedProtocol instance
*/
public static SelectedProtocol getProtocolByName(String name) {
for (SelectedProtocol protocol : SelectedProtocol.values()) {
if (protocol.getName().equals(name)) {
return protocol;
}
}
return UNKNOWN;
}
} }
private final int maxSpdyContentLength; private final int maxSpdyContentLength;
@ -54,8 +81,8 @@ public abstract class SpdyOrHttpChooser extends ByteToMessageDecoder {
} }
/** /**
* Return the {@link SelectedProtocol} for the {@link SSLEngine}. If its not known yet implementations * Return the {@link SelectedProtocol} for the {@link SSLEngine}. If its not known yet implementations MUST return
* MUST return {@link SelectedProtocol#UNKNOWN}. * {@link SelectedProtocol#UNKNOWN}.
* *
*/ */
protected abstract SelectedProtocol getProtocol(SSLEngine engine); protected abstract SelectedProtocol getProtocol(SSLEngine engine);
@ -63,14 +90,17 @@ public abstract class SpdyOrHttpChooser extends ByteToMessageDecoder {
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if (initPipeline(ctx)) { if (initPipeline(ctx)) {
// When we reached here we can remove this handler as its now clear what protocol we want to use // When we reached here we can remove this handler as its now clear
// from this point on. This will also take care of forward all messages. // what protocol we want to use
// from this point on. This will also take care of forward all
// messages.
ctx.pipeline().remove(this); ctx.pipeline().remove(this);
} }
} }
private boolean initPipeline(ChannelHandlerContext ctx) { private boolean initPipeline(ChannelHandlerContext ctx) {
// Get the SslHandler from the ChannelPipeline so we can obtain the SslEngine from it. // Get the SslHandler from the ChannelPipeline so we can obtain the
// SslEngine from it.
SslHandler handler = ctx.pipeline().get(SslHandler.class); SslHandler handler = ctx.pipeline().get(SslHandler.class);
if (handler == null) { if (handler == null) {
// SslHandler is needed by SPDY by design. // SslHandler is needed by SPDY by design.
@ -124,19 +154,17 @@ public abstract class SpdyOrHttpChooser extends ByteToMessageDecoder {
} }
/** /**
* Create the {@link ChannelHandler} that is responsible for handling the http requests * Create the {@link ChannelHandler} that is responsible for handling the http requests when the
* when the {@link SelectedProtocol} was {@link SelectedProtocol#HTTP_1_0} or * {@link SelectedProtocol} was {@link SelectedProtocol#HTTP_1_0} or {@link SelectedProtocol#HTTP_1_1}
* {@link SelectedProtocol#HTTP_1_1}
*/ */
protected abstract ChannelHandler createHttpRequestHandlerForHttp(); protected abstract ChannelHandler createHttpRequestHandlerForHttp();
/** /**
* Create the {@link ChannelHandler} that is responsible for handling the http responses * Create the {@link ChannelHandler} that is responsible for handling the http responses when the
* when the {@link SelectedProtocol} was {@link SelectedProtocol#SPDY_3} or * {@link SelectedProtocol} was {@link SelectedProtocol#SPDY_3} or {@link SelectedProtocol#SPDY_3_1}.
* {@link SelectedProtocol#SPDY_3_1}.
* *
* By default this getMethod will just delecate to {@link #createHttpRequestHandlerForHttp()}, but * By default this getMethod will just delecate to {@link #createHttpRequestHandlerForHttp()}, but sub-classes may
* sub-classes may override this to change the behaviour. * override this to change the behaviour.
*/ */
protected ChannelHandler createHttpRequestHandlerForSpdy() { protected ChannelHandler createHttpRequestHandlerForSpdy() {
return createHttpRequestHandlerForHttp(); return createHttpRequestHandlerForHttp();