From 36c6a61d33c480798511723486459f4eea04cb47 Mon Sep 17 00:00:00 2001 From: Scott Mitchell Date: Wed, 29 Mar 2017 18:54:44 -0700 Subject: [PATCH] HTTP/2 remove unnecessary buffer operations Motivation: codec-http2 has some helper methods to write to ByteBuf in a big endian fashion. This is the default memory structure for ByteBuf so these helper methods are not necessary. Modifications: - remove writeUnsignedInt and writeUnsignedShort Result: codec-http2 has less ByteBuf helper methods which are not necessary. --- .../codec/http2/DefaultHttp2FrameWriter.java | 16 +++++------ .../codec/http2/Http2ClientUpgradeCodec.java | 22 +++++++-------- .../handler/codec/http2/Http2CodecUtil.java | 27 +++---------------- .../http2/DefaultHttp2FrameReaderTest.java | 4 +-- 4 files changed, 22 insertions(+), 47 deletions(-) diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2FrameWriter.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2FrameWriter.java index 24e599d89e..c7aaede303 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2FrameWriter.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2FrameWriter.java @@ -48,8 +48,6 @@ import static io.netty.handler.codec.http2.Http2CodecUtil.WINDOW_UPDATE_FRAME_LE import static io.netty.handler.codec.http2.Http2CodecUtil.isMaxFrameSizeValid; import static io.netty.handler.codec.http2.Http2CodecUtil.verifyPadding; import static io.netty.handler.codec.http2.Http2CodecUtil.writeFrameHeaderInternal; -import static io.netty.handler.codec.http2.Http2CodecUtil.writeUnsignedInt; -import static io.netty.handler.codec.http2.Http2CodecUtil.writeUnsignedShort; import static io.netty.handler.codec.http2.Http2Error.FRAME_SIZE_ERROR; import static io.netty.handler.codec.http2.Http2Exception.connectionError; import static io.netty.handler.codec.http2.Http2FrameTypes.CONTINUATION; @@ -211,8 +209,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize ByteBuf buf = ctx.alloc().buffer(PRIORITY_FRAME_LENGTH); writeFrameHeaderInternal(buf, PRIORITY_ENTRY_LENGTH, PRIORITY, new Http2Flags(), streamId); - long word1 = exclusive ? 0x80000000L | streamDependency : streamDependency; - writeUnsignedInt(word1, buf); + buf.writeInt(exclusive ? (int) (0x80000000L | streamDependency) : streamDependency); // Adjust the weight so that it fits into a single byte on the wire. buf.writeByte(weight - 1); return ctx.write(buf, promise); @@ -230,7 +227,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize ByteBuf buf = ctx.alloc().buffer(RST_STREAM_FRAME_LENGTH); writeFrameHeaderInternal(buf, INT_FIELD_LENGTH, RST_STREAM, new Http2Flags(), streamId); - writeUnsignedInt(errorCode, buf); + buf.writeInt((int) errorCode); return ctx.write(buf, promise); } catch (Throwable t) { return promise.setFailure(t); @@ -246,8 +243,8 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize ByteBuf buf = ctx.alloc().buffer(FRAME_HEADER_LENGTH + settings.size() * SETTING_ENTRY_LENGTH); writeFrameHeaderInternal(buf, payloadLength, SETTINGS, new Http2Flags(), 0); for (Http2Settings.PrimitiveEntry entry : settings.entries()) { - writeUnsignedShort(entry.key(), buf); - writeUnsignedInt(entry.value(), buf); + buf.writeChar(entry.key()); + buf.writeInt(entry.value().intValue()); } return ctx.write(buf, promise); } catch (Throwable t) { @@ -363,7 +360,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize ByteBuf buf = ctx.alloc().buffer(GO_AWAY_FRAME_HEADER_LENGTH); writeFrameHeaderInternal(buf, payloadLength, GO_AWAY, new Http2Flags(), 0); buf.writeInt(lastStreamId); - writeUnsignedInt(errorCode, buf); + buf.writeInt((int) errorCode); ctx.write(buf, promiseAggregator.newPromise()); releaseData = false; @@ -451,8 +448,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize writePaddingLength(buf, padding); if (hasPriority) { - long word1 = exclusive ? 0x80000000L | streamDependency : streamDependency; - writeUnsignedInt(word1, buf); + buf.writeInt(exclusive ? (int) (0x80000000L | streamDependency) : streamDependency); // Adjust the weight so that it fits into a single byte on the wire. buf.writeByte(weight - 1); diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ClientUpgradeCodec.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ClientUpgradeCodec.java index 3794e3eaf4..7b1d52c761 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ClientUpgradeCodec.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ClientUpgradeCodec.java @@ -14,16 +14,6 @@ */ package io.netty.handler.codec.http2; -import static io.netty.handler.codec.base64.Base64Dialect.URL_SAFE; -import static io.netty.handler.codec.http2.Http2CodecUtil.HTTP_UPGRADE_PROTOCOL_NAME; -import static io.netty.handler.codec.http2.Http2CodecUtil.HTTP_UPGRADE_SETTINGS_HEADER; -import static io.netty.handler.codec.http2.Http2CodecUtil.SETTING_ENTRY_LENGTH; -import static io.netty.handler.codec.http2.Http2CodecUtil.writeUnsignedInt; -import static io.netty.handler.codec.http2.Http2CodecUtil.writeUnsignedShort; -import static io.netty.util.CharsetUtil.UTF_8; -import static io.netty.util.ReferenceCountUtil.release; -import static io.netty.util.internal.ObjectUtil.checkNotNull; - import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.base64.Base64; @@ -37,6 +27,14 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import static io.netty.handler.codec.base64.Base64Dialect.URL_SAFE; +import static io.netty.handler.codec.http2.Http2CodecUtil.HTTP_UPGRADE_PROTOCOL_NAME; +import static io.netty.handler.codec.http2.Http2CodecUtil.HTTP_UPGRADE_SETTINGS_HEADER; +import static io.netty.handler.codec.http2.Http2CodecUtil.SETTING_ENTRY_LENGTH; +import static io.netty.util.CharsetUtil.UTF_8; +import static io.netty.util.ReferenceCountUtil.release; +import static io.netty.util.internal.ObjectUtil.checkNotNull; + /** * Client-side cleartext upgrade codec from HTTP to HTTP/2. */ @@ -108,8 +106,8 @@ public class Http2ClientUpgradeCodec implements HttpClientUpgradeHandler.Upgrade int payloadLength = SETTING_ENTRY_LENGTH * settings.size(); buf = ctx.alloc().buffer(payloadLength); for (CharObjectMap.PrimitiveEntry entry : settings.entries()) { - writeUnsignedShort(entry.key(), buf); - writeUnsignedInt(entry.value(), buf); + buf.writeChar(entry.key()); + buf.writeInt(entry.value().intValue()); } // Base64 encode the payload and then convert to a string for the header. diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2CodecUtil.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2CodecUtil.java index 43a3b1e9a0..8d95563b64 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2CodecUtil.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2CodecUtil.java @@ -48,13 +48,13 @@ public final class Http2CodecUtil { public static final CharSequence TLS_UPGRADE_PROTOCOL_NAME = ApplicationProtocolNames.HTTP_2; public static final int PING_FRAME_PAYLOAD_LENGTH = 8; - public static final short MAX_UNSIGNED_BYTE = 0xFF; + public static final short MAX_UNSIGNED_BYTE = 0xff; /** * The maximum number of padding bytes. That is the 255 padding bytes appended to the end of a frame and the 1 byte * pad length field. */ public static final int MAX_PADDING = 256; - public static final long MAX_UNSIGNED_INT = 0xFFFFFFFFL; + public static final long MAX_UNSIGNED_INT = 0xffffffffL; public static final int FRAME_HEADER_LENGTH = 9; public static final int SETTING_ENTRY_LENGTH = 6; public static final int PRIORITY_ENTRY_LENGTH = 5; @@ -93,7 +93,7 @@ public final class Http2CodecUtil { public static final long MAX_CONCURRENT_STREAMS = MAX_UNSIGNED_INT; public static final int MAX_INITIAL_WINDOW_SIZE = Integer.MAX_VALUE; public static final int MAX_FRAME_SIZE_LOWER_BOUND = 0x4000; - public static final int MAX_FRAME_SIZE_UPPER_BOUND = 0xFFFFFF; + public static final int MAX_FRAME_SIZE_UPPER_BOUND = 0xffffff; public static final long MAX_HEADER_LIST_SIZE = MAX_UNSIGNED_INT; public static final long MIN_HEADER_TABLE_SIZE = 0; @@ -202,26 +202,7 @@ public final class Http2CodecUtil { * Reads a big-endian (31-bit) integer from the buffer. */ public static int readUnsignedInt(ByteBuf buf) { - return (buf.readByte() & 0x7F) << 24 | (buf.readByte() & 0xFF) << 16 - | (buf.readByte() & 0xFF) << 8 | buf.readByte() & 0xFF; - } - - /** - * Writes a big-endian (32-bit) unsigned integer to the buffer. - */ - public static void writeUnsignedInt(long value, ByteBuf out) { - out.writeByte((int) (value >> 24 & 0xFF)); - out.writeByte((int) (value >> 16 & 0xFF)); - out.writeByte((int) (value >> 8 & 0xFF)); - out.writeByte((int) (value & 0xFF)); - } - - /** - * Writes a big-endian (16-bit) unsigned integer to the buffer. - */ - public static void writeUnsignedShort(int value, ByteBuf out) { - out.writeByte(value >> 8 & 0xFF); - out.writeByte(value & 0xFF); + return buf.readInt() & 0x7fffffff; } /** diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2FrameReaderTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2FrameReaderTest.java index 3f74ee3130..e1e0e6be82 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2FrameReaderTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2FrameReaderTest.java @@ -367,7 +367,7 @@ public class DefaultHttp2FrameReaderTest { Http2Flags flags, int streamDependency, int weight) throws Http2Exception { ByteBuf headerBlock = Unpooled.buffer(); try { - writeUnsignedInt(streamDependency, headerBlock); + headerBlock.writeInt(streamDependency); headerBlock.writeByte(weight - 1); hpackEncoder.encodeHeaders(streamId, headerBlock, headers, Http2HeadersEncoder.NEVER_SENSITIVE); writeFrameHeader(output, headerBlock.readableBytes(), HEADERS, flags, streamId); @@ -393,7 +393,7 @@ public class DefaultHttp2FrameReaderTest { private void writePriorityFrame( ByteBuf output, int streamId, int streamDependency, int weight) { writeFrameHeader(output, 5, PRIORITY, new Http2Flags(), streamId); - writeUnsignedInt(streamDependency, output); + output.writeInt(streamDependency); output.writeByte(weight - 1); } }