Fix handling of FullHttpResponse when respond to HEAD in HttpServerCodec

Motivation:

cb139043f3 introduced special handling of response to HEAD requests. Due a bug we failed to handle FullHttpResponse correctly.

Modifications:

Correctly handle FullHttpResponse for HEAD requests.

Result:

Works as expected.
This commit is contained in:
Norman Maurer 2016-12-21 14:35:53 +01:00
parent 074075de7e
commit 0eeeb76439
2 changed files with 55 additions and 29 deletions

View File

@ -97,12 +97,6 @@ public abstract class HttpObjectEncoder<H extends HttpMessage> extends MessageTo
switch (state) {
case ST_INIT:
throw new IllegalStateException("unexpected message type: " + StringUtil.simpleClassName(msg));
case ST_CONTENT_ALWAYS_EMPTY:
out.add(EMPTY_BUFFER);
if (msg instanceof LastHttpContent) {
state = ST_INIT;
}
return;
case ST_CONTENT_NON_CHUNK:
final long contentLength = contentLength(msg);
if (contentLength > 0) {
@ -116,34 +110,44 @@ public abstract class HttpObjectEncoder<H extends HttpMessage> extends MessageTo
}
out.add(encodeAndRetain(msg));
}
} else {
if (msg instanceof LastHttpContent) {
state = ST_INIT;
}
break;
}
// fall-through!
case ST_CONTENT_ALWAYS_EMPTY:
if (buf != null) {
// We allocated a buffer so add it now.
out.add(buf);
} else {
// Need to produce some output otherwise an
// IllegalStateException will be thrown
out.add(EMPTY_BUFFER);
}
break;
case ST_CONTENT_CHUNK:
if (buf != null) {
// We allocated a buffer so add it now.
out.add(buf);
}
encodeChunkedContent(ctx, msg, contentLength(msg), out);
break;
default:
throw new Error();
}
if (msg instanceof LastHttpContent) {
state = ST_INIT;
}
return;
case ST_CONTENT_CHUNK:
if (buf != null) {
} else if (buf != null) {
out.add(buf);
}
encodeChunkedContent(ctx, msg, contentLength(msg), out);
return;
default:
throw new Error();
}
} else {
if (buf != null) {
out.add(buf);
}
}
}
/**
@ -184,16 +188,12 @@ public abstract class HttpObjectEncoder<H extends HttpMessage> extends MessageTo
buf.writeBytes(CRLF);
out.add(buf);
}
state = ST_INIT;
} else {
if (contentLength == 0) {
} else if (contentLength == 0) {
// Need to produce some output otherwise an
// IllegalstateException will be thrown
out.add(EMPTY_BUFFER);
}
}
}
boolean isContentAlwaysEmpty(@SuppressWarnings("unused") H msg) {
return false;

View File

@ -145,6 +145,32 @@ public class HttpServerCodecTest {
assertFalse(ch.finishAndReleaseAll());
}
@Test
public void testChunkedHeadFullHttpResponse() {
EmbeddedChannel ch = new EmbeddedChannel(new HttpServerCodec());
// Send the request headers.
assertTrue(ch.writeInbound(Unpooled.copiedBuffer(
"HEAD / HTTP/1.1\r\n\r\n", CharsetUtil.UTF_8)));
HttpRequest request = ch.readInbound();
assertEquals(HttpMethod.HEAD, request.method());
LastHttpContent content = ch.readInbound();
assertFalse(content.content().isReadable());
content.release();
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
HttpUtil.setTransferEncodingChunked(response, true);
assertTrue(ch.writeOutbound(response));
assertTrue(ch.finish());
ByteBuf buf = ch.readOutbound();
assertEquals("HTTP/1.1 200 OK\r\ntransfer-encoding: chunked\r\n\r\n", buf.toString(CharsetUtil.US_ASCII));
buf.release();
assertFalse(ch.finishAndReleaseAll());
}
private static ByteBuf prepareDataChunk(int size) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < size; ++i) {