package test.codec.http2.encode;
import com.firefly.codec.http2.encode.HttpGenerator;
import com.firefly.codec.http2.model.HttpFields;
import com.firefly.codec.http2.model.HttpURI;
import com.firefly.codec.http2.model.HttpVersion;
import com.firefly.codec.http2.model.MetaData;
import com.firefly.utils.io.BufferUtils;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
import java.nio.ByteBuffer;
import static org.junit.Assert.assertEquals;
public class HttpGeneratorClientTest {
public final static String[] connect = {null, "keep-alive", "close"};
class Info extends MetaData.Request {
Info(String method, String uri) {
super(method, new HttpURI(uri), HttpVersion.HTTP_1_1, new HttpFields(), -1);
}
public Info(String method, String uri, int contentLength) {
super(method, new HttpURI(uri), HttpVersion.HTTP_1_1, new HttpFields(), contentLength);
}
}
@Test
public void testGETRequestNoContent() throws Exception {
ByteBuffer header = BufferUtils.allocate(2048);
HttpGenerator gen = new HttpGenerator();
HttpGenerator.Result
result = gen.generateRequest(null, null, null, null, true);
Assert.assertEquals(HttpGenerator.Result.NEED_INFO, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
Info info = new Info("GET", "/index.html");
info.getFields().add("Host", "something");
info.getFields().add("User-Agent", "test");
Assert.assertTrue(!gen.isChunking());
result = gen.generateRequest(info, null, null, null, true);
Assert.assertEquals(HttpGenerator.Result.NEED_HEADER, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
result = gen.generateRequest(info, header, null, null, true);
Assert.assertEquals(HttpGenerator.Result.FLUSH, result);
Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
Assert.assertTrue(!gen.isChunking());
String out = BufferUtils.toString(header);
BufferUtils.clear(header);
result = gen.generateResponse(null, false, null, null, null, false);
Assert.assertEquals(HttpGenerator.Result.DONE, result);
Assert.assertEquals(HttpGenerator.State.END, gen.getState());
Assert.assertTrue(!gen.isChunking());
Assert.assertEquals(0, gen.getContentPrepared());
Assert.assertThat(out, Matchers.containsString("GET /index.html HTTP/1.1"));
Assert.assertThat(out, Matchers.not(Matchers.containsString("Content-Length")));
}
@Test
public void testPOSTRequestNoContent() throws Exception {
ByteBuffer header = BufferUtils.allocate(2048);
HttpGenerator gen = new HttpGenerator();
HttpGenerator.Result
result = gen.generateRequest(null, null, null, null, true);
Assert.assertEquals(HttpGenerator.Result.NEED_INFO, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
Info info = new Info("POST", "/index.html");
info.getFields().add("Host", "something");
info.getFields().add("User-Agent", "test");
Assert.assertTrue(!gen.isChunking());
result = gen.generateRequest(info, null, null, null, true);
Assert.assertEquals(HttpGenerator.Result.NEED_HEADER, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
result = gen.generateRequest(info, header, null, null, true);
Assert.assertEquals(HttpGenerator.Result.FLUSH, result);
Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
Assert.assertTrue(!gen.isChunking());
String out = BufferUtils.toString(header);
BufferUtils.clear(header);
result = gen.generateResponse(null, false, null, null, null, false);
Assert.assertEquals(HttpGenerator.Result.DONE, result);
Assert.assertEquals(HttpGenerator.State.END, gen.getState());
Assert.assertTrue(!gen.isChunking());
Assert.assertEquals(0, gen.getContentPrepared());
Assert.assertThat(out, Matchers.containsString("POST /index.html HTTP/1.1"));
Assert.assertThat(out, Matchers.containsString("Content-Length: 0"));
}
@Test
public void testRequestWithContent() throws Exception {
String out;
ByteBuffer header = BufferUtils.allocate(4096);
ByteBuffer content0 = BufferUtils.toBuffer("Hello World. The quick brown fox jumped over the lazy dog.");
HttpGenerator gen = new HttpGenerator();
HttpGenerator.Result
result = gen.generateRequest(null, null, null, content0, true);
Assert.assertEquals(HttpGenerator.Result.NEED_INFO, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
Info info = new Info("POST", "/index.html");
info.getFields().add("Host", "something");
info.getFields().add("User-Agent", "test");
result = gen.generateRequest(info, null, null, content0, true);
Assert.assertEquals(HttpGenerator.Result.NEED_HEADER, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
result = gen.generateRequest(info, header, null, content0, true);
Assert.assertEquals(HttpGenerator.Result.FLUSH, result);
Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
Assert.assertTrue(!gen.isChunking());
out = BufferUtils.toString(header);
BufferUtils.clear(header);
out += BufferUtils.toString(content0);
BufferUtils.clear(content0);
result = gen.generateResponse(null, false, null, null, null, false);
Assert.assertEquals(HttpGenerator.Result.DONE, result);
Assert.assertEquals(HttpGenerator.State.END, gen.getState());
Assert.assertTrue(!gen.isChunking());
Assert.assertThat(out, Matchers.containsString("POST /index.html HTTP/1.1"));
Assert.assertThat(out, Matchers.containsString("Host: something"));
Assert.assertThat(out, Matchers.containsString("Content-Length: 58"));
Assert.assertThat(out, Matchers.containsString("Hello World. The quick brown fox jumped over the lazy dog."));
Assert.assertEquals(58, gen.getContentPrepared());
}
@Test
public void testRequestWithChunkedContent() throws Exception {
String out;
ByteBuffer header = BufferUtils.allocate(4096);
ByteBuffer chunk = BufferUtils.allocate(HttpGenerator.CHUNK_SIZE);
ByteBuffer content0 = BufferUtils.toBuffer("Hello World. ");
ByteBuffer content1 = BufferUtils.toBuffer("The quick brown fox jumped over the lazy dog.");
HttpGenerator gen = new HttpGenerator();
HttpGenerator.Result result = gen.generateRequest(null, null, null, content0, false);
Assert.assertEquals(HttpGenerator.Result.NEED_INFO, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
Info info = new Info("POST", "/index.html");
info.getFields().add("Host", "something");
info.getFields().add("User-Agent", "test");
result = gen.generateRequest(info, null, null, content0, false);
Assert.assertEquals(HttpGenerator.Result.NEED_HEADER, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
result = gen.generateRequest(info, header, null, content0, false);
Assert.assertEquals(HttpGenerator.Result.FLUSH, result);
Assert.assertEquals(HttpGenerator.State.COMMITTED, gen.getState());
Assert.assertTrue(gen.isChunking());
out = BufferUtils.toString(header);
BufferUtils.clear(header);
out += BufferUtils.toString(content0);
BufferUtils.clear(content0);
result = gen.generateRequest(null, header, null, content1, false);
Assert.assertEquals(HttpGenerator.Result.NEED_CHUNK, result);
Assert.assertEquals(HttpGenerator.State.COMMITTED, gen.getState());
result = gen.generateRequest(null, null, chunk, content1, false);
Assert.assertEquals(HttpGenerator.Result.FLUSH, result);
Assert.assertEquals(HttpGenerator.State.COMMITTED, gen.getState());
Assert.assertTrue(gen.isChunking());
out += BufferUtils.toString(chunk);
BufferUtils.clear(chunk);
out += BufferUtils.toString(content1);
BufferUtils.clear(content1);
result = gen.generateResponse(null, false, null, null, null, true);
Assert.assertEquals(HttpGenerator.Result.CONTINUE, result);
Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
Assert.assertTrue(gen.isChunking());
result = gen.generateResponse(null, false, null, null, null, true);
Assert.assertEquals(HttpGenerator.Result.NEED_CHUNK, result);
Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
Assert.assertTrue(gen.isChunking());
result = gen.generateResponse(null, false, null, chunk, null, true);
Assert.assertEquals(HttpGenerator.Result.FLUSH, result);
Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
out += BufferUtils.toString(chunk);
BufferUtils.clear(chunk);
Assert.assertTrue(!gen.isChunking());
result = gen.generateResponse(null, false, null, chunk, null, true);
Assert.assertEquals(HttpGenerator.Result.DONE, result);
Assert.assertEquals(HttpGenerator.State.END, gen.getState());
Assert.assertThat(out, Matchers.containsString("POST /index.html HTTP/1.1"));
Assert.assertThat(out, Matchers.containsString("Host: something"));
Assert.assertThat(out, Matchers.containsString("Transfer-Encoding: chunked"));
Assert.assertThat(out, Matchers.containsString("\r\nD\r\nHello World. \r\n"));
Assert.assertThat(out, Matchers.containsString("\r\n2D\r\nThe quick brown fox jumped over the lazy dog.\r\n"));
Assert.assertThat(out, Matchers.containsString("\r\n0\r\n\r\n"));
Assert.assertEquals(58, gen.getContentPrepared());
}
@Test
public void testTrailer() throws Exception {
String out;
ByteBuffer header = BufferUtils.allocate(4096);
ByteBuffer chunk = BufferUtils.allocate(HttpGenerator.CHUNK_SIZE);
ByteBuffer trailer = BufferUtils.allocate(4096);
ByteBuffer content0 = BufferUtils.toBuffer("Hello World. ");
ByteBuffer content1 = BufferUtils.toBuffer("The quick brown fox jumped over the lazy dog.");
HttpGenerator gen = new HttpGenerator();
Info info = new Info("POST", "/index.html");
info.getFields().add("Host", "something");
info.getFields().add("User-Agent", "test");
info.setTrailerSupplier(() -> {
HttpFields t = new HttpFields();
t.add("Foo", "1");
t.add("Bar", "bar2");
return t;
});
HttpGenerator.Result result = gen.generateRequest(info, header, null, content0, false);
Assert.assertEquals(HttpGenerator.Result.FLUSH, result);
Assert.assertEquals(HttpGenerator.State.COMMITTED, gen.getState());
Assert.assertTrue(gen.isChunking());
out = BufferUtils.toString(header);
BufferUtils.clear(header);
out += BufferUtils.toString(content0);
BufferUtils.clear(content0);
result = gen.generateRequest(null, null, chunk, content1, false);
Assert.assertEquals(HttpGenerator.Result.FLUSH, result);
Assert.assertEquals(HttpGenerator.State.COMMITTED, gen.getState());
Assert.assertTrue(gen.isChunking());
out += BufferUtils.toString(chunk);
BufferUtils.clear(chunk);
out += BufferUtils.toString(content1);
BufferUtils.clear(content1);
result = gen.generateResponse(null, false, null, null, null, true);
Assert.assertEquals(HttpGenerator.Result.CONTINUE, result);
Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
Assert.assertTrue(gen.isChunking());
result = gen.generateResponse(null, false, null, null, null, true);
Assert.assertEquals(HttpGenerator.Result.NEED_CHUNK_TRAILER, result);
Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
Assert.assertTrue(gen.isChunking());
result = gen.generateResponse(null, false, null, trailer, null, true);
assertEquals(HttpGenerator.Result.FLUSH, result);
assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
out += BufferUtils.toString(trailer);
BufferUtils.clear(trailer);
result = gen.generateResponse(null, false, null, null, null, true);
Assert.assertEquals(HttpGenerator.Result.DONE, result);
Assert.assertEquals(HttpGenerator.State.END, gen.getState());
System.out.println(out);
}
@Test
public void testRequestWithKnownContent() throws Exception {
String out;
ByteBuffer header = BufferUtils.allocate(4096);
ByteBuffer chunk = BufferUtils.allocate(HttpGenerator.CHUNK_SIZE);
ByteBuffer content0 = BufferUtils.toBuffer("Hello World. ");
ByteBuffer content1 = BufferUtils.toBuffer("The quick brown fox jumped over the lazy dog.");
HttpGenerator gen = new HttpGenerator();
HttpGenerator.Result
result = gen.generateRequest(null, null, null, content0, false);
Assert.assertEquals(HttpGenerator.Result.NEED_INFO, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
Info info = new Info("POST", "/index.html", 58);
info.getFields().add("Host", "something");
info.getFields().add("User-Agent", "test");
result = gen.generateRequest(info, null, null, content0, false);
Assert.assertEquals(HttpGenerator.Result.NEED_HEADER, result);
Assert.assertEquals(HttpGenerator.State.START, gen.getState());
result = gen.generateRequest(info, header, null, content0, false);
Assert.assertEquals(HttpGenerator.Result.FLUSH, result);
Assert.assertEquals(HttpGenerator.State.COMMITTED, gen.getState());
Assert.assertTrue(!gen.isChunking());
out = BufferUtils.toString(header);
BufferUtils.clear(header);
out += BufferUtils.toString(content0);
BufferUtils.clear(content0);
result = gen.generateRequest(null, null, null, content1, false);
Assert.assertEquals(HttpGenerator.Result.FLUSH, result);
Assert.assertEquals(HttpGenerator.State.COMMITTED, gen.getState());
Assert.assertTrue(!gen.isChunking());
out += BufferUtils.toString(content1);
BufferUtils.clear(content1);
result = gen.generateResponse(null, false, null, null, null, true);
Assert.assertEquals(HttpGenerator.Result.CONTINUE, result);
Assert.assertEquals(HttpGenerator.State.COMPLETING, gen.getState());
Assert.assertTrue(!gen.isChunking());
result = gen.generateResponse(null, false, null, null, null, true);
Assert.assertEquals(HttpGenerator.Result.DONE, result);
Assert.assertEquals(HttpGenerator.State.END, gen.getState());
out += BufferUtils.toString(chunk);
BufferUtils.clear(chunk);
Assert.assertThat(out, Matchers.containsString("POST /index.html HTTP/1.1"));
Assert.assertThat(out, Matchers.containsString("Host: something"));
Assert.assertThat(out, Matchers.containsString("Content-Length: 58"));
Assert.assertThat(out, Matchers.containsString("\r\n\r\nHello World. The quick brown fox jumped over the lazy dog."));
Assert.assertEquals(58, gen.getContentPrepared());
}
}