vert-x3 / vertx-web

HTTP web applications for Vert.x
Apache License 2.0
1.11k stars 535 forks source link

When upgrade vertx4, the path cannot support colon, and vertx 3 is ok #2601

Closed xioyaozi closed 6 months ago

xioyaozi commented 6 months ago

Questions

When upgrade vertx4, the path cannot support colon, and vertx 3 is ok.

I have read the source code, and consider it is a compatibility issue, hope to fix it in new version.

ps; my avoidance methods is using router.routeWithRegex ,but it need create pattern regex by myself, it is not the best method.

the problem is in io.vertx.ext.web.impl.RouteImpl#setPath


    // See if the path contains ":" - if so then it contains parameter capture groups and we have to generate
    // a regex for that
    int params = 0;
    for (int i = 0; i < path.length(); i++) {
      if (path.charAt(i) == ':') {
        params++;
      }
    }
    if (params > 0) {
      int found = createPatternRegex(path);
      if (params != found) {
        throw new IllegalArgumentException("path param does not follow the variable naming rules, expected (" + params + ") found (" + found + ")");
      }
    }

Version

vertx 4.5.7

Context

Exception in thread "main" java.lang.IllegalArgumentException: path param does not follow the variable naming rules, expected (2) found (1) at io.vertx.ext.web.impl.RouteImpl.setPath(RouteImpl.java:308) at io.vertx.ext.web.impl.RouteImpl.(RouteImpl.java:50) at io.vertx.ext.web.impl.RouterImpl.route(RouterImpl.java:86) at Main.main(Main.java:10)

Do you have a reproducer?

import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServer;
import io.vertx.ext.web.Router;

public class Main {
    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        Router router = Router.router(vertx);
        router.route("/catalogue/products/:productType/messages[:]send").handler(routingContext -> {
            routingContext.response().end("hello world");
        });
        HttpServer server = vertx.createHttpServer();
        server.requestHandler(router).listen(8888);

        // user vertx 3.9.1 , run success, GET http://127.0.0.1:8888//catalogue/products/productType1/messages:send
        // user vertx 4.5.7 , run exception
        // there is a Compatibility issue
    }
}

Extra

NA

tsegismont commented 6 months ago

Indeed, Vert.x 4 is more conservative: if you have a colon in the path, you must routeWithRegex like this:

router.routeWithRegex("/catalogue/products/(?<productType>[^/]+)/messages:send")

And then retrieve the param like this:

String productType = routingContext.pathParam("productType");