Vertx-web: SubRouter Mount acting as Exact Path

Created on 3 Dec 2019  路  5Comments  路  Source: vert-x3/vertx-web

3.8.4

  • vert.x web:

Context

The handlers mounted on sub-router are ignored when the mount point is "/".
router.mountSubRouter("/", subRouter);
Note that, we can't have empty string as mount point.

It was functional until v3.8.1. With v3.8.4 it behaves as exactMatch and ending with slash.

Below table shows the difference between 3.8.1 and 3.8.4 based on the reproducer shared below:

| Path | v3.8.1 | v3.8.4 |
| --- | --- | --- |
| /primary | Success | Resource Not Found |
| /primary?query | Success | Resource Not Found |
| /primary/ | Success | Success |
| /primary/random | Resource Not Found | Resource Not Found |
| With subrouter mounted at /abc|
| /primary/abc | Success | Success |
| /primary/abc/ | Success | Success |
| /primary/abc?query | Success | Success |

Do you have a reproducer?

Steps to reproduce

By default, Vertx version is set to 3.8.4 in the reproducer. Change it to 3.8.1 to verify the behavior.

  1. Build and run the RouterTestMain given in the reproducer. Server will start listening on 8443
  2. Curl the given paths to observe the behavior. Ex: curl http://localhost:8443/primary?query

References

I have gone through below issues, wondering if this change was intended?

Extra

First two scenarios return success response in v3.8.4 also if we attach the handlers directly to the primary router instead of sub router (set useSubRouters flag in RouterTestServer.java to false to verify the behavior).

However, raising this ticket as the behavior of sub router mounting has changed.

bug in progress

Most helpful comment

Hi @pmlopes

Thanks for the test. I updated the same as below to replicate the scenario.

@Test
  public void testMountMultiLevel() throws Exception {
    Router routerFirstLevel = Router.router(vertx);
    router.mountSubRouter("/primary", routerFirstLevel);

    Router routerSecondLevel = Router.router(vertx);
    routerSecondLevel.get("/").handler(ctx -> {
      ctx.response().setStatusMessage("Hi").end();
    });
    routerFirstLevel.mountSubRouter("/", routerSecondLevel);

    // Below two scenarios will fail with 3.8.4 and higher, pass with 3.8.1 and lower.
    testRequest(HttpMethod.GET, "/primary", 200, "Hi");
    testRequest(HttpMethod.GET, "/primary?query=1", 200, "Hi");

    // Below scenarios will pass
    testRequest(HttpMethod.GET, "/primary/", 200, "Hi");
    testRequest(HttpMethod.GET, "/primary/random", 404, "Not Found");
  }

All 5 comments

I've just added this test on 3.8 and master:

  @Test
  public void testMountOnRoot() throws Exception {
    Router subRouter = Router.router(vertx);

    subRouter.get("/primary").handler(ctx -> {
      ctx.response().setStatusMessage("Hi").end();
    });

    router.mountSubRouter("/", subRouter);

    testRequest(HttpMethod.GET, "/primary", 200, "Hi");
    testRequest(HttpMethod.GET, "/primary?query=1", 200, "Hi");
    testRequest(HttpMethod.GET, "/primary/", 200, "Hi");
    testRequest(HttpMethod.GET, "/primary/random", 404, "Not Found");
  }

And the test passes.

The issue is not reproducible on a test

@pmlopes ,
I just revisited the reproducer and your test above to understand the difference.
The behavior is observed when second level of sub-router is configured. It works fine with first-level sub-router.

@ramtech123 could you help me out adding the test case to the test above that will make it fail?

Hi @pmlopes

Thanks for the test. I updated the same as below to replicate the scenario.

@Test
  public void testMountMultiLevel() throws Exception {
    Router routerFirstLevel = Router.router(vertx);
    router.mountSubRouter("/primary", routerFirstLevel);

    Router routerSecondLevel = Router.router(vertx);
    routerSecondLevel.get("/").handler(ctx -> {
      ctx.response().setStatusMessage("Hi").end();
    });
    routerFirstLevel.mountSubRouter("/", routerSecondLevel);

    // Below two scenarios will fail with 3.8.4 and higher, pass with 3.8.1 and lower.
    testRequest(HttpMethod.GET, "/primary", 200, "Hi");
    testRequest(HttpMethod.GET, "/primary?query=1", 200, "Hi");

    // Below scenarios will pass
    testRequest(HttpMethod.GET, "/primary/", 200, "Hi");
    testRequest(HttpMethod.GET, "/primary/random", 404, "Not Found");
  }
Was this page helpful?
0 / 5 - 0 ratings

Related issues

XiaohuChen picture XiaohuChen  路  11Comments

shiprabehera picture shiprabehera  路  3Comments

encodeering picture encodeering  路  5Comments

sonofingo picture sonofingo  路  5Comments

plenderyou picture plenderyou  路  7Comments