package org.deftserver.web.http;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.deftserver.util.ArrayUtil;
import org.deftserver.util.HttpRequestHelper;
import org.deftserver.util.HttpUtil;
import org.deftserver.web.http.HttpRequest;
import org.junit.Assert;
import org.junit.Test;
public class HttpRequestTest {
@Test
public void testDeserializeHttpGetRequest() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.addHeader("Host", "127.0.0.1:8080");
helper.addHeader("User-Agent", "curl/7.19.5 (i386-apple-darwin10.0.0) libcurl/7.19.5 zlib/1.2.3");
helper.addHeader("Accept", "*/*");
ByteBuffer bb1 = helper.getRequestAsByteBuffer();
helper = new HttpRequestHelper();
helper.addHeader("Host", "127.0.0.1:8080");
helper.addHeader("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; sv-SE; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
helper.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
helper.addHeader("Accept-Language", "sv-se,sv;q=0.8,en-us;q=0.5,en;q=0.3");
helper.addHeader("Accept-Encoding", "gzip,deflate");
helper.addHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
helper.addHeader("Keep-Alive", "115");
helper.addHeader("Connection", "keep-alve");
ByteBuffer bb2 = helper.getRequestAsByteBuffer();
HttpRequest request1 = HttpRequest.of(bb1);
HttpRequest request2 = HttpRequest.of(bb2);
assertEquals("GET / HTTP/1.1", request1.getRequestLine());
assertEquals("GET / HTTP/1.1", request2.getRequestLine());
assertEquals(4, request1.getHeaders().size());
assertEquals(9, request2.getHeaders().size());
List<String> expectedHeaderNamesInRequest1 = Arrays.asList(new String[]{"User-Agent", "Host", "Accept", "From"});
for (String expectedHeaderName : expectedHeaderNamesInRequest1) {
assertTrue(request1.getHeaders().containsKey(expectedHeaderName.toLowerCase()));
}
List<String> expectedHeaderNamesInRequest2 = Arrays.asList(new String[]{"Host", "User-Agent", "Accept", "From",
"Accept-Language", "Accept-Encoding", "Accept-Charset", "Keep-Alive", "Connection"});
for (String expectedHeaderName : expectedHeaderNamesInRequest2) {
assertTrue(request2.getHeaders().containsKey(expectedHeaderName.toLowerCase()));
}
// TODO RS 100920 verify that the headers exist
}
public void testRemoveTrailingEmptyStrings() {
String fields1[] = new String[]{"a", "b", "c", "", ""};
String fields2[] = new String[]{"a", "b", "c"};
assertEquals(3, ArrayUtil.dropFromEndWhile(fields1, "").length);
assertEquals(3, ArrayUtil.dropFromEndWhile(fields2, "").length);
}
@Test
public void testSingleGetParameter() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.addGetParameter("firstname", "jim");
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
assertEquals(1, request.getParameters().size());
assertEquals("jim", request.getParameter("firstname"));
}
@Test
public void testMultipleGetParameter() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.addGetParameter("firstname", "jim");
helper.addGetParameter("lastname", "petersson");
helper.addGetParameter("city", "stockholm");
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
Map<String, Collection<String>> params = request.getParameters();
assertEquals(3, getSize(params));
assertEquals("jim", request.getParameter("firstname"));
assertEquals("petersson", request.getParameter("lastname"));
assertEquals("stockholm", request.getParameter("city"));
}
private int getSize(Map<String, Collection<String>> mmap) {
int size = 0;
for (Collection<String> values : mmap.values()) {
size += values.size();
}
return size;
}
@Test
public void testSingleParameterWithoutValue() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.addGetParameter("firstname", null);
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
Map<String, Collection<String>> params = request.getParameters();
assertEquals(0, getSize(params));
assertEquals(null, request.getParameter("firstname"));
}
@Test
public void testMultipleParametersWithoutValue() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.addGetParameter("firstname", null);
helper.addGetParameter("lastName", "");
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
Map<String, Collection<String>> params = request.getParameters();
assertEquals(0, getSize(params));
assertEquals(null, request.getParameter("firstname"));
assertEquals(null, request.getParameter("lastName"));
}
@Test
public void testMultipleParametersWithAndWithoutValue() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.addGetParameter("firstname", null);
helper.addGetParameter("lastName", "petersson");
helper.addGetParameter("city", "");
helper.addGetParameter("phoneno", "12345");
helper.addGetParameter("age", "30");
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
Map<String, Collection<String>> params = request.getParameters();
assertEquals(3, getSize(params));
assertEquals(null, request.getParameter("firstname"));
assertEquals("petersson", request.getParameter("lastName"));
assertEquals(null, request.getParameter("city"));
assertEquals("12345", request.getParameter("phoneno"));
assertEquals("30", request.getParameter("age"));
}
@Test
public void testSingleGetParameterMultipleValues() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.addGetParameter("letters", "x");
helper.addGetParameter("letters", "y");
helper.addGetParameter("letters", "z");
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
Map<String, Collection<String>> params = request.getParameters();
assertEquals(3, getSize(params));
Collection<String> values = params.get("letters");
assertEquals(3, values.size());
assertTrue(values.contains("x"));
assertTrue(values.contains("y"));
assertTrue(values.contains("z"));
}
@Test
public void testMultipleGetParametersMultipleValues() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.addGetParameter("letters", "x");
helper.addGetParameter("letters", "y");
helper.addGetParameter("letters", "z");
helper.addGetParameter("numbers", "23");
helper.addGetParameter("numbers", "54");
helper.addGetParameter("country", "swe");
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
Map<String, Collection<String>> params = request.getParameters();
assertEquals(6, getSize(params));
Collection<String> letters = params.get("letters");
Collection<String> numbers = params.get("numbers");
Collection<String> country = params.get("country");
assertEquals(3, letters.size());
assertEquals(2, numbers.size());
assertEquals(1, country.size());
assertTrue(letters.contains("x"));
assertTrue(letters.contains("y"));
assertTrue(letters.contains("z"));
assertTrue(numbers.contains("23"));
assertTrue(numbers.contains("54"));
assertTrue(country.contains("swe"));
}
@Test
public void testSingleGetParameterMultipleValuesIncludingNull() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.addGetParameter("letters", "x");
helper.addGetParameter("letters", "y");
helper.addGetParameter("letters", null);
helper.addGetParameter("letters", "z");
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
Map<String, Collection<String>> params = request.getParameters();
assertEquals(3, getSize(params));
Collection<String> values = params.get("letters");
assertEquals(3, values.size());
assertTrue(values.contains("x"));
assertTrue(values.contains("y"));
assertTrue(values.contains("z"));
}
@Test
public void testEmptyParameters() {
HttpRequestHelper helper = new HttpRequestHelper();
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
Map<String, Collection<String>> params = request.getParameters();
assertNotNull(params);
assertEquals(0, getSize(params));
}
@Test(expected=UnsupportedOperationException.class)
public void testImmutableParameters() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.addGetParameter("letter", "x");
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
Map<String, Collection<String>> params = request.getParameters();
params.put("not", new ArrayList<String>());
}
@Test
public void testHostVerification_exists_HTTP_1_0() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.setVersion("1.0");
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
boolean requestOk = HttpUtil.verifyRequest(request);
assertTrue(requestOk);
}
@Test
public void testHostVerification_nonExisting_HTTP_1_0() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.setVersion("1.0");
helper.removeHeader("Host");
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
boolean requestOk = HttpUtil.verifyRequest(request);
assertTrue(requestOk);
}
@Test
public void testHostVerification_exists_HTTP_1_1() {
HttpRequestHelper helper = new HttpRequestHelper();
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
boolean requestOk = HttpUtil.verifyRequest(request);
assertTrue(requestOk);
}
@Test
public void testHostVerification_nonExisting_HTTP_1_1() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.removeHeader("Host");
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
boolean requestOk = HttpUtil.verifyRequest(request);
assertFalse(requestOk);
}
@Test
public void testGarbageRequest() {
HttpRequest.of(ByteBuffer.wrap(
new byte[] {1, 1, 1, 1} // garbage
));
}
/**
* Ensure that header keys are converted to lower case, to facilitate
* case-insensitive retrieval through {@link HttpRequest#getHeader(String)}.
*/
@Test
public void testOfConvertsHeaderKeysToLowerCase() {
HttpRequestHelper helper = new HttpRequestHelper();
helper.addHeader("TESTKEY", "unimportant");
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
assertFalse(request.getHeaders().containsKey("TESTKEY"));
assertTrue(request.getHeaders().containsKey("testkey"));
}
/**
* Ensure that the case of any header values is correctly maintained.
*/
@Test
public void testOfMaintainsHeaderValueCase() {
String expected = "vAlUe";
HttpRequestHelper helper = new HttpRequestHelper();
helper.addHeader("TESTKEY", expected);
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
String actual = request.getHeader("TESTKEY");
assertEquals(expected, actual);
}
/**
* Ensure that case for any key passed to the method is unimportant
* for its retrieval.
*/
@Test
public void testGetHeader() {
String expected = "value";
HttpRequestHelper helper = new HttpRequestHelper();
helper.addHeader("TESTKEY", expected);
HttpRequest request = HttpRequest.of(helper.getRequestAsByteBuffer());
assertEquals(expected, request.getHeader("TESTKEY"));
assertEquals(expected, request.getHeader("testkey"));
}
@Test
public void testHttpRequestNoQueryString() {
String requestLine = "GET /foobar HTTP/1.1 ";
HttpRequest request = new HttpRequest(requestLine, new HashMap<String, String>());
Assert.assertEquals("/foobar", request.getRequestedPath());
}
@Test
public void testHttpRequestNullQueryString() {
String requestLine = "GET /foobar? HTTP/1.1 ";
HttpRequest request = new HttpRequest(requestLine, new HashMap<String, String>());
Assert.assertEquals("/foobar", request.getRequestedPath());
}
@Test
public void testHttpRequestNullQueryStringTrailingSlash() {
String requestLine = "GET /foobar/? HTTP/1.1 ";
HttpRequest request = new HttpRequest(requestLine, new HashMap<String, String>());
Assert.assertEquals("/foobar/", request.getRequestedPath());
}
}