Skip to content

Commit

Permalink
Add test cases for HttpContentCompressor
Browse files Browse the repository at this point in the history
- Ported from 386a06d
  • Loading branch information
trustin committed Aug 5, 2014
1 parent 12c614a commit 6ecca27
Showing 1 changed file with 233 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,20 @@
*/
package io.netty.handler.codec.http;

import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.compression.ZlibWrapper;
import io.netty.handler.codec.http.HttpHeaders.Names;
import io.netty.handler.codec.http.HttpHeaders.Values;
import io.netty.util.CharsetUtil;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

public class HttpContentCompressorTest {

@Test
public void testGetTargetContentEncoding() throws Exception {
HttpContentCompressor compressor = new HttpContentCompressor();
Expand Down Expand Up @@ -62,33 +67,250 @@ public void testGetTargetContentEncoding() throws Exception {
}

@Test
public void testEmptyContentCompression() throws Exception {
public void testSplitContent() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());
FullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
req.headers().set(Names.ACCEPT_ENCODING, "deflate");
ch.writeInbound(req);
ch.writeInbound(newRequest());

ch.writeOutbound(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK));
ch.writeOutbound(new DefaultHttpContent(Unpooled.copiedBuffer("Hell", CharsetUtil.US_ASCII)));
ch.writeOutbound(new DefaultHttpContent(Unpooled.copiedBuffer("o, w", CharsetUtil.US_ASCII)));
ch.writeOutbound(new DefaultLastHttpContent(Unpooled.copiedBuffer("orld", CharsetUtil.US_ASCII)));

HttpResponse res = ch.readOutbound();
assertThat(res, is(not(instanceOf(FullHttpResponse.class))));
assertThat(res.headers().get(Names.TRANSFER_ENCODING), is("chunked"));
assertThat(res.headers().get(Names.CONTENT_LENGTH), is(nullValue()));
assertThat(res.headers().get(Names.CONTENT_ENCODING), is("deflate"));
assertEncodedResponse(ch);

ch.writeOutbound(LastHttpContent.EMPTY_LAST_CONTENT);
HttpContent chunk;
chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("1f8b0800000000000000f248cdc901000000ffff"));
chunk.release();

chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("cad7512807000000ffff"));
chunk.release();

chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("ca2fca4901000000ffff"));
chunk.release();

chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("0300c2a99ae70c000000"));
assertThat(chunk, is(instanceOf(HttpContent.class)));
chunk.release();

chunk = ch.readOutbound();
assertThat(chunk.content().isReadable(), is(false));
assertThat(chunk, is(instanceOf(LastHttpContent.class)));
chunk.release();

assertThat(ch.readOutbound(), is(nullValue()));
}

@Test
public void testChunkedContent() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());
ch.writeInbound(newRequest());

HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
res.headers().set(Names.TRANSFER_ENCODING, Values.CHUNKED);
ch.writeOutbound(res);

assertEncodedResponse(ch);

ch.writeOutbound(new DefaultHttpContent(Unpooled.copiedBuffer("Hell", CharsetUtil.US_ASCII)));
ch.writeOutbound(new DefaultHttpContent(Unpooled.copiedBuffer("o, w", CharsetUtil.US_ASCII)));
ch.writeOutbound(new DefaultLastHttpContent(Unpooled.copiedBuffer("orld", CharsetUtil.US_ASCII)));

HttpContent chunk;
chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("1f8b0800000000000000f248cdc901000000ffff"));
chunk.release();

chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("cad7512807000000ffff"));
chunk.release();

chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("ca2fca4901000000ffff"));
chunk.release();

chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("0300c2a99ae70c000000"));
assertThat(chunk, is(instanceOf(HttpContent.class)));
chunk.release();

chunk = ch.readOutbound();
assertThat(chunk.content().isReadable(), is(false));
assertThat(chunk, is(instanceOf(LastHttpContent.class)));
chunk.release();

assertThat(ch.readOutbound(), is(nullValue()));
}

@Test
public void testChunkedContentWithTrailingHeader() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());
ch.writeInbound(newRequest());

HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
res.headers().set(Names.TRANSFER_ENCODING, Values.CHUNKED);
ch.writeOutbound(res);

assertEncodedResponse(ch);

ch.writeOutbound(new DefaultHttpContent(Unpooled.copiedBuffer("Hell", CharsetUtil.US_ASCII)));
ch.writeOutbound(new DefaultHttpContent(Unpooled.copiedBuffer("o, w", CharsetUtil.US_ASCII)));
LastHttpContent content = new DefaultLastHttpContent(Unpooled.copiedBuffer("orld", CharsetUtil.US_ASCII));
content.trailingHeaders().set("X-Test", "Netty");
ch.writeOutbound(content);

HttpContent chunk;
chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("1f8b0800000000000000f248cdc901000000ffff"));
chunk.release();

chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("cad7512807000000ffff"));
chunk.release();

chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("ca2fca4901000000ffff"));
chunk.release();

chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("0300c2a99ae70c000000"));
assertThat(chunk, is(instanceOf(HttpContent.class)));
assertThat(chunk.content().isReadable(), is(true));
chunk.release();

chunk = ch.readOutbound();
assertThat(chunk.content().isReadable(), is(false));
assertThat(chunk, is(instanceOf(LastHttpContent.class)));
assertEquals("Netty", ((LastHttpContent) chunk).trailingHeaders().get("X-Test"));
chunk.release();

assertThat(ch.readOutbound(), is(nullValue()));
}

@Test
public void testFullContent() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());
ch.writeInbound(newRequest());

FullHttpResponse res = new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
Unpooled.copiedBuffer("Hello, World", CharsetUtil.US_ASCII));
res.headers().set(Names.CONTENT_LENGTH, res.content().readableBytes());
ch.writeOutbound(res);

assertEncodedResponse(ch);
HttpContent c = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(c.content()), is("1f8b0800000000000000f248cdc9c9d75108cf2fca4901000000ffff"));
c.release();

c = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(c.content()), is("0300c6865b260c000000"));
c.release();

LastHttpContent last = ch.readOutbound();
assertThat(last.content().readableBytes(), is(0));
last.release();

assertThat(ch.readOutbound(), is(nullValue()));
}

/**
* If the length of the content is unknown, {@link HttpContentEncoder} should not skip encoding the content
* even if the actual length is turned out to be 0.
*/
@Test
public void testEmptySplitContent() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());
ch.writeInbound(newRequest());

ch.writeOutbound(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK));
assertEncodedResponse(ch);

ch.writeOutbound(LastHttpContent.EMPTY_LAST_CONTENT);
HttpContent chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("1f8b0800000000000000"));
chunk.release();

chunk = ch.readOutbound();
assertThat(ByteBufUtil.hexDump(chunk.content()), is("03000000000000000000"));
assertThat(chunk, is(instanceOf(HttpContent.class)));
chunk.release();

chunk = ch.readOutbound();
assertThat(chunk.content().isReadable(), is(false));
assertThat(chunk, is(instanceOf(LastHttpContent.class)));
chunk.release();

assertThat(ch.readOutbound(), is(nullValue()));
}

/**
* If the length of the content is 0 for sure, {@link HttpContentEncoder} should skip encoding.
*/
@Test
public void testEmptyFullContent() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());
ch.writeInbound(newRequest());

FullHttpResponse res = new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.EMPTY_BUFFER);
ch.writeOutbound(res);

Object o = ch.readOutbound();
assertThat(o, is(instanceOf(FullHttpResponse.class)));

res = (FullHttpResponse) o;
assertThat(res.headers().get(Names.TRANSFER_ENCODING), is(nullValue()));

// Content encoding shouldn't be modified.
assertThat(res.headers().get(Names.CONTENT_ENCODING), is(nullValue()));
assertThat(res.content().readableBytes(), is(0));
assertThat(res.content().toString(CharsetUtil.US_ASCII), is(""));
res.release();

assertThat(ch.readOutbound(), is(nullValue()));
}

@Test
public void testEmptyFullContentWithTrailer() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor());
ch.writeInbound(newRequest());

FullHttpResponse res = new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.EMPTY_BUFFER);
res.trailingHeaders().set("X-Test", "Netty");
ch.writeOutbound(res);

Object o = ch.readOutbound();
assertThat(o, is(instanceOf(FullHttpResponse.class)));

res = (FullHttpResponse) o;
assertThat(res.headers().get(Names.TRANSFER_ENCODING), is(nullValue()));

// Content encoding shouldn't be modified.
assertThat(res.headers().get(Names.CONTENT_ENCODING), is(nullValue()));
assertThat(res.content().readableBytes(), is(0));
assertThat(res.content().toString(CharsetUtil.US_ASCII), is(""));
assertEquals("Netty", res.trailingHeaders().get("X-Test"));
assertThat(ch.readOutbound(), is(nullValue()));
}

private static FullHttpRequest newRequest() {
FullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
req.headers().set(Names.ACCEPT_ENCODING, "gzip");
return req;
}

private static void assertEncodedResponse(EmbeddedChannel ch) {
Object o = ch.readOutbound();
assertThat(o, is(instanceOf(HttpResponse.class)));

HttpResponse res = (HttpResponse) o;
assertThat(res, is(not(instanceOf(HttpContent.class))));
assertThat(res.headers().get(Names.TRANSFER_ENCODING), is("chunked"));
assertThat(res.headers().get(Names.CONTENT_LENGTH), is(nullValue()));
assertThat(res.headers().get(Names.CONTENT_ENCODING), is("gzip"));
}
}

0 comments on commit 6ecca27

Please sign in to comment.