diff --git a/src/main/java/org/takes/facets/fallback/FbLog4j.java b/src/main/java/org/takes/facets/fallback/FbLog4j.java index 14c7f8f7d..df426b898 100644 --- a/src/main/java/org/takes/facets/fallback/FbLog4j.java +++ b/src/main/java/org/takes/facets/fallback/FbLog4j.java @@ -29,8 +29,8 @@ import org.cactoos.bytes.BytesOf; import org.cactoos.text.TextOf; import org.takes.misc.Opt; +import org.takes.rq.RqBaseMethod; import org.takes.rq.RqHref; -import org.takes.rq.RqMethod; /** * Fallback that logs all problems through Log4J. @@ -60,7 +60,7 @@ private static void log(final RqFallback req) throws IOException { Logger.getLogger(FbLog4j.class).error( String.format( "%s %s failed with %s: %s", - new RqMethod.Base(req).method(), + new RqBaseMethod(req).method(), new RqHref.Base(req).href(), req.code(), new TextOf(new BytesOf(req.throwable())) diff --git a/src/main/java/org/takes/facets/fallback/FbSlf4j.java b/src/main/java/org/takes/facets/fallback/FbSlf4j.java index 0e151fe8e..573463d74 100644 --- a/src/main/java/org/takes/facets/fallback/FbSlf4j.java +++ b/src/main/java/org/takes/facets/fallback/FbSlf4j.java @@ -30,8 +30,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.takes.misc.Opt; +import org.takes.rq.RqBaseMethod; import org.takes.rq.RqHref; -import org.takes.rq.RqMethod; /** * Fallback that logs all problems through SFL4J. @@ -68,7 +68,7 @@ public FbSlf4j() { private static void log(final RqFallback req) throws IOException { FbSlf4j.LOGGER.error( "{} {} failed with {}: {}", - new RqMethod.Base(req).method(), + new RqBaseMethod(req).method(), new RqHref.Base(req).href(), req.code(), new TextOf(new BytesOf(req.throwable())) diff --git a/src/main/java/org/takes/facets/fallback/TkFallback.java b/src/main/java/org/takes/facets/fallback/TkFallback.java index 81080fadd..6dd789b9d 100644 --- a/src/main/java/org/takes/facets/fallback/TkFallback.java +++ b/src/main/java/org/takes/facets/fallback/TkFallback.java @@ -34,8 +34,8 @@ import org.takes.Response; import org.takes.Take; import org.takes.misc.Opt; +import org.takes.rq.RqBaseMethod; import org.takes.rq.RqHref; -import org.takes.rq.RqMethod; import org.takes.rs.ResponseOf; import org.takes.tk.TkWrap; @@ -231,7 +231,7 @@ private static Throwable error(final Throwable exp, final Request req, return new IllegalStateException( String.format( "[%s %s] failed in %s: %s", - new RqMethod.Base(req).method(), + new RqBaseMethod(req).method(), new RqHref.Base(req).href(), time, TkFallback.msg(exp) ), diff --git a/src/main/java/org/takes/facets/fork/FkMethods.java b/src/main/java/org/takes/facets/fork/FkMethods.java index 63d362df7..fa08b1e89 100644 --- a/src/main/java/org/takes/facets/fork/FkMethods.java +++ b/src/main/java/org/takes/facets/fork/FkMethods.java @@ -31,7 +31,7 @@ import org.takes.Response; import org.takes.Take; import org.takes.misc.Opt; -import org.takes.rq.RqMethod; +import org.takes.rq.RqBaseMethod; import org.takes.tk.TkFixed; /** @@ -94,7 +94,7 @@ public FkMethods(final Collection mtds, final Take tke) { @Override public Opt route(final Request req) throws Exception { - final String mtd = new RqMethod.Base(req).method(); + final String mtd = new RqBaseMethod(req).method(); final Opt resp; if (this.methods.contains(mtd)) { resp = new Opt.Single<>(this.take.act(req)); diff --git a/src/main/java/org/takes/rq/RqBaseMethod.java b/src/main/java/org/takes/rq/RqBaseMethod.java new file mode 100644 index 000000000..ccb91d31c --- /dev/null +++ b/src/main/java/org/takes/rq/RqBaseMethod.java @@ -0,0 +1,67 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2014-2024 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.takes.rq; + +import java.io.IOException; +import java.util.Locale; +import java.util.regex.Pattern; +import lombok.EqualsAndHashCode; +import org.takes.Request; + +/** + * Request decorator, for HTTP method parsing. + * + *

The class is immutable and thread-safe. + * + * @since 0.13.7 + */ +@EqualsAndHashCode(callSuper = true) +public final class RqBaseMethod extends RqWrap implements RqMethod { + + /** + * HTTP token separators which are not already excluded by PATTERN. + */ + private static final Pattern SEPARATORS = Pattern.compile( + "[()<>@,;:\\\"/\\[\\]?={}]" + ); + + /** + * Ctor. + * @param req Original request + */ + public RqBaseMethod(final Request req) { + super(req); + } + + @Override + public String method() throws IOException { + final String method = new RqRequestLine.Base(this).method(); + if (RqBaseMethod.SEPARATORS.matcher(method).find()) { + throw new IOException( + String.format("Invalid HTTP method: %s", method) + ); + } + return method.toUpperCase(Locale.ENGLISH); + } +} diff --git a/src/main/java/org/takes/rq/RqMethod.java b/src/main/java/org/takes/rq/RqMethod.java index 4fd4c9adc..f285fffb3 100644 --- a/src/main/java/org/takes/rq/RqMethod.java +++ b/src/main/java/org/takes/rq/RqMethod.java @@ -24,9 +24,6 @@ package org.takes.rq; import java.io.IOException; -import java.util.Locale; -import java.util.regex.Pattern; -import lombok.EqualsAndHashCode; import org.takes.Request; /** @@ -89,42 +86,4 @@ public interface RqMethod extends Request { * @throws IOException If fails */ String method() throws IOException; - - /** - * Request decorator, for HTTP method parsing. - * - *

The class is immutable and thread-safe. - * - * @since 0.13.7 - */ - @EqualsAndHashCode(callSuper = true) - final class Base extends RqWrap implements RqMethod { - - /** - * HTTP token separators which are not already excluded by PATTERN. - */ - private static final Pattern SEPARATORS = Pattern.compile( - "[()<>@,;:\\\"/\\[\\]?={}]" - ); - - /** - * Ctor. - * @param req Original request - */ - public Base(final Request req) { - super(req); - } - - @Override - public String method() throws IOException { - final String method = new RqRequestLine.Base(this) - .method(); - if (Base.SEPARATORS.matcher(method).find()) { - throw new IOException( - String.format("Invalid HTTP method: %s", method) - ); - } - return method.toUpperCase(Locale.ENGLISH); - } - } } diff --git a/src/main/java/org/takes/servlet/HttpServletRequestFake.java b/src/main/java/org/takes/servlet/HttpServletRequestFake.java index 1988aab45..699a8f79c 100644 --- a/src/main/java/org/takes/servlet/HttpServletRequestFake.java +++ b/src/main/java/org/takes/servlet/HttpServletRequestFake.java @@ -50,9 +50,9 @@ import java.util.Map; import java.util.NoSuchElementException; import org.takes.Request; +import org.takes.rq.RqBaseMethod; import org.takes.rq.RqHeaders; import org.takes.rq.RqHref; -import org.takes.rq.RqMethod; /** * Fake HttpServletRequest (for unit tests). @@ -123,7 +123,7 @@ public Enumeration getHeaderNames() { @Override public String getMethod() { try { - return new RqMethod.Base(this.request).method(); + return new RqBaseMethod(this.request).method(); } catch (final IOException ex) { throw new IllegalArgumentException( "Failed to get method from the request", diff --git a/src/main/java/org/takes/tk/TkProxy.java b/src/main/java/org/takes/tk/TkProxy.java index 442c1afd0..293495746 100644 --- a/src/main/java/org/takes/tk/TkProxy.java +++ b/src/main/java/org/takes/tk/TkProxy.java @@ -35,9 +35,9 @@ import org.takes.Request; import org.takes.Response; import org.takes.Take; +import org.takes.rq.RqBaseMethod; import org.takes.rq.RqHeaders; import org.takes.rq.RqLengthAware; -import org.takes.rq.RqMethod; import org.takes.rq.RqPrint; import org.takes.rq.RqRequestLine; import org.takes.rs.RsWithBody; @@ -130,7 +130,7 @@ public Response act(final Request req) throws Exception { @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") private com.jcabi.http.Request request(final Request req, final URI dest) throws Exception { - final String method = new RqMethod.Base(req).method(); + final String method = new RqBaseMethod(req).method(); com.jcabi.http.Request proxied = new JdkRequest(dest).method(method); final RqHeaders headers = new RqHeaders.Base(req); for (final String name : headers.names()) { diff --git a/src/main/java/org/takes/tk/TkSlf4j.java b/src/main/java/org/takes/tk/TkSlf4j.java index 279b7a743..b1dc114ba 100644 --- a/src/main/java/org/takes/tk/TkSlf4j.java +++ b/src/main/java/org/takes/tk/TkSlf4j.java @@ -38,8 +38,8 @@ import org.takes.Request; import org.takes.Response; import org.takes.Take; +import org.takes.rq.RqBaseMethod; import org.takes.rq.RqHref; -import org.takes.rq.RqMethod; /** * Logs Take.act() calls. @@ -100,7 +100,7 @@ public Response act(final Request req) throws Exception { new TextOf(" "), new FormattedText( "[%s %s]", - new RqMethod.Base(req).method(), + new RqBaseMethod(req).method(), new RqHref.Base(req).href() ), new FormattedText(params.getKey(), params.getValue()), diff --git a/src/main/java/org/takes/tk/TkVerbose.java b/src/main/java/org/takes/tk/TkVerbose.java index eab847287..426e684d7 100644 --- a/src/main/java/org/takes/tk/TkVerbose.java +++ b/src/main/java/org/takes/tk/TkVerbose.java @@ -27,8 +27,8 @@ import lombok.ToString; import org.takes.HttpException; import org.takes.Take; +import org.takes.rq.RqBaseMethod; import org.takes.rq.RqHref; -import org.takes.rq.RqMethod; /** * Take that makes all not-found exceptions location aware. @@ -55,7 +55,7 @@ public TkVerbose(final Take take) { ex.code(), String.format( "%s %s", - new RqMethod.Base(request).method(), + new RqBaseMethod(request).method(), new RqHref.Base(request).href() ), ex diff --git a/src/test/java/org/takes/rq/RqMethodTest.java b/src/test/java/org/takes/rq/RqMethodTest.java index 4c74634b6..794c804f2 100644 --- a/src/test/java/org/takes/rq/RqMethodTest.java +++ b/src/test/java/org/takes/rq/RqMethodTest.java @@ -39,7 +39,7 @@ final class RqMethodTest { @Test void returnsMethod() throws IOException { MatcherAssert.assertThat( - new RqMethod.Base(new RqFake(RqMethod.POST)).method(), + new RqBaseMethod(new RqFake(RqMethod.POST)).method(), Matchers.equalTo(RqMethod.POST) ); } @@ -55,7 +55,7 @@ void supportsAllStandardMethods() throws IOException { ) ) { MatcherAssert.assertThat( - new RqMethod.Base(new RqFake(method)).method(), + new RqBaseMethod(new RqFake(method)).method(), Matchers.equalTo(method) ); } @@ -65,14 +65,14 @@ void supportsAllStandardMethods() throws IOException { void supportsExtensionMethods() throws IOException { final String method = "CUSTOM"; MatcherAssert.assertThat( - new RqMethod.Base(new RqFake(method)).method(), + new RqBaseMethod(new RqFake(method)).method(), Matchers.equalTo(method) ); } @Test void failsOnMissingUri() { - final RqMethod.Base req = new RqMethod.Base( + final RqBaseMethod req = new RqBaseMethod( new RqSimple(Arrays.asList("GET"), null) ); Assertions.assertThrows( @@ -85,7 +85,7 @@ void failsOnMissingUri() { void failsOnExtraLineElement() { Assertions.assertThrows( IOException.class, - () -> new RqMethod.Base( + () -> new RqBaseMethod( new RqSimple(Arrays.asList("GET / HTTP/1.1 abc"), null) ).method() ); @@ -95,7 +95,7 @@ void failsOnExtraLineElement() { void failsOnExtraSpaces() { Assertions.assertThrows( IOException.class, - () -> new RqMethod.Base( + () -> new RqBaseMethod( new RqSimple(Arrays.asList("GET / HTTP/1.1"), null) ).method() ); @@ -105,7 +105,7 @@ void failsOnExtraSpaces() { void failsOnSeparatorsInExtensionMethod() { Assertions.assertThrows( IOException.class, - () -> new RqMethod.Base(new RqFake("CUSTO{M)")).method() + () -> new RqBaseMethod(new RqFake("CUSTO{M)")).method() ); } } diff --git a/src/test/java/org/takes/tk/TkProxyTest.java b/src/test/java/org/takes/tk/TkProxyTest.java index da8e653e6..ccdc18655 100644 --- a/src/test/java/org/takes/tk/TkProxyTest.java +++ b/src/test/java/org/takes/tk/TkProxyTest.java @@ -43,6 +43,7 @@ import org.takes.facets.fork.FkMethods; import org.takes.facets.fork.TkFork; import org.takes.http.FtRemote; +import org.takes.rq.RqBaseMethod; import org.takes.rq.RqFake; import org.takes.rq.RqHref; import org.takes.rq.RqMethod; @@ -277,7 +278,7 @@ void addsAllInitialHeaders() throws Exception { } private static Request createEchoRequest(final Request req) throws IOException { - final String method = new RqMethod.Base(req).method(); + final String method = new RqBaseMethod(req).method(); return TkProxyTest.NOBODIES.getOrDefault(method, rq -> req).create(req); }