From a34c444aecd95650a46ddd836f144e815b329929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rg=20Prante?= Date: Sun, 30 Jul 2023 21:57:18 +0200 Subject: [PATCH] remove default domain, stricter security --- gradle.properties | 2 +- .../java/org/xbib/net/path/PathDecoder.java | 2 +- .../java/org/xbib/net/path/PathResolver.java | 5 +- .../org/xbib/net/path/simple/PathMatcher.java | 6 +- .../xbib/net/path/simple/PathResolver.java | 5 +- .../xbib/net/path/structure/PathResolver.java | 5 +- .../org/xbib/net/path/PathDecoderTest.java | 28 +++---- .../xbib/net/path/simple/PathMatcherTest.java | 30 ++++---- .../net/path/simple/PathResolverTest.java | 41 +++++----- .../net/path/structure/PathResolverTest.java | 35 +++++---- net/src/main/java/org/xbib/net/Parameter.java | 77 +++++++++++-------- .../java/org/xbib/net/ParameterBuilder.java | 2 +- .../java/org/xbib/net/ParameterException.java | 9 +++ .../main/java/org/xbib/net/URLBuilder.java | 3 +- .../test/java/org/xbib/net/ParameterTest.java | 36 +++++---- .../test/java/org/xbib/net/URLParserTest.java | 2 +- 16 files changed, 161 insertions(+), 127 deletions(-) create mode 100644 net/src/main/java/org/xbib/net/ParameterException.java diff --git a/gradle.properties b/gradle.properties index 8461118..a5b16aa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ group = org.xbib name = net -version = 3.2.0 +version = 3.3.0 org.gradle.warning.mode = ALL diff --git a/net-path/src/main/java/org/xbib/net/path/PathDecoder.java b/net-path/src/main/java/org/xbib/net/path/PathDecoder.java index 2d11d2c..11e9a7e 100644 --- a/net-path/src/main/java/org/xbib/net/path/PathDecoder.java +++ b/net-path/src/main/java/org/xbib/net/path/PathDecoder.java @@ -21,7 +21,7 @@ public class PathDecoder { String path = pos > 0 ? pathAndQuery.substring(0, pos) : pathAndQuery; this.query = pos > 0 ? pathAndQuery.substring(pos + 1) : null; this.path = PathNormalizer.normalize(path); - this.params = Parameter.builder().enablePercentDecoding(); + this.params = Parameter.builder().domain(Parameter.Domain.PATH).enablePercentDecoding(); if (query != null) { parse(query); } diff --git a/net-path/src/main/java/org/xbib/net/path/PathResolver.java b/net-path/src/main/java/org/xbib/net/path/PathResolver.java index b6a9aa5..d59d78f 100644 --- a/net-path/src/main/java/org/xbib/net/path/PathResolver.java +++ b/net-path/src/main/java/org/xbib/net/path/PathResolver.java @@ -1,10 +1,11 @@ package org.xbib.net.path; import org.xbib.net.Parameter; +import org.xbib.net.ParameterException; public interface PathResolver { - void resolve(String method, String path, ResultListener listener); + void resolve(String method, String path, ResultListener listener) throws ParameterException; interface Builder { @@ -25,7 +26,7 @@ public interface PathResolver { @FunctionalInterface interface ResultListener { - void onResult(Result result); + void onResult(Result result) throws ParameterException; } } diff --git a/net-path/src/main/java/org/xbib/net/path/simple/PathMatcher.java b/net-path/src/main/java/org/xbib/net/path/simple/PathMatcher.java index a95fd26..dccfb57 100644 --- a/net-path/src/main/java/org/xbib/net/path/simple/PathMatcher.java +++ b/net-path/src/main/java/org/xbib/net/path/simple/PathMatcher.java @@ -50,11 +50,11 @@ public class PathMatcher { } public Parameter extractUriTemplateVariables(String pattern, String path) { - ParameterBuilder queryParameters = Parameter.builder(); - if (!doMatch(pattern, path, true, queryParameters)) { + ParameterBuilder uriParameters = Parameter.builder().domain(Parameter.Domain.PATH); + if (!doMatch(pattern, path, true, uriParameters)) { throw new IllegalStateException("Pattern \"" + pattern + "\" is not a match for \"" + path + "\""); } - return queryParameters.build(); + return uriParameters.build(); } public PathComparator getPatternComparator(String path) { diff --git a/net-path/src/main/java/org/xbib/net/path/simple/PathResolver.java b/net-path/src/main/java/org/xbib/net/path/simple/PathResolver.java index aa80180..5ccbe79 100644 --- a/net-path/src/main/java/org/xbib/net/path/simple/PathResolver.java +++ b/net-path/src/main/java/org/xbib/net/path/simple/PathResolver.java @@ -2,6 +2,7 @@ package org.xbib.net.path.simple; import org.xbib.net.Parameter; import org.xbib.net.ParameterBuilder; +import org.xbib.net.ParameterException; import org.xbib.net.util.CharMatcher; import java.util.ArrayList; @@ -53,7 +54,7 @@ public class PathResolver implements org.xbib.net.path.PathResolver { * @param resultListener result listener */ @Override - public void resolve(String method, String path, ResultListener resultListener) { + public void resolve(String method, String path, ResultListener resultListener) throws ParameterException { Objects.requireNonNull(method, "method"); Objects.requireNonNull(path, "path"); resolve(method, builder.pathMatcher.tokenize(path), 0, new ArrayList<>(), resultListener); @@ -68,7 +69,7 @@ public class PathResolver implements org.xbib.net.path.PathResolver { List pathSegments, int index, List parameters, - ResultListener resultListener) { + ResultListener resultListener) throws ParameterException { if (index < pathSegments.size()) { String segment = pathSegments.get(index); PathResolver child = children.get(segment); diff --git a/net-path/src/main/java/org/xbib/net/path/structure/PathResolver.java b/net-path/src/main/java/org/xbib/net/path/structure/PathResolver.java index 7e70ac2..174dcbb 100644 --- a/net-path/src/main/java/org/xbib/net/path/structure/PathResolver.java +++ b/net-path/src/main/java/org/xbib/net/path/structure/PathResolver.java @@ -4,6 +4,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.xbib.net.Parameter; import org.xbib.net.ParameterBuilder; +import org.xbib.net.ParameterException; import org.xbib.net.PathNormalizer; import java.util.ArrayList; @@ -37,7 +38,7 @@ public class PathResolver implements org.xbib.net.path.PathResolver { } @Override - public void resolve(String method, String path, ResultListener listener) { + public void resolve(String method, String path, ResultListener listener) throws ParameterException { Objects.requireNonNull(method, "method"); Objects.requireNonNull(path, "path"); List pathSegments = PathMatcher.tokenize(PathNormalizer.normalize(path), @@ -54,7 +55,7 @@ public class PathResolver implements org.xbib.net.path.PathResolver { private ParameterBuilder resolve(List pathSegments, int index, ParameterBuilder parameterBuilder, - ResultListener listener) { + ResultListener listener) throws ParameterException { ParameterBuilder pb = parameterBuilder; if (index < pathSegments.size()) { PathSegment segment = pathSegments.get(index); diff --git a/net-path/src/test/java/org/xbib/net/path/PathDecoderTest.java b/net-path/src/test/java/org/xbib/net/path/PathDecoderTest.java index b13374a..0a5bb54 100644 --- a/net-path/src/test/java/org/xbib/net/path/PathDecoderTest.java +++ b/net-path/src/test/java/org/xbib/net/path/PathDecoderTest.java @@ -10,17 +10,17 @@ import static org.junit.jupiter.api.Assertions.assertNull; class PathDecoderTest { @Test - void testPlusSign() { + void testPlusSign() throws Exception { PathDecoder decoder = new PathDecoder("/path?a=b+c", "d=e+f"); - assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.DEFAULT).toString()); - assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.DEFAULT).toString()); + assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.PATH).toString()); + assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.PATH).toString()); } @Test - void testSlash() { + void testSlash() throws Exception { 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("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.DEFAULT).toString()); + assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.PATH).toString()); + assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.PATH).toString()); } @Test @@ -30,23 +30,23 @@ class PathDecoderTest { } @Test - void testSlashes() { + void testSlashes() throws Exception { PathDecoder decoder = new PathDecoder("//path?a=b+c", "d=e+f"); assertEquals("/path", decoder.path()); - assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.DEFAULT).toString()); - assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.DEFAULT).toString()); + assertEquals("[b c]", decoder.getParameter().getAll("a", Parameter.Domain.PATH).toString()); + assertEquals("[e f]", decoder.getParameter().getAll("d", Parameter.Domain.PATH).toString()); } @Test - void testPlusPercent() { + void testPlusPercent() throws Exception { PathDecoder decoder = new PathDecoder("//path?a=b%2Bc", "d=e%2Bf"); assertEquals("/path", decoder.path()); - assertEquals("[b+c]", decoder.getParameter().getAll("a", Parameter.Domain.DEFAULT).toString()); - assertEquals("[e+f]", decoder.getParameter().getAll("d", Parameter.Domain.DEFAULT).toString()); + assertEquals("[b+c]", decoder.getParameter().getAll("a", Parameter.Domain.PATH).toString()); + assertEquals("[e+f]", decoder.getParameter().getAll("d", Parameter.Domain.PATH).toString()); } @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-"; URL url = URL.builder().path(requestURI).build(); 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-]", 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()); } } diff --git a/net-path/src/test/java/org/xbib/net/path/simple/PathMatcherTest.java b/net-path/src/test/java/org/xbib/net/path/simple/PathMatcherTest.java index 7c3a1de..e6ee1e9 100644 --- a/net-path/src/test/java/org/xbib/net/path/simple/PathMatcherTest.java +++ b/net-path/src/test/java/org/xbib/net/path/simple/PathMatcherTest.java @@ -311,38 +311,38 @@ class PathMatcherTest { } @Test - void extractUriTemplateVariablesRegex() { + void extractUriTemplateVariablesRegex() throws Exception { Parameter result = pathMatcher.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-{version:[\\w\\.]+}.jar", "com.example-1.0.0.jar"); - assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0)); - assertEquals("1.0.0", result.getAll("version", 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.PATH).get(0)); result = pathMatcher.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-sources-{version:[\\w\\.]+}.jar", "com.example-sources-1.0.0.jar"); - assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0)); - assertEquals("1.0.0", result.getAll("version", 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.PATH).get(0)); } @Test - void extractUriTemplateVarsRegexQualifiers() { + void extractUriTemplateVarsRegexQualifiers() throws Exception { Parameter result = pathMatcher.extractUriTemplateVariables( "{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.]+}.jar", "com.example-sources-1.0.0.jar"); - assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0)); - assertEquals("1.0.0", result.getAll("version", 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.PATH).get(0)); result = pathMatcher.extractUriTemplateVariables( "{symbolicName:[\\w\\.]+}-sources-{version:[\\d\\.]+}-{year:\\d{4}}{month:\\d{2}}{day:\\d{2}}.jar", "com.example-sources-1.0.0-20100220.jar"); - assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0)); - assertEquals("1.0.0", result.getAll("version", Parameter.Domain.DEFAULT).get(0)); - assertEquals("2010", result.getAll("year", Parameter.Domain.DEFAULT).get(0)); - assertEquals("02", result.getAll("month", Parameter.Domain.DEFAULT).get(0)); - assertEquals("20", result.getAll("day", 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.PATH).get(0)); + assertEquals("2010", result.getAll("year", Parameter.Domain.PATH).get(0)); + assertEquals("02", result.getAll("month", Parameter.Domain.PATH).get(0)); + assertEquals("20", result.getAll("day", Parameter.Domain.PATH).get(0)); result = pathMatcher.extractUriTemplateVariables( "{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.\\{\\}]+}.jar", "com.example-sources-1.0.0.{12}.jar"); - assertEquals("com.example", result.getAll("symbolicName", Parameter.Domain.DEFAULT).get(0)); - assertEquals("1.0.0.{12}", result.getAll("version", 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.PATH).get(0)); } @Test diff --git a/net-path/src/test/java/org/xbib/net/path/simple/PathResolverTest.java b/net-path/src/test/java/org/xbib/net/path/simple/PathResolverTest.java index c35078b..a36fcdb 100644 --- a/net-path/src/test/java/org/xbib/net/path/simple/PathResolverTest.java +++ b/net-path/src/test/java/org/xbib/net/path/simple/PathResolverTest.java @@ -2,6 +2,7 @@ package org.xbib.net.path.simple; import org.junit.jupiter.api.Test; import org.xbib.net.Parameter; +import org.xbib.net.ParameterException; import java.util.Collections; import java.util.Map; @@ -18,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.fail; class PathResolverTest { @Test - void simple() { + void simple() throws ParameterException { PathResolver pathResolver = PathResolver.builder() .add("GET", "explorer", 1234) .build(); @@ -29,7 +30,7 @@ class PathResolverTest { } @Test - void name() { + void name() throws ParameterException { PathResolver pathResolver = PathResolver.builder() .add("GET", "/static/{file}", 1234) .add("HEAD", "/static/{file}", 1234) @@ -39,7 +40,7 @@ class PathResolverTest { } @Test - void glob() { + void glob() throws ParameterException { PathResolver trie = PathResolver.builder() .add("GET", "/static/**", 1234) .build(); @@ -48,7 +49,7 @@ class PathResolverTest { } @Test - void sharedPrefix() { + void sharedPrefix() throws ParameterException { PathResolver trie = PathResolver.builder() .add("GET", "discovery/v1/rest", 1234) .add("GET", "discovery/v2/rest", 4321) @@ -61,7 +62,7 @@ class PathResolverTest { } @Test - void prefix() { + void prefix() throws ParameterException { PathResolver trie = PathResolver.builder() .add("GET", "discovery", 1234) .add("GET", "discovery/v1", 4321) @@ -72,7 +73,7 @@ class PathResolverTest { } @Test - void parameter() { + void parameter() throws ParameterException { PathResolver trie = PathResolver.builder() .add("GET", "discovery/{version}/rest", 1234) .build(); @@ -81,7 +82,7 @@ class PathResolverTest { } @Test - void multipleParameters() { + void multipleParameters() throws ParameterException { PathResolver trie = PathResolver.builder() .add("GET", "discovery/{discovery_version}/apis/{api}/{format}", 1234) .build(); @@ -90,7 +91,7 @@ class PathResolverTest { } @Test - void sharedParameterPrefix() { + void sharedParameterPrefix() throws ParameterException { PathResolver trie = PathResolver.builder() .add("GET", "discovery/{version}/rest", 1234) .add("GET", "discovery/{version}/rpc", 4321) @@ -102,7 +103,7 @@ class PathResolverTest { } @Test - void testResolveParameterAfterLiteral() { + void testResolveParameterAfterLiteral() throws ParameterException { PathResolver trie = PathResolver.builder() .add("GET", "{one}/three", 1234) .add("GET", "one/two", 4321) @@ -112,7 +113,7 @@ class PathResolverTest { } @Test - void testResolveBacktrack() { + void testResolveBacktrack() throws ParameterException { PathResolver trie = PathResolver.builder() .add("GET", "{one}/{two}/three/{four}", 1234) .add("GET", "one/two/{three}/four", 4321) @@ -122,7 +123,7 @@ class PathResolverTest { } @Test - void pathMethodsWithDifferentParameterNames() { + void pathMethodsWithDifferentParameterNames() throws ParameterException { PathResolver trie = PathResolver.builder() .add("GET", "test/{one}", 1234) .add("PUT", "test/{two}", 4321) @@ -142,7 +143,7 @@ class PathResolverTest { } @Test - void laxDuplicatePath() { + void laxDuplicatePath() throws ParameterException { PathResolver pathResolver = PathResolver.builder(false) .add("GET", "test/{one}", 1234) .add("GET", "test/{two}", 4321) @@ -186,6 +187,8 @@ class PathResolverTest { fail("expected NullPointerException"); } catch (NullPointerException e) { // expected + } catch (ParameterException e) { + throw new RuntimeException(e); } } @@ -223,7 +226,7 @@ class PathResolverTest { } @Test - void testFallback() { + void testFallback() throws ParameterException { AtomicInteger counter = new AtomicInteger(0); org.xbib.net.path.PathResolver trie = PathResolver.builder() .add("GET", "/test/{one}", 1) @@ -247,16 +250,16 @@ class PathResolverTest { } } - private void assertSuccessfulGetResolution(PathResolver trie, String path, Integer value) { + private void assertSuccessfulGetResolution(PathResolver trie, String path, Integer value) throws ParameterException { assertSuccessfulResolution(trie, "GET", path, value); } - private void assertSuccessfulResolution(PathResolver trie, String method, String path, Integer value) { + private void assertSuccessfulResolution(PathResolver trie, String method, String path, Integer value) throws ParameterException { assertSuccessfulResolution(trie, method, path, Set.of(value), Collections.emptyMap()); } private void assertSuccessfulGetResolution(PathResolver trie, String path, Integer value, - Map rawParameters) { + Map rawParameters) throws ParameterException { assertSuccessfulResolution(trie, "GET", path, Set.of(value), rawParameters); } @@ -264,18 +267,18 @@ class PathResolverTest { String method, String path, Set values, - Map rawParameters) { + Map rawParameters) throws ParameterException { trie.resolve(method, path, result -> { assertTrue(values.contains(result.getValue())); //assertThat(result.getRawParameters(), is(rawParameters)); }); } - private void assertFailedGetResolution(PathResolver trie, String path) { + private void assertFailedGetResolution(PathResolver trie, String path) throws ParameterException { assertFailedGetResolution(trie, "GET", path); } - private void assertFailedGetResolution(PathResolver trie, String method, String path) { + private void assertFailedGetResolution(PathResolver trie, String method, String path) throws ParameterException { trie.resolve(method, path, r-> { fail(); }); } } diff --git a/net-path/src/test/java/org/xbib/net/path/structure/PathResolverTest.java b/net-path/src/test/java/org/xbib/net/path/structure/PathResolverTest.java index 6b5696b..271c69c 100644 --- a/net-path/src/test/java/org/xbib/net/path/structure/PathResolverTest.java +++ b/net-path/src/test/java/org/xbib/net/path/structure/PathResolverTest.java @@ -3,6 +3,7 @@ package org.xbib.net.path.structure; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.xbib.net.Parameter; +import org.xbib.net.ParameterException; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; @@ -20,7 +21,7 @@ import static org.junit.jupiter.api.Assertions.fail; class PathResolverTest { @Test - void example() { + void example() throws ParameterException { PathResolver pathResolver = PathResolver.builder() .add( "GET", "/static/{file}", 1234) .build(); @@ -29,7 +30,7 @@ class PathResolverTest { } @Test - void simple() { + void simple() throws ParameterException { PathResolver pathResolver = PathResolver.builder() .add("GET", "explorer", 1234) .build(); @@ -39,7 +40,7 @@ class PathResolverTest { } @Test - void sharedPrefix() { + void sharedPrefix() throws ParameterException { PathResolver pathResolver = PathResolver.builder() .add("GET", "discovery/v1/rest", 1234) .add("GET", "discovery/v2/rest", 4321) @@ -52,7 +53,7 @@ class PathResolverTest { } @Test - void prefix() { + void prefix() throws ParameterException { PathResolver pathResolver = PathResolver.builder() .add("GET", "discovery", 1234) .add("GET", "discovery/v1", 4321) @@ -63,7 +64,7 @@ class PathResolverTest { } @Test - void parameter() { + void parameter() throws ParameterException { PathResolver pathResolver = PathResolver.builder() .add("GET", "discovery/{version}/rest", 1234) .build(); @@ -72,7 +73,7 @@ class PathResolverTest { } @Test - void multipleParameters() { + void multipleParameters() throws ParameterException { PathResolver pathResolver = PathResolver.builder() .add("GET", "discovery/{discovery_version}/apis/{api}/{format}", 1234) .build(); @@ -81,7 +82,7 @@ class PathResolverTest { } @Test - void sharedParameterPrefix() { + void sharedParameterPrefix() throws ParameterException { PathResolver pathResolver = PathResolver.builder() .add("GET", "discovery/{version}/rest", 1234) .add("GET", "discovery/{version}/rpc", 4321) @@ -97,7 +98,7 @@ class PathResolverTest { } @Test - void testResolveParameterAfterLiteral() { + void testResolveParameterAfterLiteral() throws ParameterException { PathResolver pathResolver = PathResolver.builder() .add("GET", "{one}/three", 1234) .add("GET", "one/two", 4321) @@ -108,7 +109,7 @@ class PathResolverTest { } @Test - void testResolveBacktrack() { + void testResolveBacktrack() throws ParameterException { PathResolver pathResolver = PathResolver.builder() .add("GET", "{one}/{two}/three/{four}", 1234) .add("GET", "one/two/{three}/four", 4321) @@ -128,7 +129,7 @@ class PathResolverTest { } @Test - void pathMethodsWithDifferentParameterNames() { + void pathMethodsWithDifferentParameterNames() throws ParameterException { PathResolver pathResolver = PathResolver.builder() .add("GET", "test/{one}", 1234) .add("GET", "test/{two}", 4321) @@ -148,7 +149,7 @@ class PathResolverTest { } @Test - void duplicatePathParams() { + void duplicatePathParams() throws ParameterException { PathResolver pathResolver = PathResolver.builder() .add("GET", "test/{one}", 1234) .add("GET", "test/{two}", 4321) @@ -197,11 +198,13 @@ class PathResolverTest { fail("expected NullPointerException"); } catch (NullPointerException e) { // expected + } catch (ParameterException e) { + throw new RuntimeException(e); } } @Test - void testFallback() { + void testFallback() throws ParameterException { AtomicInteger counter = new AtomicInteger(0); PathResolver trie = PathResolver.builder() .add( "GET", "/test/{one}", 1) @@ -216,7 +219,7 @@ class PathResolverTest { @Disabled @Test - void testSuffixCatchAll() { + void testSuffixCatchAll() throws ParameterException { AtomicInteger counter = new AtomicInteger(0); PathResolver trie = PathResolver.builder() .add( "GET", "/**/*.test", 1) @@ -229,12 +232,12 @@ class PathResolverTest { assertThat(counter.get(), equalTo(2)); } - private void assertSuccessfulResolution(PathResolver pathResolver, String path, Integer value) { + private void assertSuccessfulResolution(PathResolver pathResolver, String path, Integer value) throws ParameterException { assertSuccessfulResolution(pathResolver, "GET", path, value, Parameter.builder().domain(Parameter.Domain.PATH).build()); } private void assertSuccessfulResolution(PathResolver pathResolver, String method, String path, Integer value, - Parameter parameter) { + Parameter parameter) throws ParameterException { AtomicBoolean found = new AtomicBoolean(false); pathResolver.resolve(method, path, result -> { assertThat(result, notNullValue()); @@ -246,7 +249,7 @@ class PathResolverTest { assertTrue(found.get()); } - private void assertFailedGetResolution(PathResolver pathResolver, String path) { + private void assertFailedGetResolution(PathResolver pathResolver, String path) throws ParameterException { pathResolver.resolve("GET", path, r -> assertThat(r, nullValue())); } } diff --git a/net/src/main/java/org/xbib/net/Parameter.java b/net/src/main/java/org/xbib/net/Parameter.java index d8edafd..04c8bc6 100644 --- a/net/src/main/java/org/xbib/net/Parameter.java +++ b/net/src/main/java/org/xbib/net/Parameter.java @@ -16,7 +16,7 @@ import org.xbib.datastructures.common.Pair; public class Parameter implements Iterable>, Comparable { public enum Domain { - DEFAULT, + UNDEFINED, QUERY, FORM, PATH, @@ -92,7 +92,7 @@ public class Parameter implements Iterable>, Comparable collection = (Collection) object; @@ -108,7 +108,7 @@ public class Parameter implements Iterable>, Comparable collection = (Collection) object; @@ -128,7 +128,7 @@ public class Parameter implements Iterable>, Comparable collection = (Collection) object; @@ -147,49 +147,35 @@ public class Parameter implements Iterable>, Comparable sb.append(" ").append(key).append(" -> ").append(value)); - return sb.toString(); - } - public boolean hasElements() { return !list.isEmpty(); } - public MultiMap asMultiMap() { + public MultiMap asMultiMap() throws ParameterException{ + if (getDomain() == Domain.UNDEFINED) { + throw new ParameterException("undefined domain"); + } MultiMap multiMap = new LinkedHashSetMultiMap<>(); this.forEach(p -> multiMap.put(p.getKey(), p.getValue())); return multiMap; } - public Map asSingleValuedMap() { + public Map asSingleValuedMap() throws ParameterException { + if (getDomain() == Domain.UNDEFINED) { + throw new ParameterException("undefined domain"); + } Map map = new LinkedHashMap<>(); this.forEach(p -> map.put(p.getKey(), createValue(p.getValue()))); return map; } - @SuppressWarnings("unchecked") - private static Object createValue(Object object) { - if (object instanceof Collection) { - Collection collection = (Collection) object; - if (collection.size() == 1) { - return collection.iterator().next(); - } else { - return collection; - } - } - return object; - } - - public List getAllDomain(Domain domain) { + public List getAllInDomain(Domain domain) { Parameter parameter = null; if (builder.parameterMap.containsKey(domain)) { parameter = builder.parameterMap.get(domain); } if (parameter != null) { - return parameter.getAllDomain(domain); + return parameter.getAllInDomain(domain); } if (getDomain().equals(domain)) { return list.stream() @@ -213,7 +199,10 @@ public class Parameter implements Iterable>, Comparable>, Comparable getAll(String key, Domain domain) { + public List getAll(String key, Domain domain) throws Exception { + if (getDomain() == Domain.UNDEFINED) { + throw new ParameterException("undefined domain"); + } Parameter parameter = null; if (builder.parameterMap.containsKey(domain)) { parameter = builder.parameterMap.get(domain); @@ -255,7 +247,10 @@ public class Parameter implements Iterable>, Comparable>, Comparable sb.append(" ").append(key).append(" -> ").append(value)); + return sb.toString(); + } + + @SuppressWarnings("unchecked") + private static Object createValue(Object object) { + if (object instanceof Collection) { + Collection collection = (Collection) object; + if (collection.size() == 1) { + return collection.iterator().next(); + } else { + return collection; + } + } + return object; + } } diff --git a/net/src/main/java/org/xbib/net/ParameterBuilder.java b/net/src/main/java/org/xbib/net/ParameterBuilder.java index 838b010..8fea99a 100644 --- a/net/src/main/java/org/xbib/net/ParameterBuilder.java +++ b/net/src/main/java/org/xbib/net/ParameterBuilder.java @@ -65,7 +65,7 @@ public class ParameterBuilder implements PairValidator { ParameterBuilder() { this.list = new ArrayList<>(); this.parameterMap = new HashMap<>(); - this.domain = Parameter.Domain.DEFAULT; + this.domain = Parameter.Domain.UNDEFINED; this.limit = 0; } diff --git a/net/src/main/java/org/xbib/net/ParameterException.java b/net/src/main/java/org/xbib/net/ParameterException.java new file mode 100644 index 0000000..f40008d --- /dev/null +++ b/net/src/main/java/org/xbib/net/ParameterException.java @@ -0,0 +1,9 @@ +package org.xbib.net; + +@SuppressWarnings("serial") +public class ParameterException extends Exception { + + public ParameterException(String message) { + super(message); + } +} diff --git a/net/src/main/java/org/xbib/net/URLBuilder.java b/net/src/main/java/org/xbib/net/URLBuilder.java index bf499fd..d65792d 100644 --- a/net/src/main/java/org/xbib/net/URLBuilder.java +++ b/net/src/main/java/org/xbib/net/URLBuilder.java @@ -82,7 +82,7 @@ public class URLBuilder { .onMalformedInput(codingErrorAction) .onUnmappableCharacter(codingErrorAction); this.percentDecoder = new PercentDecoder(charsetDecoder); - this.queryParams = Parameter.builder(); + this.queryParams = Parameter.builder().domain(Parameter.Domain.QUERY); return this; } @@ -301,7 +301,6 @@ public class URLBuilder { } } - /** * A path segment with associated matrix params, if any. */ diff --git a/net/src/test/java/org/xbib/net/ParameterTest.java b/net/src/test/java/org/xbib/net/ParameterTest.java index 23821e7..4e959b0 100644 --- a/net/src/test/java/org/xbib/net/ParameterTest.java +++ b/net/src/test/java/org/xbib/net/ParameterTest.java @@ -17,33 +17,35 @@ public class ParameterTest { public void testEmptyBuilder() { Parameter parameter = Parameter.builder().build(); assertNotNull(parameter); - assertFalse(parameter.containsKey("param1", Parameter.Domain.DEFAULT)); + assertFalse(parameter.containsKey("param1", Parameter.Domain.UNDEFINED)); } @Test public void testSingleParameter() { Parameter parameter = Parameter.builder() + .domain(Parameter.Domain.QUERY) .add("Hello", "World") .build(); assertNotNull(parameter); - assertTrue(parameter.containsKey("Hello", Parameter.Domain.DEFAULT)); + assertTrue(parameter.containsKey("Hello", Parameter.Domain.QUERY)); } @Test - public void testDuplicateParameter() { + public void testDuplicateParameter() throws Exception { Parameter parameter = Parameter.builder() + .domain(Parameter.Domain.QUERY) .enableDuplicates() .add("Hello", "World") .add("Hello", "World") .add("Hello", "World") .build(); assertNotNull(parameter); - assertTrue(parameter.containsKey("Hello", Parameter.Domain.DEFAULT)); - assertEquals(List.of("World", "World", "World"), parameter.getAll("Hello", Parameter.Domain.DEFAULT)); + assertTrue(parameter.containsKey("Hello", Parameter.Domain.QUERY)); + assertEquals(List.of("World", "World", "World"), parameter.getAll("Hello", Parameter.Domain.QUERY)); } @Test - public void testHttpHeaderParameter() { + public void testHttpHeaderParameter() throws Exception { Parameter parameter = Parameter.builder() .charset(StandardCharsets.US_ASCII) .lowercase() @@ -116,20 +118,20 @@ public class ParameterTest { } @Test - void testSimpleParse() { - ParameterBuilder queryParameters = Parameter.builder(); + void testSimpleParse() throws Exception { + ParameterBuilder queryParameters = Parameter.builder().domain(Parameter.Domain.QUERY); String body = "a=b&c=d&e=f"; queryParameters.addPercentEncodedBody(body); Parameter parameter = queryParameters.build(); - assertEquals("b", parameter.getAll("a", Parameter.Domain.DEFAULT).get(0)); - assertEquals("d", parameter.getAll("c", Parameter.Domain.DEFAULT).get(0)); - assertEquals("f", parameter.getAll("e", Parameter.Domain.DEFAULT).get(0)); + assertEquals("b", parameter.getAll("a", Parameter.Domain.QUERY).get(0)); + assertEquals("d", parameter.getAll("c", Parameter.Domain.QUERY).get(0)); + assertEquals("f", parameter.getAll("e", Parameter.Domain.QUERY).get(0)); } @Test void testParseExceedingParamLimit() { Assertions.assertThrows(IllegalArgumentException.class, () -> { - ParameterBuilder queryParameters = Parameter.builder().limit(100); + ParameterBuilder queryParameters = Parameter.builder().domain(Parameter.Domain.QUERY).limit(100); List list = new ArrayList<>(); for (int i = 0; i < 200; i++) { list.add("a" + i + "=b" + i); @@ -137,18 +139,19 @@ public class ParameterTest { String body = String.join("&", list); queryParameters.addPercentEncodedBody(body); Parameter parameter = queryParameters.build(); - assertEquals("b0", parameter.getAll("a0", Parameter.Domain.DEFAULT).get(0)); - assertEquals("b99", parameter.getAll("a99", Parameter.Domain.DEFAULT).get(0)); - assertEquals("[]", parameter.getAll("a100", Parameter.Domain.DEFAULT).toString()); + assertEquals("b0", parameter.getAll("a0", Parameter.Domain.QUERY).get(0)); + assertEquals("b99", parameter.getAll("a99", Parameter.Domain.QUERY).get(0)); + assertEquals("[]", parameter.getAll("a100", Parameter.Domain.QUERY).toString()); }); } @Test - void testDomains() { + void testDomains() throws ParameterException { 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 p3 = Parameter.builder().domain(Parameter.Domain.HEADER).add("c", "c").build(); Parameter p = Parameter.builder() + .domain(Parameter.Domain.QUERY) .add(p1) .add(p2) .add(p3) @@ -162,6 +165,5 @@ public class ParameterTest { assertTrue(p.isPresent(Parameter.Domain.QUERY)); assertTrue(p.isPresent(Parameter.Domain.FORM)); assertTrue(p.isPresent(Parameter.Domain.HEADER)); - assertFalse(p.isPresent(Parameter.Domain.DEFAULT)); } } diff --git a/net/src/test/java/org/xbib/net/URLParserTest.java b/net/src/test/java/org/xbib/net/URLParserTest.java index 2c872c1..db59182 100644 --- a/net/src/test/java/org/xbib/net/URLParserTest.java +++ b/net/src/test/java/org/xbib/net/URLParserTest.java @@ -327,7 +327,7 @@ class URLParserTest { assertEquals("path", pathSegment.getSegment()); assertEquals("p2", pathSegment.getMatrixParams().get(0).getKey()); 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