Next round of cleanup of http2 codec
Motivation: Bring the http2 codec more inline with the rest of Netty's code-base. Modifications: - Add null checks in constructors - Move private static methods into inner-classes where they are used - Use getBytes(CharsetUtil.UTf8) Result: More consistent code-base
This commit is contained in:
parent
98bfc8e600
commit
4307729ff7
@ -35,8 +35,8 @@ public final class DefaultHttp2Headers extends Http2Headers {
|
|||||||
private final HeaderEntry head;
|
private final HeaderEntry head;
|
||||||
|
|
||||||
private DefaultHttp2Headers(Builder builder) {
|
private DefaultHttp2Headers(Builder builder) {
|
||||||
this.entries = builder.entries;
|
entries = builder.entries;
|
||||||
this.head = builder.head;
|
head = builder.head;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -126,7 +126,7 @@ public final class DefaultHttp2Headers extends Http2Headers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds instances of {@link DefaultHttp2Header}.
|
* Builds instances of {@link DefaultHttp2Headers}.
|
||||||
*/
|
*/
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private HeaderEntry[] entries;
|
private HeaderEntry[] entries;
|
||||||
@ -344,6 +344,52 @@ public final class DefaultHttp2Headers extends Http2Headers {
|
|||||||
}
|
}
|
||||||
return value.toString();
|
return value.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a HTTP2 header value. Does not validate max length.
|
||||||
|
*/
|
||||||
|
private static void validateHeaderValue(String value) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new NullPointerException("value");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < value.length(); i ++) {
|
||||||
|
char c = value.charAt(i);
|
||||||
|
if (c == 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"value contains null character: " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a HTTP2 header name.
|
||||||
|
*/
|
||||||
|
private static void validateHeaderName(String name) {
|
||||||
|
if (name == null) {
|
||||||
|
throw new NullPointerException("name");
|
||||||
|
}
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"name cannot be length zero");
|
||||||
|
}
|
||||||
|
// Since name may only contain ascii characters, for valid names
|
||||||
|
// name.length() returns the number of bytes when UTF-8 encoded.
|
||||||
|
if (name.length() > MAX_VALUE_LENGTH) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"name exceeds allowable length: " + name);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < name.length(); i ++) {
|
||||||
|
char c = name.charAt(i);
|
||||||
|
if (c == 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"name contains null character: " + name);
|
||||||
|
}
|
||||||
|
if (c > 127) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"name contains non-ascii character: " + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int hash(String name) {
|
private static int hash(String name) {
|
||||||
@ -393,52 +439,6 @@ public final class DefaultHttp2Headers extends Http2Headers {
|
|||||||
return hash % BUCKET_SIZE;
|
return hash % BUCKET_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate a HTTP2 header name.
|
|
||||||
*/
|
|
||||||
private static void validateHeaderName(String name) {
|
|
||||||
if (name == null) {
|
|
||||||
throw new NullPointerException("name");
|
|
||||||
}
|
|
||||||
if (name.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"name cannot be length zero");
|
|
||||||
}
|
|
||||||
// Since name may only contain ascii characters, for valid names
|
|
||||||
// name.length() returns the number of bytes when UTF-8 encoded.
|
|
||||||
if (name.length() > MAX_VALUE_LENGTH) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"name exceeds allowable length: " + name);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < name.length(); i ++) {
|
|
||||||
char c = name.charAt(i);
|
|
||||||
if (c == 0) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"name contains null character: " + name);
|
|
||||||
}
|
|
||||||
if (c > 127) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"name contains non-ascii character: " + name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate a HTTP2 header value. Does not validate max length.
|
|
||||||
*/
|
|
||||||
private static void validateHeaderValue(String value) {
|
|
||||||
if (value == null) {
|
|
||||||
throw new NullPointerException("value");
|
|
||||||
}
|
|
||||||
for (int i = 0; i < value.length(); i ++) {
|
|
||||||
char c = value.charAt(i);
|
|
||||||
if (c == 0) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"value contains null character: " + value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class HeaderIterator implements Iterator<Map.Entry<String, String>> {
|
private final class HeaderIterator implements Iterator<Map.Entry<String, String>> {
|
||||||
|
|
||||||
private HeaderEntry current = head;
|
private HeaderEntry current = head;
|
||||||
|
@ -98,12 +98,12 @@ public abstract class Http2Headers implements Iterable<Entry<String, String>> {
|
|||||||
|
|
||||||
private final String value;
|
private final String value;
|
||||||
|
|
||||||
private HttpName(String value) {
|
HttpName(String value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String value() {
|
public String value() {
|
||||||
return this.value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,9 @@ public class DefaultInboundFlowController implements InboundFlowController {
|
|||||||
private final Map<Integer, StreamWindow> streamWindows = new HashMap<Integer, StreamWindow>();
|
private final Map<Integer, StreamWindow> streamWindows = new HashMap<Integer, StreamWindow>();
|
||||||
|
|
||||||
public DefaultInboundFlowController(Http2Connection connection) {
|
public DefaultInboundFlowController(Http2Connection connection) {
|
||||||
|
if (connection == null) {
|
||||||
|
throw new NullPointerException("connecton");
|
||||||
|
}
|
||||||
connection.addListener(new Http2Connection.Listener() {
|
connection.addListener(new Http2Connection.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void streamCreated(int streamId) {
|
public void streamCreated(int streamId) {
|
||||||
|
@ -42,6 +42,9 @@ public class DefaultOutboundFlowController implements OutboundFlowController {
|
|||||||
private int connectionWindowSize = DEFAULT_FLOW_CONTROL_WINDOW_SIZE;
|
private int connectionWindowSize = DEFAULT_FLOW_CONTROL_WINDOW_SIZE;
|
||||||
|
|
||||||
public DefaultOutboundFlowController(Http2Connection connection) {
|
public DefaultOutboundFlowController(Http2Connection connection) {
|
||||||
|
if (connection == null) {
|
||||||
|
throw new NullPointerException("connection");
|
||||||
|
}
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
connection.addListener(new Http2Connection.Listener() {
|
connection.addListener(new Http2Connection.Listener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -65,6 +65,15 @@ public class Http2ConnectionHandler extends ChannelHandlerAdapter {
|
|||||||
|
|
||||||
public Http2ConnectionHandler(final Http2Connection connection,
|
public Http2ConnectionHandler(final Http2Connection connection,
|
||||||
final InboundFlowController inboundFlow, final OutboundFlowController outboundFlow) {
|
final InboundFlowController inboundFlow, final OutboundFlowController outboundFlow) {
|
||||||
|
if (connection == null) {
|
||||||
|
throw new NullPointerException("connection");
|
||||||
|
}
|
||||||
|
if (inboundFlow == null) {
|
||||||
|
throw new NullPointerException("inboundFlow");
|
||||||
|
}
|
||||||
|
if (outboundFlow == null) {
|
||||||
|
throw new NullPointerException("outboundFlow");
|
||||||
|
}
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.inboundFlow = inboundFlow;
|
this.inboundFlow = inboundFlow;
|
||||||
this.outboundFlow = outboundFlow;
|
this.outboundFlow = outboundFlow;
|
||||||
|
@ -22,6 +22,7 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.http2.draft10.Http2Exception;
|
import io.netty.handler.codec.http2.draft10.Http2Exception;
|
||||||
|
import io.netty.util.CharsetUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constants and utility method used for encoding/decoding HTTP2 frames.
|
* Constants and utility method used for encoding/decoding HTTP2 frames.
|
||||||
@ -51,7 +52,7 @@ public final class Http2ConnectionUtil {
|
|||||||
ByteBuf debugData = Unpooled.EMPTY_BUFFER;
|
ByteBuf debugData = Unpooled.EMPTY_BUFFER;
|
||||||
if (cause != null) {
|
if (cause != null) {
|
||||||
// Create the debug message.
|
// Create the debug message.
|
||||||
byte[] msg = cause.getMessage().getBytes();
|
byte[] msg = cause.getMessage().getBytes(CharsetUtil.UTF_8);
|
||||||
debugData = ctx.alloc().buffer(msg.length);
|
debugData = ctx.alloc().buffer(msg.length);
|
||||||
debugData.writeBytes(msg);
|
debugData.writeBytes(msg);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ public abstract class AbstractHttp2FrameUnmarshaller implements Http2FrameUnmars
|
|||||||
@Override
|
@Override
|
||||||
public final Http2FrameUnmarshaller unmarshall(Http2FrameHeader header) throws Http2Exception {
|
public final Http2FrameUnmarshaller unmarshall(Http2FrameHeader header) throws Http2Exception {
|
||||||
if (header == null) {
|
if (header == null) {
|
||||||
throw new IllegalArgumentException("header must be non-null.");
|
throw new NullPointerException("header");
|
||||||
}
|
}
|
||||||
|
|
||||||
validate(header);
|
validate(header);
|
||||||
|
@ -54,6 +54,9 @@ public class Http2FrameDecoder extends ByteToMessageDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Http2FrameDecoder(Http2FrameUnmarshaller frameUnmarshaller) {
|
public Http2FrameDecoder(Http2FrameUnmarshaller frameUnmarshaller) {
|
||||||
|
if (frameUnmarshaller == null) {
|
||||||
|
throw new NullPointerException("frameUnmarshaller");
|
||||||
|
}
|
||||||
this.frameUnmarshaller = frameUnmarshaller;
|
this.frameUnmarshaller = frameUnmarshaller;
|
||||||
state = State.FRAME_HEADER;
|
state = State.FRAME_HEADER;
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ public class Http2HeadersFrameUnmarshaller extends AbstractHeadersUnmarshaller {
|
|||||||
|
|
||||||
public Http2HeadersFrameUnmarshaller(Http2HeadersDecoder headersDecoder) {
|
public Http2HeadersFrameUnmarshaller(Http2HeadersDecoder headersDecoder) {
|
||||||
if (headersDecoder == null) {
|
if (headersDecoder == null) {
|
||||||
throw new IllegalArgumentException("headersDecoder must not be null.");
|
throw new NullPointerException("headersDecoder");
|
||||||
}
|
}
|
||||||
this.headersDecoder = headersDecoder;
|
this.headersDecoder = headersDecoder;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ public class Http2PushPromiseFrameUnmarshaller extends AbstractHeadersUnmarshall
|
|||||||
|
|
||||||
public Http2PushPromiseFrameUnmarshaller(Http2HeadersDecoder headersDecoder) {
|
public Http2PushPromiseFrameUnmarshaller(Http2HeadersDecoder headersDecoder) {
|
||||||
if (headersDecoder == null) {
|
if (headersDecoder == null) {
|
||||||
throw new IllegalArgumentException("headersDecoder must not be null.");
|
throw new NullPointerException("headersDecoder");
|
||||||
}
|
}
|
||||||
this.headersDecoder = headersDecoder;
|
this.headersDecoder = headersDecoder;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ public abstract class AbstractHttp2FrameMarshaller<T extends Http2Frame> impleme
|
|||||||
|
|
||||||
protected AbstractHttp2FrameMarshaller(Class<T> frameType) {
|
protected AbstractHttp2FrameMarshaller(Class<T> frameType) {
|
||||||
if (frameType == null) {
|
if (frameType == null) {
|
||||||
throw new IllegalArgumentException("frameType must be non-null.");
|
throw new NullPointerException("frameType");
|
||||||
}
|
}
|
||||||
this.frameType = frameType;
|
this.frameType = frameType;
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ public abstract class AbstractHttp2FrameMarshaller<T extends Http2Frame> impleme
|
|||||||
public final void marshall(Http2Frame frame, ByteBuf out, ByteBufAllocator alloc)
|
public final void marshall(Http2Frame frame, ByteBuf out, ByteBufAllocator alloc)
|
||||||
throws Http2Exception {
|
throws Http2Exception {
|
||||||
if (frame == null) {
|
if (frame == null) {
|
||||||
throw new IllegalArgumentException("frame must be non-null.");
|
throw new NullPointerException("frame");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!frameType.isAssignableFrom(frame.getClass())) {
|
if (!frameType.isAssignableFrom(frame.getClass())) {
|
||||||
|
@ -36,6 +36,9 @@ public class Http2FrameEncoder extends MessageToByteEncoder<Http2Frame> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Http2FrameEncoder(Http2FrameMarshaller frameMarshaller) {
|
public Http2FrameEncoder(Http2FrameMarshaller frameMarshaller) {
|
||||||
|
if (frameMarshaller == null) {
|
||||||
|
throw new NullPointerException("frameMarshaller");
|
||||||
|
}
|
||||||
this.frameMarshaller = frameMarshaller;
|
this.frameMarshaller = frameMarshaller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ public class Http2HeadersFrameMarshaller extends AbstractHttp2FrameMarshaller<Ht
|
|||||||
public Http2HeadersFrameMarshaller(Http2HeadersEncoder headersEncoder) {
|
public Http2HeadersFrameMarshaller(Http2HeadersEncoder headersEncoder) {
|
||||||
super(Http2HeadersFrame.class);
|
super(Http2HeadersFrame.class);
|
||||||
if (headersEncoder == null) {
|
if (headersEncoder == null) {
|
||||||
throw new NullPointerException("headersEncoder must not be null.");
|
throw new NullPointerException("headersEncoder");
|
||||||
}
|
}
|
||||||
this.headersEncoder = headersEncoder;
|
this.headersEncoder = headersEncoder;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ public class Http2PushPromiseFrameMarshaller extends
|
|||||||
public Http2PushPromiseFrameMarshaller(Http2HeadersEncoder headersEncoder) {
|
public Http2PushPromiseFrameMarshaller(Http2HeadersEncoder headersEncoder) {
|
||||||
super(Http2PushPromiseFrame.class);
|
super(Http2PushPromiseFrame.class);
|
||||||
if (headersEncoder == null) {
|
if (headersEncoder == null) {
|
||||||
throw new NullPointerException("headersEncoder must not be null.");
|
throw new NullPointerException("headersEncoder");
|
||||||
}
|
}
|
||||||
this.headersEncoder = headersEncoder;
|
this.headersEncoder = headersEncoder;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ public class Http2StandardFrameMarshaller implements Http2FrameMarshaller {
|
|||||||
Http2FrameMarshaller marshaller = null;
|
Http2FrameMarshaller marshaller = null;
|
||||||
|
|
||||||
if (frame == null) {
|
if (frame == null) {
|
||||||
throw new IllegalArgumentException("frame must be non-null");
|
throw new NullPointerException("frame");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame instanceof Http2DataFrame) {
|
if (frame instanceof Http2DataFrame) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user