package test.codec.http2.model;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assume.assumeNoException;
import static org.junit.Assume.assumeNotNull;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import com.firefly.codec.http2.model.HttpURI;
@RunWith(Parameterized.class)
public class HttpURIParseTest {
@Parameters(name = "{0}")
public static List<String[]> data() {
String[][] tests = {
// Nothing but path
{ "path", null, null, "-1", "path", null, null, null },
{ "path/path", null, null, "-1", "path/path", null, null, null },
{ "%65ncoded/path", null, null, "-1", "%65ncoded/path", null, null, null },
// Basic path reference
{ "/path/to/context", null, null, "-1", "/path/to/context", null, null, null },
// Basic with encoded query
{ "http://example.com/path/to/context;param?query=%22value%22#fragment", "http", "example.com", "-1",
"/path/to/context;param", "param", "query=%22value%22", "fragment" },
{ "http://[::1]/path/to/context;param?query=%22value%22#fragment", "http", "[::1]", "-1",
"/path/to/context;param", "param", "query=%22value%22", "fragment" },
// Basic with parameters and query
{ "http://example.com:8080/path/to/context;param?query=%22value%22#fragment", "http", "example.com",
"8080", "/path/to/context;param", "param", "query=%22value%22", "fragment" },
{ "http://[::1]:8080/path/to/context;param?query=%22value%22#fragment", "http", "[::1]", "8080",
"/path/to/context;param", "param", "query=%22value%22", "fragment" },
// Path References
{ "/path/info", null, null, null, "/path/info", null, null, null },
{ "/path/info#fragment", null, null, null, "/path/info", null, null, "fragment" },
{ "/path/info?query", null, null, null, "/path/info", null, "query", null },
{ "/path/info?query#fragment", null, null, null, "/path/info", null, "query", "fragment" },
{ "/path/info;param", null, null, null, "/path/info;param", "param", null, null },
{ "/path/info;param#fragment", null, null, null, "/path/info;param", "param", null, "fragment" },
{ "/path/info;param?query", null, null, null, "/path/info;param", "param", "query", null },
{ "/path/info;param?query#fragment", null, null, null, "/path/info;param", "param", "query",
"fragment" },
// Protocol Less (aka scheme-less) URIs
{ "//host/path/info", null, "host", null, "/path/info", null, null, null },
{ "//user@host/path/info", null, "host", null, "/path/info", null, null, null },
{ "//user@host:8080/path/info", null, "host", "8080", "/path/info", null, null, null },
{ "//host:8080/path/info", null, "host", "8080", "/path/info", null, null, null },
// Host Less
{ "http:/path/info", "http", null, null, "/path/info", null, null, null },
{ "http:/path/info#fragment", "http", null, null, "/path/info", null, null, "fragment" },
{ "http:/path/info?query", "http", null, null, "/path/info", null, "query", null },
{ "http:/path/info?query#fragment", "http", null, null, "/path/info", null, "query", "fragment" },
{ "http:/path/info;param", "http", null, null, "/path/info;param", "param", null, null },
{ "http:/path/info;param#fragment", "http", null, null, "/path/info;param", "param", null, "fragment" },
{ "http:/path/info;param?query", "http", null, null, "/path/info;param", "param", "query", null },
{ "http:/path/info;param?query#fragment", "http", null, null, "/path/info;param", "param", "query",
"fragment" },
// Everything and the kitchen sink
{ "http://user@host:8080/path/info;param?query#fragment", "http", "host", "8080", "/path/info;param",
"param", "query", "fragment" },
{ "xxxxx://user@host:8080/path/info;param?query#fragment", "xxxxx", "host", "8080", "/path/info;param",
"param", "query", "fragment" },
// No host, parameter with no content
{ "http:///;?#", "http", null, null, "/;", "", "", "" },
// Path with query that has no value
{ "/path/info?a=?query", null, null, null, "/path/info", null, "a=?query", null },
// Path with query alt syntax
{ "/path/info?a=;query", null, null, null, "/path/info", null, "a=;query", null },
// URI with host character
{"/@path/info",null,null,null,"/@path/info",null,null,null},
{"/user@path/info",null,null,null,"/user@path/info",null,null,null},
{"//user@host/info",null,"host",null,"/info",null,null,null},
{"//@host/info",null,"host",null,"/info",null,null,null},
{"@host/info",null,null,null,"@host/info",null,null,null},
// Scheme-less, with host and port (overlapping with path)
{ "//host:8080//", null, "host", "8080", "//", null, null, null },
// File reference
{ "file:///path/info", "file", null, null, "/path/info", null, null, null },
{ "file:/path/info", "file", null, null, "/path/info", null, null, null },
// Bad URI (no scheme, no host, no path)
{ "//", null, null, null, null, null, null, null },
// Simple localhost references
{ "http://localhost/", "http", "localhost", null, "/", null, null, null },
{ "http://localhost:8080/", "http", "localhost", "8080", "/", null, null, null },
{ "http://localhost/?x=y", "http", "localhost", null, "/", null, "x=y", null },
// Simple path with parameter
{ "/;param", null, null, null, "/;param", "param", null, null },
{ ";param", null, null, null, ";param", "param", null, null },
// Simple path with query
{ "/?x=y", null, null, null, "/", null, "x=y", null },
{ "/?abc=test", null, null, null, "/", null, "abc=test", null },
// Simple path with fragment
{ "/#fragment", null, null, null, "/", null, null, "fragment" },
// Simple IPv4 host with port (default path)
{ "http://192.0.0.1:8080/", "http", "192.0.0.1", "8080", "/", null, null, null },
// Simple IPv6 host with port (default path)
{ "http://[2001:db8::1]:8080/", "http", "[2001:db8::1]", "8080", "/", null, null, null },
// IPv6 authenticated host with port (default path)
{ "http://user@[2001:db8::1]:8080/", "http", "[2001:db8::1]", "8080", "/", null, null, null },
// Simple IPv6 host no port (default path)
{ "http://[2001:db8::1]/", "http", "[2001:db8::1]", null, "/", null, null, null },
// Scheme-less IPv6, host with port (default path)
{ "//[2001:db8::1]:8080/", null, "[2001:db8::1]", "8080", "/", null, null, null },
// Interpreted as relative path of "*" (no
// host/port/scheme/query/fragment)
{ "*", null, null, null, "*", null, null, null },
// Path detection Tests (seen from JSP/JSTL and <c:url> use
{ "http://host:8080/path/info?q1=v1&q2=v2", "http", "host", "8080", "/path/info", null, "q1=v1&q2=v2",
null },
{ "/path/info?q1=v1&q2=v2", null, null, null, "/path/info", null, "q1=v1&q2=v2", null },
{ "/info?q1=v1&q2=v2", null, null, null, "/info", null, "q1=v1&q2=v2", null },
{ "info?q1=v1&q2=v2", null, null, null, "info", null, "q1=v1&q2=v2", null },
{ "info;q1=v1?q2=v2", null, null, null, "info;q1=v1", "q1=v1", "q2=v2", null },
// Path-less, query only (seen from JSP/JSTL and <c:url> use
{ "?q1=v1&q2=v2", null, null, null, "", null, "q1=v1&q2=v2", null } };
return Arrays.asList(tests);
}
@Parameter(0)
public String input;
@Parameter(1)
public String scheme;
@Parameter(2)
public String host;
@Parameter(3)
public String port;
@Parameter(4)
public String path;
@Parameter(5)
public String param;
@Parameter(6)
public String query;
@Parameter(7)
public String fragment;
@Test
public void testParseString() throws Exception {
HttpURI httpUri = new HttpURI(input);
try {
new URI(input);
// URI is valid (per java.net.URI parsing)
// Test case sanity check
assertThat("[" + input + "] expected path (test case) cannot be null", path, notNullValue());
// Assert expectations
assertThat("[" + input + "] .scheme", httpUri.getScheme(), is(scheme));
assertThat("[" + input + "] .host", httpUri.getHost(), is(host));
assertThat("[" + input + "] .port", httpUri.getPort(), is(port == null ? -1 : Integer.parseInt(port)));
assertThat("[" + input + "] .path", httpUri.getPath(), is(path));
assertThat("[" + input + "] .param", httpUri.getParam(), is(param));
assertThat("[" + input + "] .query", httpUri.getQuery(), is(query));
assertThat("[" + input + "] .fragment", httpUri.getFragment(), is(fragment));
assertThat("[" + input + "] .toString", httpUri.toString(), is(input));
} catch (URISyntaxException e) {
// Assert HttpURI values for invalid URI (such as "//")
assertThat("[" + input + "] .scheme", httpUri.getScheme(), is(nullValue()));
assertThat("[" + input + "] .host", httpUri.getHost(), is(nullValue()));
assertThat("[" + input + "] .port", httpUri.getPort(), is(-1));
assertThat("[" + input + "] .path", httpUri.getPath(), is(nullValue()));
assertThat("[" + input + "] .param", httpUri.getParam(), is(nullValue()));
assertThat("[" + input + "] .query", httpUri.getQuery(), is(nullValue()));
assertThat("[" + input + "] .fragment", httpUri.getFragment(), is(nullValue()));
}
}
@Test
public void testParseURI() throws Exception {
URI javaUri = null;
try {
javaUri = new URI(input);
assumeNotNull(javaUri);
} catch (URISyntaxException e) {
// Ignore, as URI is invalid anyway
assumeNoException(e);
}
HttpURI httpUri = new HttpURI(javaUri);
assertThat("[" + input + "] .scheme", httpUri.getScheme(), is(scheme));
assertThat("[" + input + "] .host", httpUri.getHost(), is(host));
assertThat("[" + input + "] .port", httpUri.getPort(), is(port == null ? -1 : Integer.parseInt(port)));
assertThat("[" + input + "] .path", httpUri.getPath(), is(path));
assertThat("[" + input + "] .param", httpUri.getParam(), is(param));
assertThat("[" + input + "] .query", httpUri.getQuery(), is(query));
assertThat("[" + input + "] .fragment", httpUri.getFragment(), is(fragment));
assertThat("[" + input + "] .toString", httpUri.toString(), is(input));
}
@Test
public void testCompareToJavaNetURI() throws Exception {
URI javaUri = null;
try {
javaUri = new URI(input);
assumeNotNull(javaUri);
} catch (URISyntaxException e) {
// Ignore, as URI is invalid anyway
assumeNoException(e);
}
HttpURI httpUri = new HttpURI(javaUri);
assertThat("[" + input + "] .scheme", httpUri.getScheme(), is(javaUri.getScheme()));
assertThat("[" + input + "] .host", httpUri.getHost(), is(javaUri.getHost()));
assertThat("[" + input + "] .port", httpUri.getPort(), is(javaUri.getPort()));
assertThat("[" + input + "] .path", httpUri.getPath(), is(javaUri.getRawPath()));
// Not Relevant for java.net.URI -- assertThat("["+input+"] .param",
// httpUri.getParam(), is(param));
assertThat("[" + input + "] .query", httpUri.getQuery(), is(javaUri.getRawQuery()));
assertThat("[" + input + "] .fragment", httpUri.getFragment(), is(javaUri.getFragment()));
assertThat("[" + input + "] .toString", httpUri.toString(), is(javaUri.toASCIIString()));
}
}