]> source.dussan.org Git - sonarqube.git/commitdiff
Fix WS routing
authorJulien HENRY <julien.henry@sonarsource.com>
Tue, 3 Apr 2018 12:27:43 +0000 (14:27 +0200)
committerSonarTech <sonartech@sonarsource.com>
Wed, 4 Apr 2018 13:18:42 +0000 (15:18 +0200)
When a regular WS path is a suffix of a "ServletFilter" path, the regular WS can't be reached.

server/sonar-server/src/main/java/org/sonar/server/ws/WebServiceFilter.java
server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceFilterTest.java
sonar-plugin-api/src/main/java/org/sonar/api/web/ServletFilter.java
sonar-plugin-api/src/test/java/org/sonar/api/web/ServletFilterTest.java

index 4691c046295637767964797e9e54cb663cb5085c..1efd88c106525c1d7160f4fba7c35834ea5f99ca 100644 (file)
@@ -95,7 +95,7 @@ public class WebServiceFilter extends ServletFilter {
   }
 
   private static Function<WebService.Action, String> toPath() {
-    return action -> "/" + action.path() + "/*";
+    return action -> "/" + action.path() + ".*";
   }
 
 }
index a7d5969a97e76d3d4c1153fd9f0cdf3034f05be4..b2c7c21c3597757eda04effb7f22d4e54c088934 100644 (file)
@@ -62,7 +62,7 @@ public class WebServiceFilterTest {
   }
 
   @Test
-  public void match_declared_web_services() {
+  public void match_declared_web_services_with_optional_suffix() {
     initWebServiceEngine(
       newWsUrl("api/issues", "search"),
       newWsUrl("batch", "index"));
@@ -70,6 +70,7 @@ public class WebServiceFilterTest {
     assertThat(underTest.doGetPattern().matches("/api/issues/search")).isTrue();
     assertThat(underTest.doGetPattern().matches("/api/issues/search.protobuf")).isTrue();
     assertThat(underTest.doGetPattern().matches("/batch/index")).isTrue();
+    assertThat(underTest.doGetPattern().matches("/batch/index.protobuf")).isTrue();
 
     assertThat(underTest.doGetPattern().matches("/foo")).isFalse();
   }
@@ -89,6 +90,16 @@ public class WebServiceFilterTest {
     assertThat(underTest.doGetPattern().matches("/api/authentication/login")).isFalse();
   }
 
+  @Test
+  public void does_not_match_servlet_filter_that_prefix_a_ws() {
+    initWebServiceEngine(
+        newWsUrl("api/foo", "action").setHandler(ServletFilterHandler.INSTANCE),
+        newWsUrl("api/foo", "action_2"));
+
+    assertThat(underTest.doGetPattern().matches("/api/foo/action")).isFalse();
+    assertThat(underTest.doGetPattern().matches("/api/foo/action_2")).isTrue();
+  }
+
   @Test
   public void does_not_match_api_properties_ws() {
     initWebServiceEngine(newWsUrl("api/properties", "index"));
index 5fd7540ac1def5f3c5d000a952a9526682a87528..93e549358ddb34b368f8c2103bd1c65ed0389ccb 100644 (file)
@@ -35,6 +35,7 @@ import org.sonar.api.server.ServerSide;
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Arrays.asList;
 import static java.util.Collections.unmodifiableList;
+import static org.apache.commons.lang.StringUtils.substringBeforeLast;
 
 /**
  * @since 3.1
@@ -160,7 +161,8 @@ public abstract class ServletFilter implements Filter {
       /**
        * Add inclusion patterns. Supported formats are:
        * <ul>
-       *   <li>path prefixed by / and ended by *, for example "/api/foo/*", to match all paths "/api/foo" and "api/api/foo/something/else"</li>
+       *   <li>path prefixed by / and ended by * or /*, for example "/api/foo/*", to match all paths "/api/foo" and "api/api/foo/something/else"</li>
+       *   <li>path prefixed by / and ended by .*, for example "/api/foo.*", to match exact path "/api/foo" with any suffix like "/api/foo.protobuf"</li>
        *   <li>path prefixed by *, for example "*\/foo", to match all paths "/api/foo" and "something/else/foo"</li>
        *   <li>path with leading slash and no wildcard, for example "/api/foo", to match exact path "/api/foo"</li>
        * </ul>
@@ -206,8 +208,15 @@ public abstract class ServletFilter implements Filter {
         checkArgument(countStars == 1, "URL pattern accepts only zero or one wildcard character '*': %s", pattern);
         if (pattern.charAt(0) == '/') {
           checkArgument(pattern.endsWith(WILDCARD_CHAR), "URL pattern must end with wildcard character '*': %s", pattern);
-          // remove the ending /* or *
-          String path = pattern.replaceAll("/?\\*", "");
+          if (pattern.endsWith("/*")) {
+            String path = pattern.substring(0, pattern.length() - "/*".length());
+            return url -> url.startsWith(path);
+          }
+          if (pattern.endsWith(".*")) {
+            String path = pattern.substring(0, pattern.length() - ".*".length());
+            return url -> substringBeforeLast(url, ".").equals(path);
+          }
+          String path = pattern.substring(0, pattern.length() - "*".length());
           return url -> url.startsWith(path);
         }
         checkArgument(pattern.startsWith(WILDCARD_CHAR), "URL pattern must start with wildcard character '*': %s", pattern);
index 6d98e78e2b0a28f0627ab7c0353f4a4d2eeda756..43e3379cf575215e5e40260a76c2b020a9786914 100644 (file)
@@ -158,6 +158,17 @@ public class ServletFilterTest {
     assertThat(pattern.matches("/foo/index")).isTrue();
   }
 
+  @Test
+  public void use_include_and_exclude_prefix() {
+    ServletFilter.UrlPattern pattern = ServletFilter.UrlPattern.builder()
+        .includes("/foo_2")
+        .excludes("/foo")
+        .build();
+    assertThat(pattern.matches("/")).isFalse();
+    assertThat(pattern.matches("/foo_2")).isTrue();
+    assertThat(pattern.matches("/foo")).isFalse();
+  }
+
   @Test
   public void exclude_pattern_has_higher_priority_than_include_pattern() {
     ServletFilter.UrlPattern pattern = ServletFilter.UrlPattern.builder()