codec-http2: Mark requests as chunked in Http2ServerDowngrader

Motivation:

Http2ServerDowngrader doesn't mark chunked requests as chunked, even
though the natural conversion from http/2 requests to http/1.1 requests
is to chunked ones.

Modifications:

Mark requests that aren't already complete as chunked.

Result:

Requests will be chunked, and can later be aggregated if necessary.
This commit is contained in:
Moses Nakamura 2016-09-09 16:54:43 -04:00 committed by Norman Maurer
parent 0b5e75a614
commit da8734a6f9
2 changed files with 33 additions and 2 deletions

View File

@ -24,8 +24,12 @@ import io.netty.handler.codec.http.DefaultLastHttpContent;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.util.ReferenceCountUtil;
@ -78,9 +82,12 @@ public class Http2ServerDowngrader extends MessageToMessageCodec<Http2StreamFram
out.add(full);
}
} else {
out.add(HttpConversionUtil.toHttpRequest(id, headersFrame.headers(), validateHeaders));
HttpRequest req = HttpConversionUtil.toHttpRequest(id, headersFrame.headers(), validateHeaders);
if (!HttpUtil.isContentLengthSet(req)) {
req.headers().add(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED);
}
out.add(req);
}
} else if (frame instanceof Http2DataFrame) {
Http2DataFrame dataFrame = (Http2DataFrame) frame;
if (dataFrame.isEndStream()) {

View File

@ -32,6 +32,7 @@ import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.util.CharsetUtil;
@ -255,6 +256,28 @@ public class Http2ServerDowngraderTest {
assertThat(request.method(), is(HttpMethod.GET));
assertThat(request.protocolVersion(), is(HttpVersion.HTTP_1_1));
assertFalse(request instanceof FullHttpRequest);
assertTrue(HttpUtil.isTransferEncodingChunked(request));
assertThat(ch.readInbound(), is(nullValue()));
assertFalse(ch.finish());
}
@Test
public void testDowngradeHeadersWithContentLength() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new Http2ServerDowngrader());
Http2Headers headers = new DefaultHttp2Headers();
headers.path("/");
headers.method("GET");
headers.setInt("content-length", 0);
assertTrue(ch.writeInbound(new DefaultHttp2HeadersFrame(headers)));
HttpRequest request = ch.readInbound();
assertThat(request.uri(), is("/"));
assertThat(request.method(), is(HttpMethod.GET));
assertThat(request.protocolVersion(), is(HttpVersion.HTTP_1_1));
assertFalse(request instanceof FullHttpRequest);
assertFalse(HttpUtil.isTransferEncodingChunked(request));
assertThat(ch.readInbound(), is(nullValue()));
assertFalse(ch.finish());
@ -276,6 +299,7 @@ public class Http2ServerDowngraderTest {
assertThat(request.protocolVersion(), is(HttpVersion.HTTP_1_1));
assertThat(request.content().readableBytes(), is(0));
assertTrue(request.trailingHeaders().isEmpty());
assertFalse(HttpUtil.isTransferEncodingChunked(request));
} finally {
request.release();
}