| // |
| // ======================================================================== |
| // Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. |
| // ------------------------------------------------------------------------ |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // and Apache License v2.0 which accompanies this distribution. |
| // |
| // The Eclipse Public License is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // The Apache License v2.0 is available at |
| // http://www.opensource.org/licenses/apache2.0.php |
| // |
| // You may elect to redistribute this code under either of these licenses. |
| // ======================================================================== |
| // |
| |
| |
| package org.eclipse.jetty.http; |
| |
| 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 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; |
| |
| |
| @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"}, |
| // FIXME: {"/path/info;a=b/foo;c=d",null,null,null,"/data/info;a=b/foo;c=d","foo=bar1",null,null}, |
| |
| // 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())); |
| } |
| } |