package org.webpieces.httpparser.api;
import java.nio.ByteBuffer;
import org.junit.Assert;
import org.junit.Test;
import org.webpieces.data.api.BufferCreationPool;
import org.webpieces.data.api.DataWrapper;
import org.webpieces.data.api.DataWrapperGenerator;
import org.webpieces.data.api.DataWrapperGeneratorFactory;
import org.webpieces.httpparser.api.common.Header;
import org.webpieces.httpparser.api.common.KnownHeaderName;
import org.webpieces.httpparser.api.dto.HttpPayload;
import org.webpieces.httpparser.api.dto.HttpRequest;
import org.webpieces.httpparser.api.dto.HttpRequestLine;
import org.webpieces.httpparser.api.dto.HttpUri;
import org.webpieces.httpparser.api.dto.KnownHttpMethod;
import org.webpieces.httpparser.impl.ConvertAscii;
public class TestRequestParsing {
private HttpParser parser = HttpParserFactory.createParser(new BufferCreationPool());
private DataWrapperGenerator dataGen = DataWrapperGeneratorFactory.createDataWrapperGenerator();
private byte[] unwrap(ByteBuffer buffer) {
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
return data;
}
@Test
public void testBasic() {
HttpRequestLine requestLine = new HttpRequestLine();
requestLine.setMethod(KnownHttpMethod.POST);
requestLine.setUri(new HttpUri("http://myhost.com"));
HttpRequest request = new HttpRequest();
request.setRequestLine(requestLine);
String result1 = request.toString();
String result2 = parser.marshalToString(request);
String msg = "POST http://myhost.com HTTP/1.1\r\n\r\n";
Assert.assertEquals(msg, result1);
Assert.assertEquals(msg, result2);
}
@Test
public void testAsciiConverter() {
HttpRequest request = createPostRequest();
byte[] payload = unwrap(parser.marshalToByteBuffer(request));
ConvertAscii converter = new ConvertAscii();
String readableForm = converter.convertToReadableForm(payload);
String expected = "POST\\s http://myhost.com\\s HTTP/1.1\\r\\n\r\n"
+ "Accept:\\s CooolValue\\r\\n\r\n"
+ "CustomerHEADER:\\s betterValue\\r\\n\r\n"
+ "\\r\\n\r\n";
Assert.assertEquals(expected, readableForm);
}
@Test
public void testWithHeadersAndBody() {
HttpRequest request = createPostRequest();
String result1 = request.toString();
String result2 = parser.marshalToString(request);
String msg = "POST http://myhost.com HTTP/1.1\r\n"
+ "Accept: CooolValue\r\n"
+ "CustomerHEADER: betterValue\r\n"
+ "\r\n";
Assert.assertEquals(msg, result1);
Assert.assertEquals(msg, result2);
}
@Test
public void testPartialHttpMessage() {
HttpRequest request = createPostRequest();
byte[] payload = unwrap(parser.marshalToByteBuffer(request));
byte[] firstPart = new byte[10];
byte[] secondPart = new byte[payload.length-firstPart.length];
//let's split the payload up into two pieces
System.arraycopy(payload, 0, firstPart, 0, firstPart.length);
System.arraycopy(payload, firstPart.length, secondPart, 0, secondPart.length);
DataWrapper data1 = dataGen.wrapByteArray(firstPart);
DataWrapper data2 = dataGen.wrapByteArray(secondPart);
Memento memento = parser.prepareToParse();
memento = parser.parse(memento, data1);
Assert.assertEquals(0, memento.getParsedMessages().size());
memento = parser.parse(memento, data2);
Assert.assertEquals(1, memento.getParsedMessages().size());
HttpPayload httpMessage = memento.getParsedMessages().get(0);
HttpRequest req = (HttpRequest) httpMessage;
Assert.assertEquals(request.getRequestLine(), req.getRequestLine());
Assert.assertEquals(request.getHeaders(), req.getHeaders());
Assert.assertEquals(request, httpMessage);
}
@Test
public void test2AndHalfHttpMessages() {
HttpRequest request = createPostRequest();
byte[] payload = unwrap(parser.marshalToByteBuffer(request));
byte[] first = new byte[2*payload.length + 20];
byte[] second = new byte[payload.length - 20];
System.arraycopy(payload, 0, first, 0, payload.length);
System.arraycopy(payload, 0, first, payload.length, payload.length);
System.arraycopy(payload, 0, first, 2*payload.length, 20);
System.arraycopy(payload, 20, second, 0, second.length);
DataWrapper data1 = dataGen.wrapByteArray(first);
DataWrapper data2 = dataGen.wrapByteArray(second);
Memento memento = parser.prepareToParse();
memento = parser.parse(memento, data1);
Assert.assertEquals(2, memento.getParsedMessages().size());
memento = parser.parse(memento, data2);
Assert.assertEquals(1, memento.getParsedMessages().size());
}
/**
* Send in 1/2 first http message and then send in
* next 1/2 AND 1/2 of second message TOGETHER in 2nd
* payload of bytes to make sure it is handled correctly
* and then finally last 1/2
*/
@Test
public void testHalfThenTwoHalvesNext() {
HttpRequest request = createPostRequest();
byte[] payload = unwrap(parser.marshalToByteBuffer(request));
byte[] first = new byte[20];
byte[] second = new byte[payload.length];
byte[] third = new byte[payload.length - first.length];
System.arraycopy(payload, 0, first, 0, first.length);
System.arraycopy(payload, first.length, second, 0, payload.length-first.length);
System.arraycopy(payload, 0, second, payload.length-first.length, first.length);
System.arraycopy(payload, first.length, third, 0, third.length);
DataWrapper data1 = dataGen.wrapByteArray(first);
DataWrapper data2 = dataGen.wrapByteArray(second);
DataWrapper data3 = dataGen.wrapByteArray(third);
Memento memento = parser.prepareToParse();
memento = parser.parse(memento, data1);
Assert.assertEquals(0, memento.getParsedMessages().size());
memento = parser.parse(memento, data2);
Assert.assertEquals(1, memento.getParsedMessages().size());
memento = parser.parse(memento, data3);
Assert.assertEquals(1, memento.getParsedMessages().size());
}
static HttpRequest createPostRequest() {
Header header1 = new Header();
header1.setName(KnownHeaderName.ACCEPT);
header1.setValue("CooolValue");
Header header2 = new Header();
//let's keep the case even though name is case-insensitive..
header2.setName("CustomerHEADER");
header2.setValue("betterValue");
HttpRequestLine requestLine = new HttpRequestLine();
requestLine.setMethod(KnownHttpMethod.POST);
requestLine.setUri(new HttpUri("http://myhost.com"));
HttpRequest request = new HttpRequest();
request.setRequestLine(requestLine);
request.addHeader(header1);
request.addHeader(header2);
return request;
}
}