Added test for multi header, HttpObjectDecoder performance improvement for multi header, removed empty else block.

Motivation:

For multi-line headers HttpObjectDecoder uses StringBuilder.append(a).append(b) pattern that could be easily replaced with regular a + b. Also oparations with a and b moved out from concat operation to make it friendly for StringOptimizeConcat optimization and thus - faster.

Modification:

StringBuilder.append(a).append(b) reaplced with a + b. Operations with a and b moved out from concat oparation.

Result:
Code simpler to read and faster.
This commit is contained in:
Dmitriy Dumanskiy 2017-06-14 21:15:58 +03:00 committed by Norman Maurer
parent 82a43727c3
commit 81f9434ec7
2 changed files with 32 additions and 13 deletions

View File

@ -574,12 +574,11 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
do {
char firstChar = line.charAt(0);
if (name != null && (firstChar == ' ' || firstChar == '\t')) {
//please do not make one line from below code
//as it breaks +XX:OptimizeStringConcat optimization
String trimmedLine = line.toString().trim();
StringBuilder buf = new StringBuilder(value.length() + trimmedLine.length() + 1);
buf.append(value)
.append(' ')
.append(trimmedLine);
value = buf.toString();
String valueStr = String.valueOf(value);
value = valueStr + ' ' + trimmedLine;
} else {
if (name != null) {
headers.add(name, value);
@ -641,14 +640,11 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
List<String> current = trailer.trailingHeaders().getAll(lastHeader);
if (!current.isEmpty()) {
int lastPos = current.size() - 1;
//please do not make one line from below code
//as it breaks +XX:OptimizeStringConcat optimization
String lineTrimmed = line.toString().trim();
CharSequence currentLastPos = current.get(lastPos);
StringBuilder b = new StringBuilder(currentLastPos.length() + lineTrimmed.length());
b.append(currentLastPos)
.append(lineTrimmed);
current.set(lastPos, b.toString());
} else {
// Content-Length, Transfer-Encoding, or Trailer
String currentLastPos = current.get(lastPos);
current.set(lastPos, currentLastPos + lineTrimmed);
}
} else {
splitHeader(line);

View File

@ -174,6 +174,29 @@ public class HttpRequestDecoderTest {
assertNull(channel.readInbound());
}
@Test
public void testMultiLineHeader() {
EmbeddedChannel channel = new EmbeddedChannel(new HttpRequestDecoder());
String crlf = "\r\n";
String request = "GET /some/path HTTP/1.1" + crlf +
"Host: localhost" + crlf +
"MyTestHeader: part1" + crlf +
" newLinePart2" + crlf +
"MyTestHeader2: part21" + crlf +
"\t newLinePart22"
+ crlf + crlf;
assertTrue(channel.writeInbound(Unpooled.copiedBuffer(request, CharsetUtil.US_ASCII)));
HttpRequest req = channel.readInbound();
assertEquals("part1 newLinePart2", req.headers().get(of("MyTestHeader")));
assertEquals("part21 newLinePart22", req.headers().get(of("MyTestHeader2")));
LastHttpContent c = channel.readInbound();
c.release();
assertFalse(channel.finish());
assertNull(channel.readInbound());
}
@Test
public void testEmptyHeaderValue() {
EmbeddedChannel channel = new EmbeddedChannel(new HttpRequestDecoder());
@ -181,7 +204,7 @@ public class HttpRequestDecoderTest {
String request = "GET /some/path HTTP/1.1" + crlf +
"Host: localhost" + crlf +
"EmptyHeader:" + crlf + crlf;
channel.writeInbound(Unpooled.wrappedBuffer(request.getBytes(CharsetUtil.US_ASCII)));
channel.writeInbound(Unpooled.copiedBuffer(request, CharsetUtil.US_ASCII));
HttpRequest req = channel.readInbound();
assertEquals("", req.headers().get(of("EmptyHeader")));
}