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;
public class TestRequestBody {
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 testBody() {
HttpRequest request = createPostRequestWithBody();
byte[] expected = request.getBody().createByteArray();
byte[] data = unwrap(parser.marshalToByteBuffer(request));
DataWrapper wrap1 = dataGen.wrapByteArray(data);
Memento memento = parser.prepareToParse();
memento = parser.parse(memento, wrap1);
Assert.assertEquals(1, memento.getParsedMessages().size());
HttpPayload msg = memento.getParsedMessages().get(0);
DataWrapper body = msg.getBody();
byte[] bodyBytesActual = body.createByteArray();
Assert.assertArrayEquals(expected, bodyBytesActual);
}
@Test
public void testPartialBody() {
HttpRequest request = createPostRequestWithBody();
byte[] expected = request.getBody().createByteArray();
byte[] data = unwrap(parser.marshalToByteBuffer(request));
byte[] first = new byte[data.length - 20];
byte[] second = new byte[data.length - first.length];
System.arraycopy(data, 0, first, 0, first.length);
System.arraycopy(data, first.length, second, 0, second.length);
DataWrapper wrap1 = dataGen.wrapByteArray(first);
DataWrapper wrap2 = dataGen.wrapByteArray(second);
Memento memento = parser.prepareToParse();
memento = parser.parse(memento, wrap1);
Assert.assertEquals(ParsingState.BODY, memento.getUnParsedState().getCurrentlyParsing());
Assert.assertEquals(10, memento.getUnParsedState().getCurrentUnparsedSize());
HttpPayload payload = memento.getHalfParsedMessage();
HttpRequest httpRequest = payload.getHttpRequest();
Header header = httpRequest.getHeaderLookupStruct().getHeader(KnownHeaderName.CONTENT_LENGTH);
Assert.assertEquals("30", header.getValue());
Assert.assertEquals(0, memento.getParsedMessages().size());
memento = parser.parse(memento, wrap2);
Assert.assertEquals(1, memento.getParsedMessages().size());
HttpPayload msg = memento.getParsedMessages().get(0);
DataWrapper body = msg.getBody();
byte[] bodyBytesActual = body.createByteArray();
Assert.assertArrayEquals(expected, bodyBytesActual);
}
@Test
public void testPartialBodyThenHalfBodyWithNextHttpMsg() {
HttpRequest request = createPostRequestWithBody();
byte[] expected = request.getBody().createByteArray();
byte[] data = unwrap(parser.marshalToByteBuffer(request));
HttpRequest request2 = TestRequestParsing.createPostRequest();
byte[] payload = unwrap(parser.marshalToByteBuffer(request2));
byte[] first = new byte[data.length - 20];
byte[] second = new byte[data.length - first.length + payload.length];
System.arraycopy(data, 0, first, 0, first.length);
int lenOfLastPiece = data.length - first.length;
System.arraycopy(data, first.length, second, 0, lenOfLastPiece);
System.arraycopy(payload, 0, second, lenOfLastPiece, payload.length);
DataWrapper wrap1 = dataGen.wrapByteArray(first);
DataWrapper wrap2 = dataGen.wrapByteArray(second);
Memento memento = parser.prepareToParse();
memento = parser.parse(memento, wrap1);
Assert.assertEquals(0, memento.getParsedMessages().size());
memento = parser.parse(memento, wrap2);
Assert.assertEquals(2, memento.getParsedMessages().size());
HttpPayload msg = memento.getParsedMessages().get(0);
DataWrapper body = msg.getBody();
byte[] bodyBytesActual = body.createByteArray();
Assert.assertArrayEquals(expected, bodyBytesActual);
}
@Test
public void testPartialHeaders() {
HttpRequest request = createPostRequestWithBody();
byte[] expected = request.getBody().createByteArray();
byte[] data = unwrap(parser.marshalToByteBuffer(request));
byte[] first = new byte[20];
byte[] second = new byte[10];
byte[] third = new byte[data.length - first.length - second.length];
System.arraycopy(data, 0, first, 0, first.length);
System.arraycopy(data, first.length, second, 0, second.length);
System.arraycopy(data, first.length+second.length, third, 0, third.length);
DataWrapper wrap1 = dataGen.wrapByteArray(first);
DataWrapper wrap2 = dataGen.wrapByteArray(second);
DataWrapper wrap3 = dataGen.wrapByteArray(third);
Memento memento = parser.prepareToParse();
memento = parser.parse(memento, wrap1);
Assert.assertEquals(ParsingState.HEADERS, memento.getUnParsedState().getCurrentlyParsing());
Assert.assertEquals(20, memento.getUnParsedState().getCurrentUnparsedSize());
memento = parser.parse(memento, wrap2);
Assert.assertEquals(ParsingState.HEADERS, memento.getUnParsedState().getCurrentlyParsing());
Assert.assertEquals(30, memento.getUnParsedState().getCurrentUnparsedSize());
Assert.assertEquals(0, memento.getParsedMessages().size());
memento = parser.parse(memento, wrap3);
Assert.assertEquals(1, memento.getParsedMessages().size());
HttpPayload msg = memento.getParsedMessages().get(0);
DataWrapper body = msg.getBody();
byte[] bodyBytesActual = body.createByteArray();
Assert.assertArrayEquals(expected, bodyBytesActual);
}
private HttpRequest createPostRequestWithBody() {
byte[] payload = new byte[30];
for(int i = 0; i < payload.length; i++) {
payload[i] = (byte) i;
}
HttpRequest request = TestRequestParsing.createPostRequest();
Header header = new Header();
header.setName(KnownHeaderName.CONTENT_LENGTH);
header.setValue(""+payload.length);
DataWrapper data = dataGen.wrapByteArray(payload);
request.addHeader(header);
request.setBody(data);
return request;
}
}