remove default domain, stricter security

This commit is contained in:
Jörg Prante 2023-07-30 21:57:18 +02:00 committed by Jörg Prante
parent 4fc4e72cb2
commit abd1df903b
16 changed files with 161 additions and 127 deletions

View file

@ -1,5 +1,5 @@
group = org.xbib group = org.xbib
name = net name = net
version = 3.2.0 version = 3.3.0
org.gradle.warning.mode = ALL org.gradle.warning.mode = ALL

View file

@ -21,7 +21,7 @@ public class PathDecoder {
String path = pos > 0 ? pathAndQuery.substring(0, pos) : pathAndQuery; String path = pos > 0 ? pathAndQuery.substring(0, pos) : pathAndQuery;
this.query = pos > 0 ? pathAndQuery.substring(pos + 1) : null; this.query = pos > 0 ? pathAndQuery.substring(pos + 1) : null;
this.path = PathNormalizer.normalize(path); this.path = PathNormalizer.normalize(path);
this.params = Parameter.builder().enablePercentDecoding(); this.params = Parameter.builder().domain(Parameter.Domain.PATH).enablePercentDecoding();
if (query != null) { if (query != null) {
parse(query); parse(query);
} }

View file

@ -1,10 +1,11 @@
package org.xbib.net.path; package org.xbib.net.path;
import org.xbib.net.Parameter; import org.xbib.net.Parameter;
import org.xbib.net.ParameterException;
public interface PathResolver<T> { public interface PathResolver<T> {
void resolve(String method, String path, ResultListener<T> listener); void resolve(String method, String path, ResultListener<T> listener) throws ParameterException;
interface Builder<T> { interface Builder<T> {
@ -25,7 +26,7 @@ public interface PathResolver<T> {
@FunctionalInterface @FunctionalInterface
interface ResultListener<T> { interface ResultListener<T> {
void onResult(Result<T> result); void onResult(Result<T> result) throws ParameterException;
} }
} }

View file

@ -50,11 +50,11 @@ public class PathMatcher {
} }
public Parameter extractUriTemplateVariables(String pattern, String path) { public Parameter extractUriTemplateVariables(String pattern, String path) {
ParameterBuilder queryParameters = Parameter.builder(); ParameterBuilder uriParameters = Parameter.builder().domain(Parameter.Domain.PATH);
if (!doMatch(pattern, path, true, queryParameters)) { if (!doMatch(pattern, path, true, uriParameters)) {
throw new IllegalStateException("Pattern \"" + pattern + "\" is not a match for \"" + path + "\""); throw new IllegalStateException("Pattern \"" + pattern + "\" is not a match for \"" + path + "\"");
} }
return queryParameters.build(); return uriParameters.build();
} }
public PathComparator getPatternComparator(String path) { public PathComparator getPatternComparator(String path) {

View file

@ -2,6 +2,7 @@ package org.xbib.net.path.simple;
import org.xbib.net.Parameter; import org.xbib.net.Parameter;
import org.xbib.net.ParameterBuilder; import org.xbib.net.ParameterBuilder;
import org.xbib.net.ParameterException;
import org.xbib.net.util.CharMatcher; import org.xbib.net.util.CharMatcher;
import java.util.ArrayList; import java.util.ArrayList;
@ -53,7 +54,7 @@ public class PathResolver<T> implements org.xbib.net.path.PathResolver<T> {
* @param resultListener result listener * @param resultListener result listener
*/ */
@Override @Override
public void resolve(String method, String path, ResultListener<T> resultListener) { public void resolve(String method, String path, ResultListener<T> resultListener) throws ParameterException {
Objects.requireNonNull(method, "method"); Objects.requireNonNull(method, "method");
Objects.requireNonNull(path, "path"); Objects.requireNonNull(path, "path");
resolve(method, builder.pathMatcher.tokenize(path), 0, new ArrayList<>(), resultListener); resolve(method, builder.pathMatcher.tokenize(path), 0, new ArrayList<>(), resultListener);
@ -68,7 +69,7 @@ public class PathResolver<T> implements org.xbib.net.path.PathResolver<T> {
List<String> pathSegments, List<String> pathSegments,
int index, int index,
List<String> parameters, List<String> parameters,
ResultListener<T> resultListener) { ResultListener<T> resultListener) throws ParameterException {
if (index < pathSegments.size()) { if (index < pathSegments.size()) {
String segment = pathSegments.get(index); String segment = pathSegments.get(index);
PathResolver<T> child = children.get(segment); PathResolver<T> child = children.get(segment);

View file

@ -4,6 +4,7 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.xbib.net.Parameter; import org.xbib.net.Parameter;
import org.xbib.net.ParameterBuilder; import org.xbib.net.ParameterBuilder;
import org.xbib.net.ParameterException;
import org.xbib.net.PathNormalizer; import org.xbib.net.PathNormalizer;
import java.util.ArrayList; import java.util.ArrayList;
@ -37,7 +38,7 @@ public class PathResolver<T> implements org.xbib.net.path.PathResolver<T> {
} }
@Override @Override
public void resolve(String method, String path, ResultListener<T> listener) { public void resolve(String method, String path, ResultListener<T> listener) throws ParameterException {
Objects.requireNonNull(method, "method"); Objects.requireNonNull(method, "method");
Objects.requireNonNull(path, "path"); Objects.requireNonNull(path, "path");
List<PathSegment> pathSegments = PathMatcher.tokenize(PathNormalizer.normalize(path), List<PathSegment> pathSegments = PathMatcher.tokenize(PathNormalizer.normalize(path),
@ -54,7 +55,7 @@ public class PathResolver<T> implements org.xbib.net.path.PathResolver<T> {
private ParameterBuilder resolve(List<PathSegment> pathSegments, private ParameterBuilder resolve(List<PathSegment> pathSegments,
int index, int index,
ParameterBuilder parameterBuilder, ParameterBuilder parameterBuilder,
ResultListener<T> listener) { ResultListener<T> listener) throws ParameterException {
ParameterBuilder pb = parameterBuilder; ParameterBuilder pb = parameterBuilder;
if (index < pathSegments.size()) { if (index < pathSegments.size()) {
PathSegment segment = pathSegments.get(index); PathSegment segment = pathSegments.get(index);

View file

@ -10,17 +10,17 @@ import static org.junit.jupiter.api.Assertions.assertNull;
class PathDecoderTest { class PathDecoderTest {
@Test @Test
void testPlusSign() { void testPlusSign() throws Exception {
PathDecoder decoder = new PathDecoder("/path?a=b+c", "d=e+f"); PathDecoder decoder = new PathDecoder("/path?a=b+c", "d=e+f");
assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.DEFAULT).toString()); assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.PATH).toString());
assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.DEFAULT).toString()); assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.PATH).toString());
} }
@Test @Test
void testSlash() { void testSlash() throws Exception {
PathDecoder decoder = new PathDecoder("path/foo/bar/?a=b+c", "d=e+f"); PathDecoder decoder = new PathDecoder("path/foo/bar/?a=b+c", "d=e+f");
assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.DEFAULT).toString()); assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.PATH).toString());
assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.DEFAULT).toString()); assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.PATH).toString());
} }
@Test @Test
@ -30,23 +30,23 @@ class PathDecoderTest {
} }
@Test @Test
void testSlashes() { void testSlashes() throws Exception {
PathDecoder decoder = new PathDecoder("//path?a=b+c", "d=e+f"); PathDecoder decoder = new PathDecoder("//path?a=b+c", "d=e+f");
assertEquals("/path", decoder.path()); assertEquals("/path", decoder.path());
assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.DEFAULT).toString()); assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.PATH).toString());
assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.DEFAULT).toString()); assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.PATH).toString());
} }
@Test @Test
void testPlusPercent() { void testPlusPercent() throws Exception {
PathDecoder decoder = new PathDecoder("//path?a=b%2Bc", "d=e%2Bf"); PathDecoder decoder = new PathDecoder("//path?a=b%2Bc", "d=e%2Bf");
assertEquals("/path", decoder.path()); assertEquals("/path", decoder.path());
assertEquals("[b+c]", decoder.getParameter().getAll("a", Parameter.Domain.DEFAULT).toString()); assertEquals("[b+c]", decoder.getParameter().getAll("a", Parameter.Domain.PATH).toString());
assertEquals("[e+f]", decoder.getParameter().getAll("d", Parameter.Domain.DEFAULT).toString()); assertEquals("[e+f]", decoder.getParameter().getAll("d", Parameter.Domain.PATH).toString());
} }
@Test @Test
void decodeURL() { void decodeURL() throws Exception {
String requestURI = "/pdfconverter/index.gtpl?x-fl-key=20190035592&x-source=ftp://dummy@xbib.org/upload/20190035592/20190035592.pdf&x-fl-target=ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf&x-fl-copy=&x-fl-ack=https://xbib.org/ack/&x-fl-pages=1-"; String requestURI = "/pdfconverter/index.gtpl?x-fl-key=20190035592&x-source=ftp://dummy@xbib.org/upload/20190035592/20190035592.pdf&x-fl-target=ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf&x-fl-copy=&x-fl-ack=https://xbib.org/ack/&x-fl-pages=1-";
URL url = URL.builder().path(requestURI).build(); URL url = URL.builder().path(requestURI).build();
assertNull(url.getHost()); assertNull(url.getHost());
@ -59,7 +59,7 @@ class PathDecoderTest {
} }
assertEquals("x-fl-key=20190035592&x-source=ftp://dummy@xbib.org/upload/20190035592/20190035592.pdf&x-fl-target=ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf&x-fl-copy=&x-fl-ack=https://xbib.org/ack/&x-fl-pages=1-", url.getDecodedQuery()); assertEquals("x-fl-key=20190035592&x-source=ftp://dummy@xbib.org/upload/20190035592/20190035592.pdf&x-fl-target=ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf&x-fl-copy=&x-fl-ack=https://xbib.org/ack/&x-fl-pages=1-", url.getDecodedQuery());
assertEquals("[x-fl-key=20190035592, x-source=ftp://dummy@xbib.org/upload/20190035592/20190035592.pdf, x-fl-target=ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf, x-fl-copy=, x-fl-ack=https://xbib.org/ack/, x-fl-pages=1-]", decoder.getParameter().toString()); assertEquals("[x-fl-key=20190035592, x-source=ftp://dummy@xbib.org/upload/20190035592/20190035592.pdf, x-fl-target=ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf, x-fl-copy=, x-fl-ack=https://xbib.org/ack/, x-fl-pages=1-]", decoder.getParameter().toString());
url = URL.from(decoder.getParameter().getAll("x-fl-target", Parameter.Domain.DEFAULT).get(0).toString()); url = URL.from(decoder.getParameter().getAll("x-fl-target", Parameter.Domain.PATH).get(0).toString());
assertEquals("ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf", url.toString()); assertEquals("ftp://dummy@xbib.org/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf", url.toString());
} }
} }

View file

@ -311,38 +311,38 @@ class PathMatcherTest {
} }
@Test @Test
void extractUriTemplateVariablesRegex() { void extractUriTemplateVariablesRegex() throws Exception {
Parameter result = pathMatcher.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-{version:[\\w\\.]+}.jar", Parameter result = pathMatcher.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-{version:[\\w\\.]+}.jar",
"com.example-1.0.0.jar"); "com.example-1.0.0.jar");
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0)); assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.PATH).get(0));
assertEquals("1.0.0", result.getAll("version", Parameter.Domain.DEFAULT).get(0)); assertEquals("1.0.0", result.getAll("version", Parameter.Domain.PATH).get(0));
result = pathMatcher.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-sources-{version:[\\w\\.]+}.jar", result = pathMatcher.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-sources-{version:[\\w\\.]+}.jar",
"com.example-sources-1.0.0.jar"); "com.example-sources-1.0.0.jar");
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0)); assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.PATH).get(0));
assertEquals("1.0.0", result.getAll("version", Parameter.Domain.DEFAULT).get(0)); assertEquals("1.0.0", result.getAll("version", Parameter.Domain.PATH).get(0));
} }
@Test @Test
void extractUriTemplateVarsRegexQualifiers() { void extractUriTemplateVarsRegexQualifiers() throws Exception {
Parameter result = pathMatcher.extractUriTemplateVariables( Parameter result = pathMatcher.extractUriTemplateVariables(
"{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.]+}.jar", "{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.]+}.jar",
"com.example-sources-1.0.0.jar"); "com.example-sources-1.0.0.jar");
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0)); assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.PATH).get(0));
assertEquals("1.0.0", result.getAll("version", Parameter.Domain.DEFAULT).get(0)); assertEquals("1.0.0", result.getAll("version", Parameter.Domain.PATH).get(0));
result = pathMatcher.extractUriTemplateVariables( result = pathMatcher.extractUriTemplateVariables(
"{symbolicName:[\\w\\.]+}-sources-{version:[\\d\\.]+}-{year:\\d{4}}{month:\\d{2}}{day:\\d{2}}.jar", "{symbolicName:[\\w\\.]+}-sources-{version:[\\d\\.]+}-{year:\\d{4}}{month:\\d{2}}{day:\\d{2}}.jar",
"com.example-sources-1.0.0-20100220.jar"); "com.example-sources-1.0.0-20100220.jar");
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0)); assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.PATH).get(0));
assertEquals("1.0.0", result.getAll("version", Parameter.Domain.DEFAULT).get(0)); assertEquals("1.0.0", result.getAll("version", Parameter.Domain.PATH).get(0));
assertEquals("2010", result.getAll("year", Parameter.Domain.DEFAULT).get(0)); assertEquals("2010", result.getAll("year", Parameter.Domain.PATH).get(0));
assertEquals("02", result.getAll("month", Parameter.Domain.DEFAULT).get(0)); assertEquals("02", result.getAll("month", Parameter.Domain.PATH).get(0));
assertEquals("20", result.getAll("day", Parameter.Domain.DEFAULT).get(0)); assertEquals("20", result.getAll("day", Parameter.Domain.PATH).get(0));
result = pathMatcher.extractUriTemplateVariables( result = pathMatcher.extractUriTemplateVariables(
"{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.\\{\\}]+}.jar", "{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.\\{\\}]+}.jar",
"com.example-sources-1.0.0.{12}.jar"); "com.example-sources-1.0.0.{12}.jar");
assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0)); assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.PATH).get(0));
assertEquals("1.0.0.{12}", result.getAll("version", Parameter.Domain.DEFAULT).get(0)); assertEquals("1.0.0.{12}", result.getAll("version", Parameter.Domain.PATH).get(0));
} }
@Test @Test

View file

@ -2,6 +2,7 @@ package org.xbib.net.path.simple;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.net.Parameter; import org.xbib.net.Parameter;
import org.xbib.net.ParameterException;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@ -18,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.fail;
class PathResolverTest { class PathResolverTest {
@Test @Test
void simple() { void simple() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder() PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
.add("GET", "explorer", 1234) .add("GET", "explorer", 1234)
.build(); .build();
@ -29,7 +30,7 @@ class PathResolverTest {
} }
@Test @Test
void name() { void name() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder() PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
.add("GET", "/static/{file}", 1234) .add("GET", "/static/{file}", 1234)
.add("HEAD", "/static/{file}", 1234) .add("HEAD", "/static/{file}", 1234)
@ -39,7 +40,7 @@ class PathResolverTest {
} }
@Test @Test
void glob() { void glob() throws ParameterException {
PathResolver<Integer> trie = PathResolver.<Integer>builder() PathResolver<Integer> trie = PathResolver.<Integer>builder()
.add("GET", "/static/**", 1234) .add("GET", "/static/**", 1234)
.build(); .build();
@ -48,7 +49,7 @@ class PathResolverTest {
} }
@Test @Test
void sharedPrefix() { void sharedPrefix() throws ParameterException {
PathResolver<Integer> trie = PathResolver.<Integer>builder() PathResolver<Integer> trie = PathResolver.<Integer>builder()
.add("GET", "discovery/v1/rest", 1234) .add("GET", "discovery/v1/rest", 1234)
.add("GET", "discovery/v2/rest", 4321) .add("GET", "discovery/v2/rest", 4321)
@ -61,7 +62,7 @@ class PathResolverTest {
} }
@Test @Test
void prefix() { void prefix() throws ParameterException {
PathResolver<Integer> trie = PathResolver.<Integer>builder() PathResolver<Integer> trie = PathResolver.<Integer>builder()
.add("GET", "discovery", 1234) .add("GET", "discovery", 1234)
.add("GET", "discovery/v1", 4321) .add("GET", "discovery/v1", 4321)
@ -72,7 +73,7 @@ class PathResolverTest {
} }
@Test @Test
void parameter() { void parameter() throws ParameterException {
PathResolver<Integer> trie = PathResolver.<Integer>builder() PathResolver<Integer> trie = PathResolver.<Integer>builder()
.add("GET", "discovery/{version}/rest", 1234) .add("GET", "discovery/{version}/rest", 1234)
.build(); .build();
@ -81,7 +82,7 @@ class PathResolverTest {
} }
@Test @Test
void multipleParameters() { void multipleParameters() throws ParameterException {
PathResolver<Integer> trie = PathResolver.<Integer>builder() PathResolver<Integer> trie = PathResolver.<Integer>builder()
.add("GET", "discovery/{discovery_version}/apis/{api}/{format}", 1234) .add("GET", "discovery/{discovery_version}/apis/{api}/{format}", 1234)
.build(); .build();
@ -90,7 +91,7 @@ class PathResolverTest {
} }
@Test @Test
void sharedParameterPrefix() { void sharedParameterPrefix() throws ParameterException {
PathResolver<Integer> trie = PathResolver.<Integer>builder() PathResolver<Integer> trie = PathResolver.<Integer>builder()
.add("GET", "discovery/{version}/rest", 1234) .add("GET", "discovery/{version}/rest", 1234)
.add("GET", "discovery/{version}/rpc", 4321) .add("GET", "discovery/{version}/rpc", 4321)
@ -102,7 +103,7 @@ class PathResolverTest {
} }
@Test @Test
void testResolveParameterAfterLiteral() { void testResolveParameterAfterLiteral() throws ParameterException {
PathResolver<Integer> trie = PathResolver.<Integer>builder() PathResolver<Integer> trie = PathResolver.<Integer>builder()
.add("GET", "{one}/three", 1234) .add("GET", "{one}/three", 1234)
.add("GET", "one/two", 4321) .add("GET", "one/two", 4321)
@ -112,7 +113,7 @@ class PathResolverTest {
} }
@Test @Test
void testResolveBacktrack() { void testResolveBacktrack() throws ParameterException {
PathResolver<Integer> trie = PathResolver.<Integer>builder() PathResolver<Integer> trie = PathResolver.<Integer>builder()
.add("GET", "{one}/{two}/three/{four}", 1234) .add("GET", "{one}/{two}/three/{four}", 1234)
.add("GET", "one/two/{three}/four", 4321) .add("GET", "one/two/{three}/four", 4321)
@ -122,7 +123,7 @@ class PathResolverTest {
} }
@Test @Test
void pathMethodsWithDifferentParameterNames() { void pathMethodsWithDifferentParameterNames() throws ParameterException {
PathResolver<Integer> trie = PathResolver.<Integer>builder() PathResolver<Integer> trie = PathResolver.<Integer>builder()
.add("GET", "test/{one}", 1234) .add("GET", "test/{one}", 1234)
.add("PUT", "test/{two}", 4321) .add("PUT", "test/{two}", 4321)
@ -142,7 +143,7 @@ class PathResolverTest {
} }
@Test @Test
void laxDuplicatePath() { void laxDuplicatePath() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder(false) PathResolver<Integer> pathResolver = PathResolver.<Integer>builder(false)
.add("GET", "test/{one}", 1234) .add("GET", "test/{one}", 1234)
.add("GET", "test/{two}", 4321) .add("GET", "test/{two}", 4321)
@ -186,6 +187,8 @@ class PathResolverTest {
fail("expected NullPointerException"); fail("expected NullPointerException");
} catch (NullPointerException e) { } catch (NullPointerException e) {
// expected // expected
} catch (ParameterException e) {
throw new RuntimeException(e);
} }
} }
@ -223,7 +226,7 @@ class PathResolverTest {
} }
@Test @Test
void testFallback() { void testFallback() throws ParameterException {
AtomicInteger counter = new AtomicInteger(0); AtomicInteger counter = new AtomicInteger(0);
org.xbib.net.path.PathResolver<Integer> trie = PathResolver.<Integer>builder() org.xbib.net.path.PathResolver<Integer> trie = PathResolver.<Integer>builder()
.add("GET", "/test/{one}", 1) .add("GET", "/test/{one}", 1)
@ -247,16 +250,16 @@ class PathResolverTest {
} }
} }
private void assertSuccessfulGetResolution(PathResolver<Integer> trie, String path, Integer value) { private void assertSuccessfulGetResolution(PathResolver<Integer> trie, String path, Integer value) throws ParameterException {
assertSuccessfulResolution(trie, "GET", path, value); assertSuccessfulResolution(trie, "GET", path, value);
} }
private void assertSuccessfulResolution(PathResolver<Integer> trie, String method, String path, Integer value) { private void assertSuccessfulResolution(PathResolver<Integer> trie, String method, String path, Integer value) throws ParameterException {
assertSuccessfulResolution(trie, method, path, Set.of(value), Collections.emptyMap()); assertSuccessfulResolution(trie, method, path, Set.of(value), Collections.emptyMap());
} }
private void assertSuccessfulGetResolution(PathResolver<Integer> trie, String path, Integer value, private void assertSuccessfulGetResolution(PathResolver<Integer> trie, String path, Integer value,
Map<String, String> rawParameters) { Map<String, String> rawParameters) throws ParameterException {
assertSuccessfulResolution(trie, "GET", path, Set.of(value), rawParameters); assertSuccessfulResolution(trie, "GET", path, Set.of(value), rawParameters);
} }
@ -264,18 +267,18 @@ class PathResolverTest {
String method, String method,
String path, String path,
Set<Integer> values, Set<Integer> values,
Map<String, String> rawParameters) { Map<String, String> rawParameters) throws ParameterException {
trie.resolve(method, path, result -> { trie.resolve(method, path, result -> {
assertTrue(values.contains(result.getValue())); assertTrue(values.contains(result.getValue()));
//assertThat(result.getRawParameters(), is(rawParameters)); //assertThat(result.getRawParameters(), is(rawParameters));
}); });
} }
private void assertFailedGetResolution(PathResolver<Integer> trie, String path) { private void assertFailedGetResolution(PathResolver<Integer> trie, String path) throws ParameterException {
assertFailedGetResolution(trie, "GET", path); assertFailedGetResolution(trie, "GET", path);
} }
private void assertFailedGetResolution(PathResolver<Integer> trie, String method, String path) { private void assertFailedGetResolution(PathResolver<Integer> trie, String method, String path) throws ParameterException {
trie.resolve(method, path, r-> { fail(); }); trie.resolve(method, path, r-> { fail(); });
} }
} }

View file

@ -3,6 +3,7 @@ package org.xbib.net.path.structure;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.net.Parameter; import org.xbib.net.Parameter;
import org.xbib.net.ParameterException;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@ -20,7 +21,7 @@ import static org.junit.jupiter.api.Assertions.fail;
class PathResolverTest { class PathResolverTest {
@Test @Test
void example() { void example() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder() PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
.add( "GET", "/static/{file}", 1234) .add( "GET", "/static/{file}", 1234)
.build(); .build();
@ -29,7 +30,7 @@ class PathResolverTest {
} }
@Test @Test
void simple() { void simple() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder() PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
.add("GET", "explorer", 1234) .add("GET", "explorer", 1234)
.build(); .build();
@ -39,7 +40,7 @@ class PathResolverTest {
} }
@Test @Test
void sharedPrefix() { void sharedPrefix() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder() PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
.add("GET", "discovery/v1/rest", 1234) .add("GET", "discovery/v1/rest", 1234)
.add("GET", "discovery/v2/rest", 4321) .add("GET", "discovery/v2/rest", 4321)
@ -52,7 +53,7 @@ class PathResolverTest {
} }
@Test @Test
void prefix() { void prefix() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder() PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
.add("GET", "discovery", 1234) .add("GET", "discovery", 1234)
.add("GET", "discovery/v1", 4321) .add("GET", "discovery/v1", 4321)
@ -63,7 +64,7 @@ class PathResolverTest {
} }
@Test @Test
void parameter() { void parameter() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder() PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
.add("GET", "discovery/{version}/rest", 1234) .add("GET", "discovery/{version}/rest", 1234)
.build(); .build();
@ -72,7 +73,7 @@ class PathResolverTest {
} }
@Test @Test
void multipleParameters() { void multipleParameters() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder() PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
.add("GET", "discovery/{discovery_version}/apis/{api}/{format}", 1234) .add("GET", "discovery/{discovery_version}/apis/{api}/{format}", 1234)
.build(); .build();
@ -81,7 +82,7 @@ class PathResolverTest {
} }
@Test @Test
void sharedParameterPrefix() { void sharedParameterPrefix() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder() PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
.add("GET", "discovery/{version}/rest", 1234) .add("GET", "discovery/{version}/rest", 1234)
.add("GET", "discovery/{version}/rpc", 4321) .add("GET", "discovery/{version}/rpc", 4321)
@ -97,7 +98,7 @@ class PathResolverTest {
} }
@Test @Test
void testResolveParameterAfterLiteral() { void testResolveParameterAfterLiteral() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder() PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
.add("GET", "{one}/three", 1234) .add("GET", "{one}/three", 1234)
.add("GET", "one/two", 4321) .add("GET", "one/two", 4321)
@ -108,7 +109,7 @@ class PathResolverTest {
} }
@Test @Test
void testResolveBacktrack() { void testResolveBacktrack() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder() PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
.add("GET", "{one}/{two}/three/{four}", 1234) .add("GET", "{one}/{two}/three/{four}", 1234)
.add("GET", "one/two/{three}/four", 4321) .add("GET", "one/two/{three}/four", 4321)
@ -128,7 +129,7 @@ class PathResolverTest {
} }
@Test @Test
void pathMethodsWithDifferentParameterNames() { void pathMethodsWithDifferentParameterNames() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder() PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
.add("GET", "test/{one}", 1234) .add("GET", "test/{one}", 1234)
.add("GET", "test/{two}", 4321) .add("GET", "test/{two}", 4321)
@ -148,7 +149,7 @@ class PathResolverTest {
} }
@Test @Test
void duplicatePathParams() { void duplicatePathParams() throws ParameterException {
PathResolver<Integer> pathResolver = PathResolver.<Integer>builder() PathResolver<Integer> pathResolver = PathResolver.<Integer>builder()
.add("GET", "test/{one}", 1234) .add("GET", "test/{one}", 1234)
.add("GET", "test/{two}", 4321) .add("GET", "test/{two}", 4321)
@ -197,11 +198,13 @@ class PathResolverTest {
fail("expected NullPointerException"); fail("expected NullPointerException");
} catch (NullPointerException e) { } catch (NullPointerException e) {
// expected // expected
} catch (ParameterException e) {
throw new RuntimeException(e);
} }
} }
@Test @Test
void testFallback() { void testFallback() throws ParameterException {
AtomicInteger counter = new AtomicInteger(0); AtomicInteger counter = new AtomicInteger(0);
PathResolver<Integer> trie = PathResolver.<Integer>builder() PathResolver<Integer> trie = PathResolver.<Integer>builder()
.add( "GET", "/test/{one}", 1) .add( "GET", "/test/{one}", 1)
@ -216,7 +219,7 @@ class PathResolverTest {
@Disabled @Disabled
@Test @Test
void testSuffixCatchAll() { void testSuffixCatchAll() throws ParameterException {
AtomicInteger counter = new AtomicInteger(0); AtomicInteger counter = new AtomicInteger(0);
PathResolver<Integer> trie = PathResolver.<Integer>builder() PathResolver<Integer> trie = PathResolver.<Integer>builder()
.add( "GET", "/**/*.test", 1) .add( "GET", "/**/*.test", 1)
@ -229,12 +232,12 @@ class PathResolverTest {
assertThat(counter.get(), equalTo(2)); assertThat(counter.get(), equalTo(2));
} }
private void assertSuccessfulResolution(PathResolver<Integer> pathResolver, String path, Integer value) { private void assertSuccessfulResolution(PathResolver<Integer> pathResolver, String path, Integer value) throws ParameterException {
assertSuccessfulResolution(pathResolver, "GET", path, value, Parameter.builder().domain(Parameter.Domain.PATH).build()); assertSuccessfulResolution(pathResolver, "GET", path, value, Parameter.builder().domain(Parameter.Domain.PATH).build());
} }
private void assertSuccessfulResolution(PathResolver<Integer> pathResolver, String method, String path, Integer value, private void assertSuccessfulResolution(PathResolver<Integer> pathResolver, String method, String path, Integer value,
Parameter parameter) { Parameter parameter) throws ParameterException {
AtomicBoolean found = new AtomicBoolean(false); AtomicBoolean found = new AtomicBoolean(false);
pathResolver.resolve(method, path, result -> { pathResolver.resolve(method, path, result -> {
assertThat(result, notNullValue()); assertThat(result, notNullValue());
@ -246,7 +249,7 @@ class PathResolverTest {
assertTrue(found.get()); assertTrue(found.get());
} }
private void assertFailedGetResolution(PathResolver<Integer> pathResolver, String path) { private void assertFailedGetResolution(PathResolver<Integer> pathResolver, String path) throws ParameterException {
pathResolver.resolve("GET", path, r -> assertThat(r, nullValue())); pathResolver.resolve("GET", path, r -> assertThat(r, nullValue()));
} }
} }

View file

@ -16,7 +16,7 @@ import org.xbib.datastructures.common.Pair;
public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Parameter> { public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Parameter> {
public enum Domain { public enum Domain {
DEFAULT, UNDEFINED,
QUERY, QUERY,
FORM, FORM,
PATH, PATH,
@ -92,7 +92,7 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public String getAsString(String key, Domain domain) { public String getAsString(String key, Domain domain) throws ParameterException {
Object object = get(key, domain); Object object = get(key, domain);
if (object instanceof Collection) { if (object instanceof Collection) {
Collection<Object> collection = (Collection<Object>) object; Collection<Object> collection = (Collection<Object>) object;
@ -108,7 +108,7 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Integer getAsInteger(String key, Domain domain) { public Integer getAsInteger(String key, Domain domain) throws ParameterException {
Object object = get(key, domain); Object object = get(key, domain);
if (object instanceof Collection) { if (object instanceof Collection) {
Collection<Object> collection = (Collection<Object>) object; Collection<Object> collection = (Collection<Object>) object;
@ -128,7 +128,7 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Boolean getAsBoolean(String key, Domain domain) { public Boolean getAsBoolean(String key, Domain domain) throws ParameterException {
Object object = get(key, domain); Object object = get(key, domain);
if (object instanceof Collection) { if (object instanceof Collection) {
Collection<Object> collection = (Collection<Object>) object; Collection<Object> collection = (Collection<Object>) object;
@ -147,49 +147,35 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
} }
} }
public String allToString() {
StringBuilder sb = new StringBuilder();
sb.append(list.toString());
builder.parameterMap.forEach((key, value) -> sb.append(" ").append(key).append(" -> ").append(value));
return sb.toString();
}
public boolean hasElements() { public boolean hasElements() {
return !list.isEmpty(); return !list.isEmpty();
} }
public MultiMap<String, Object> asMultiMap() { public MultiMap<String, Object> asMultiMap() throws ParameterException{
if (getDomain() == Domain.UNDEFINED) {
throw new ParameterException("undefined domain");
}
MultiMap<String, Object> multiMap = new LinkedHashSetMultiMap<>(); MultiMap<String, Object> multiMap = new LinkedHashSetMultiMap<>();
this.forEach(p -> multiMap.put(p.getKey(), p.getValue())); this.forEach(p -> multiMap.put(p.getKey(), p.getValue()));
return multiMap; return multiMap;
} }
public Map<String, Object> asSingleValuedMap() { public Map<String, Object> asSingleValuedMap() throws ParameterException {
if (getDomain() == Domain.UNDEFINED) {
throw new ParameterException("undefined domain");
}
Map<String, Object> map = new LinkedHashMap<>(); Map<String, Object> map = new LinkedHashMap<>();
this.forEach(p -> map.put(p.getKey(), createValue(p.getValue()))); this.forEach(p -> map.put(p.getKey(), createValue(p.getValue())));
return map; return map;
} }
@SuppressWarnings("unchecked") public List<Object> getAllInDomain(Domain domain) {
private static Object createValue(Object object) {
if (object instanceof Collection) {
Collection<Object> collection = (Collection<Object>) object;
if (collection.size() == 1) {
return collection.iterator().next();
} else {
return collection;
}
}
return object;
}
public List<Object> getAllDomain(Domain domain) {
Parameter parameter = null; Parameter parameter = null;
if (builder.parameterMap.containsKey(domain)) { if (builder.parameterMap.containsKey(domain)) {
parameter = builder.parameterMap.get(domain); parameter = builder.parameterMap.get(domain);
} }
if (parameter != null) { if (parameter != null) {
return parameter.getAllDomain(domain); return parameter.getAllInDomain(domain);
} }
if (getDomain().equals(domain)) { if (getDomain().equals(domain)) {
return list.stream() return list.stream()
@ -213,7 +199,10 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
return false; return false;
} }
public Parameter getDomain(Domain domain) { public Parameter get(Domain domain) throws ParameterException {
if (getDomain() == Domain.UNDEFINED) {
throw new ParameterException("undefined domain");
}
if (builder.parameterMap.containsKey(domain)) { if (builder.parameterMap.containsKey(domain)) {
return builder.parameterMap.get(domain); return builder.parameterMap.get(domain);
} }
@ -223,7 +212,10 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
return null; return null;
} }
public List<Object> getAll(String key, Domain domain) { public List<Object> getAll(String key, Domain domain) throws Exception {
if (getDomain() == Domain.UNDEFINED) {
throw new ParameterException("undefined domain");
}
Parameter parameter = null; Parameter parameter = null;
if (builder.parameterMap.containsKey(domain)) { if (builder.parameterMap.containsKey(domain)) {
parameter = builder.parameterMap.get(domain); parameter = builder.parameterMap.get(domain);
@ -255,7 +247,10 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
return false; return false;
} }
public Object get(String key, Domain domain) { public Object get(String key, Domain domain) throws ParameterException {
if (getDomain() == Domain.UNDEFINED) {
throw new ParameterException("undefined domain");
}
Parameter parameter = null; Parameter parameter = null;
if (builder.parameterMap.containsKey(domain)) { if (builder.parameterMap.containsKey(domain)) {
parameter = builder.parameterMap.get(domain); parameter = builder.parameterMap.get(domain);
@ -278,4 +273,24 @@ public class Parameter implements Iterable<Pair<String, Object>>, Comparable<Par
public String getAsQueryString() { public String getAsQueryString() {
return queryString; return queryString;
} }
private String allToString() {
StringBuilder sb = new StringBuilder();
sb.append(list.toString());
builder.parameterMap.forEach((key, value) -> sb.append(" ").append(key).append(" -> ").append(value));
return sb.toString();
}
@SuppressWarnings("unchecked")
private static Object createValue(Object object) {
if (object instanceof Collection) {
Collection<Object> collection = (Collection<Object>) object;
if (collection.size() == 1) {
return collection.iterator().next();
} else {
return collection;
}
}
return object;
}
} }

View file

@ -65,7 +65,7 @@ public class ParameterBuilder implements PairValidator {
ParameterBuilder() { ParameterBuilder() {
this.list = new ArrayList<>(); this.list = new ArrayList<>();
this.parameterMap = new HashMap<>(); this.parameterMap = new HashMap<>();
this.domain = Parameter.Domain.DEFAULT; this.domain = Parameter.Domain.UNDEFINED;
this.limit = 0; this.limit = 0;
} }

View file

@ -0,0 +1,9 @@
package org.xbib.net;
@SuppressWarnings("serial")
public class ParameterException extends Exception {
public ParameterException(String message) {
super(message);
}
}

View file

@ -82,7 +82,7 @@ public class URLBuilder {
.onMalformedInput(codingErrorAction) .onMalformedInput(codingErrorAction)
.onUnmappableCharacter(codingErrorAction); .onUnmappableCharacter(codingErrorAction);
this.percentDecoder = new PercentDecoder(charsetDecoder); this.percentDecoder = new PercentDecoder(charsetDecoder);
this.queryParams = Parameter.builder(); this.queryParams = Parameter.builder().domain(Parameter.Domain.QUERY);
return this; return this;
} }
@ -301,7 +301,6 @@ public class URLBuilder {
} }
} }
/** /**
* A path segment with associated matrix params, if any. * A path segment with associated matrix params, if any.
*/ */

View file

@ -17,33 +17,35 @@ public class ParameterTest {
public void testEmptyBuilder() { public void testEmptyBuilder() {
Parameter parameter = Parameter.builder().build(); Parameter parameter = Parameter.builder().build();
assertNotNull(parameter); assertNotNull(parameter);
assertFalse(parameter.containsKey("param1", Parameter.Domain.DEFAULT)); assertFalse(parameter.containsKey("param1", Parameter.Domain.UNDEFINED));
} }
@Test @Test
public void testSingleParameter() { public void testSingleParameter() {
Parameter parameter = Parameter.builder() Parameter parameter = Parameter.builder()
.domain(Parameter.Domain.QUERY)
.add("Hello", "World") .add("Hello", "World")
.build(); .build();
assertNotNull(parameter); assertNotNull(parameter);
assertTrue(parameter.containsKey("Hello", Parameter.Domain.DEFAULT)); assertTrue(parameter.containsKey("Hello", Parameter.Domain.QUERY));
} }
@Test @Test
public void testDuplicateParameter() { public void testDuplicateParameter() throws Exception {
Parameter parameter = Parameter.builder() Parameter parameter = Parameter.builder()
.domain(Parameter.Domain.QUERY)
.enableDuplicates() .enableDuplicates()
.add("Hello", "World") .add("Hello", "World")
.add("Hello", "World") .add("Hello", "World")
.add("Hello", "World") .add("Hello", "World")
.build(); .build();
assertNotNull(parameter); assertNotNull(parameter);
assertTrue(parameter.containsKey("Hello", Parameter.Domain.DEFAULT)); assertTrue(parameter.containsKey("Hello", Parameter.Domain.QUERY));
assertEquals(List.of("World", "World", "World"), parameter.getAll("Hello", Parameter.Domain.DEFAULT)); assertEquals(List.of("World", "World", "World"), parameter.getAll("Hello", Parameter.Domain.QUERY));
} }
@Test @Test
public void testHttpHeaderParameter() { public void testHttpHeaderParameter() throws Exception {
Parameter parameter = Parameter.builder() Parameter parameter = Parameter.builder()
.charset(StandardCharsets.US_ASCII) .charset(StandardCharsets.US_ASCII)
.lowercase() .lowercase()
@ -116,20 +118,20 @@ public class ParameterTest {
} }
@Test @Test
void testSimpleParse() { void testSimpleParse() throws Exception {
ParameterBuilder queryParameters = Parameter.builder(); ParameterBuilder queryParameters = Parameter.builder().domain(Parameter.Domain.QUERY);
String body = "a=b&c=d&e=f"; String body = "a=b&c=d&e=f";
queryParameters.addPercentEncodedBody(body); queryParameters.addPercentEncodedBody(body);
Parameter parameter = queryParameters.build(); Parameter parameter = queryParameters.build();
assertEquals("b", parameter.getAll("a", Parameter.Domain.DEFAULT).get(0)); assertEquals("b", parameter.getAll("a", Parameter.Domain.QUERY).get(0));
assertEquals("d", parameter.getAll("c", Parameter.Domain.DEFAULT).get(0)); assertEquals("d", parameter.getAll("c", Parameter.Domain.QUERY).get(0));
assertEquals("f", parameter.getAll("e", Parameter.Domain.DEFAULT).get(0)); assertEquals("f", parameter.getAll("e", Parameter.Domain.QUERY).get(0));
} }
@Test @Test
void testParseExceedingParamLimit() { void testParseExceedingParamLimit() {
Assertions.assertThrows(IllegalArgumentException.class, () -> { Assertions.assertThrows(IllegalArgumentException.class, () -> {
ParameterBuilder queryParameters = Parameter.builder().limit(100); ParameterBuilder queryParameters = Parameter.builder().domain(Parameter.Domain.QUERY).limit(100);
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
for (int i = 0; i < 200; i++) { for (int i = 0; i < 200; i++) {
list.add("a" + i + "=b" + i); list.add("a" + i + "=b" + i);
@ -137,18 +139,19 @@ public class ParameterTest {
String body = String.join("&", list); String body = String.join("&", list);
queryParameters.addPercentEncodedBody(body); queryParameters.addPercentEncodedBody(body);
Parameter parameter = queryParameters.build(); Parameter parameter = queryParameters.build();
assertEquals("b0", parameter.getAll("a0", Parameter.Domain.DEFAULT).get(0)); assertEquals("b0", parameter.getAll("a0", Parameter.Domain.QUERY).get(0));
assertEquals("b99", parameter.getAll("a99", Parameter.Domain.DEFAULT).get(0)); assertEquals("b99", parameter.getAll("a99", Parameter.Domain.QUERY).get(0));
assertEquals("[]", parameter.getAll("a100", Parameter.Domain.DEFAULT).toString()); assertEquals("[]", parameter.getAll("a100", Parameter.Domain.QUERY).toString());
}); });
} }
@Test @Test
void testDomains() { void testDomains() throws ParameterException {
Parameter p1 = Parameter.builder().domain(Parameter.Domain.QUERY).add("a", "a").build(); Parameter p1 = Parameter.builder().domain(Parameter.Domain.QUERY).add("a", "a").build();
Parameter p2 = Parameter.builder().domain(Parameter.Domain.FORM).add("b", "b").build(); Parameter p2 = Parameter.builder().domain(Parameter.Domain.FORM).add("b", "b").build();
Parameter p3 = Parameter.builder().domain(Parameter.Domain.HEADER).add("c", "c").build(); Parameter p3 = Parameter.builder().domain(Parameter.Domain.HEADER).add("c", "c").build();
Parameter p = Parameter.builder() Parameter p = Parameter.builder()
.domain(Parameter.Domain.QUERY)
.add(p1) .add(p1)
.add(p2) .add(p2)
.add(p3) .add(p3)
@ -162,6 +165,5 @@ public class ParameterTest {
assertTrue(p.isPresent(Parameter.Domain.QUERY)); assertTrue(p.isPresent(Parameter.Domain.QUERY));
assertTrue(p.isPresent(Parameter.Domain.FORM)); assertTrue(p.isPresent(Parameter.Domain.FORM));
assertTrue(p.isPresent(Parameter.Domain.HEADER)); assertTrue(p.isPresent(Parameter.Domain.HEADER));
assertFalse(p.isPresent(Parameter.Domain.DEFAULT));
} }
} }

View file

@ -327,7 +327,7 @@ class URLParserTest {
assertEquals("path", pathSegment.getSegment()); assertEquals("path", pathSegment.getSegment());
assertEquals("p2", pathSegment.getMatrixParams().get(0).getKey()); assertEquals("p2", pathSegment.getMatrixParams().get(0).getKey());
assertEquals("v2", pathSegment.getMatrixParams().get(0).getValue()); assertEquals("v2", pathSegment.getMatrixParams().get(0).getValue());
assertEquals("v3", url.getQueryParams().getAll("q1", Parameter.Domain.DEFAULT).get(0)); assertEquals("v3", url.getQueryParams().getAll("q1", Parameter.Domain.QUERY).get(0));
} }
@Test @Test