blob: 3f58f680629ff68cf50e37391ed72e21dbeef63a [file] [log] [blame]
//
// ========================================================================
// 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()));
}
}