浏览代码

Register reserved routes so we do not register them by accident (#92893)

This commits adds four "reserved" paths that Elasticsearch should not register under any cases. By registering these and returning a bad request (we don't actually serve them), we can ensure that if we ever try to register them in the path, Elasticsearch will trip an assertion and fail to build.
Lee Hinman 2 年之前
父节点
当前提交
4573c5641e

+ 5 - 1
server/src/main/java/org/elasticsearch/rest/RestController.java

@@ -71,6 +71,7 @@ public class RestController implements HttpServerTransport.Dispatcher {
 
 
     static final String ELASTIC_PRODUCT_HTTP_HEADER = "X-elastic-product";
     static final String ELASTIC_PRODUCT_HTTP_HEADER = "X-elastic-product";
     static final String ELASTIC_PRODUCT_HTTP_HEADER_VALUE = "Elasticsearch";
     static final String ELASTIC_PRODUCT_HTTP_HEADER_VALUE = "Elasticsearch";
+    static final Set<String> RESERVED_PATHS = Set.of("/__elb_health__", "/__elb_health__/zk", "/_health", "/_health/zk");
 
 
     private static final BytesReference FAVICON_RESPONSE;
     private static final BytesReference FAVICON_RESPONSE;
 
 
@@ -264,6 +265,9 @@ public class RestController implements HttpServerTransport.Dispatcher {
         assert RestApiVersion.minimumSupported() == version || RestApiVersion.current() == version
         assert RestApiVersion.minimumSupported() == version || RestApiVersion.current() == version
             : "REST API compatibility is only supported for version " + RestApiVersion.minimumSupported().major;
             : "REST API compatibility is only supported for version " + RestApiVersion.minimumSupported().major;
 
 
+        if (RESERVED_PATHS.contains(path)) {
+            throw new IllegalArgumentException("path [" + path + "] is a reserved path and may not be registered");
+        }
         handlers.insertOrUpdate(
         handlers.insertOrUpdate(
             path,
             path,
             new MethodHandlers(path).addMethod(method, version, handler),
             new MethodHandlers(path).addMethod(method, version, handler),
@@ -659,7 +663,7 @@ public class RestController implements HttpServerTransport.Dispatcher {
      * Handle a requests with no candidate handlers (return a 400 Bad Request
      * Handle a requests with no candidate handlers (return a 400 Bad Request
      * error).
      * error).
      */
      */
-    private static void handleBadRequest(String uri, RestRequest.Method method, RestChannel channel) throws IOException {
+    public static void handleBadRequest(String uri, RestRequest.Method method, RestChannel channel) throws IOException {
         try (XContentBuilder builder = channel.newErrorBuilder()) {
         try (XContentBuilder builder = channel.newErrorBuilder()) {
             builder.startObject();
             builder.startObject();
             {
             {

+ 15 - 0
server/src/test/java/org/elasticsearch/rest/RestControllerTests.java

@@ -938,6 +938,21 @@ public class RestControllerTests extends ESTestCase {
         );
         );
     }
     }
 
 
+    public void testRegisterWithReservedPath() {
+        final RestController restController = new RestController(Set.of(), null, client, circuitBreakerService, usageService, tracer);
+        for (String path : RestController.RESERVED_PATHS) {
+            IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> {
+                restController.registerHandler(
+                    new Route(randomFrom(RestRequest.Method.values()), path),
+                    (request, channel, client) -> channel.sendResponse(
+                        new RestResponse(RestStatus.OK, RestResponse.TEXT_CONTENT_TYPE, BytesArray.EMPTY)
+                    )
+                );
+            });
+            assertThat(iae.getMessage(), containsString("path [" + path + "] is a reserved path and may not be registered"));
+        }
+    }
+
     private static final class TestHttpServerTransport extends AbstractLifecycleComponent implements HttpServerTransport {
     private static final class TestHttpServerTransport extends AbstractLifecycleComponent implements HttpServerTransport {
 
 
         TestHttpServerTransport() {}
         TestHttpServerTransport() {}