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:
parent
074075de7e
commit
0eeeb76439
@ -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,33 +110,43 @@ public abstract class HttpObjectEncoder<H extends HttpMessage> extends MessageTo
|
||||
}
|
||||
out.add(encodeAndRetain(msg));
|
||||
}
|
||||
} else {
|
||||
if (buf != null) {
|
||||
out.add(buf);
|
||||
} else {
|
||||
// Need to produce some output otherwise an
|
||||
// IllegalStateException will be thrown
|
||||
out.add(EMPTY_BUFFER);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (msg instanceof LastHttpContent) {
|
||||
state = ST_INIT;
|
||||
}
|
||||
return;
|
||||
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);
|
||||
return;
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
} else {
|
||||
if (buf != null) {
|
||||
out.add(buf);
|
||||
|
||||
if (msg instanceof LastHttpContent) {
|
||||
state = ST_INIT;
|
||||
}
|
||||
} else if (buf != null) {
|
||||
out.add(buf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,14 +188,10 @@ public abstract class HttpObjectEncoder<H extends HttpMessage> extends MessageTo
|
||||
buf.writeBytes(CRLF);
|
||||
out.add(buf);
|
||||
}
|
||||
|
||||
state = ST_INIT;
|
||||
} else {
|
||||
if (contentLength == 0) {
|
||||
// Need to produce some output otherwise an
|
||||
// IllegalstateException will be thrown
|
||||
out.add(EMPTY_BUFFER);
|
||||
}
|
||||
} else if (contentLength == 0) {
|
||||
// Need to produce some output otherwise an
|
||||
// IllegalstateException will be thrown
|
||||
out.add(EMPTY_BUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user