allthingssecurity opened a new pull request, #28538: URL: https://github.com/apache/camel/pull/28538
# Description [CAMEL-26051](https://issues.apache.org/jira/browse/CAMEL-26051) When the endpoint URI of an undertow or vertx-http producer has a query, the `CamelHttpPath` header is lost or put in the wrong place: - camel-undertow: `UndertowHelper.createURL` appends the path to `getHttpURI().toASCIIString()`, which already ends with `?query`, so `http://host/orders?apiVersion=2` and `CamelHttpPath=/123` give `http://host/orders?apiVersion=2/123`. `createURI` then sets the query again (from `CamelHttpQuery` or the endpoint), and the path is gone: the request goes to `/orders?apiVersion=2`. - camel-vertx-http: `VertxHttpHelper.resolveHttpURI` appends the path the same way. The path ends up inside the query (`/orders?apiVersion=2/123`), or is dropped when `CamelHttpQuery` is set. camel-http and camel-netty-http insert the path before the query (`HttpHelper.createURL` in camel-http-common), so the same route works with them. A typical case is a REST API with a version or key in the endpoint query (`?apiVersion=2`) and the resource id in `CamelHttpPath`, for example a route that bridges a request whose path the consumer put in the header. The wrong resource is called, and nothing is logged. Changes: - `UndertowHelper.createURL` and `VertxHttpHelper.resolveHttpURI` insert the path before the `?` of the URI, as camel-http does, with exactly one `/` between the endpoint path and the header path. Neither module depends on camel-http-common, so the few lines are repeated in both, the same as the code they replace. - A URI without a query gives the same result as before. The query handling (`CamelHttpQuery` overrides the endpoint query) is unchanged. - No option or generated file change. - Routes that bridge an HTTP consumer to these producers now call a different URL. The HTTP consumers (undertow, platform-http-vertx, servlet) set `CamelHttpPath` from the path of the request, so a proxy route such as `from("undertow:http://0.0.0.0:8080/api?matchOnUriPrefix=true").to("undertow:http://backend/svc?key=1")` (or a `vertx-http:` producer with `bridgeEndpoint=true`) sent a request for `/api/orders/123` to `/svc` and now sends it to `/svc/orders/123`, as camel-http does. This is the fix, but users can notice it, so the 4.24 upgrade guide has an entry (`camel-undertow, camel-vertx-http - CamelHttpPath with a query in the endpoint uri`): to keep the old target, remove the header before the producer (`removeHeader(Exchange.HTTP_PATH)`). - Backport: the same code is on camel-4.23.x, 4.22.x, 4.18.x and 4.14.x (the 4.14.9, 4.18.5 and 4.22.2 tags have it). Tests: - New `UndertowProducerPathHeaderWithEndpointQueryTest` (7 tests) and `VertxHttpPathHeaderWithEndpointQueryTest` (8 tests), JUnit assertions as in the modules. They cover an endpoint query with the path header alone, with `CamelHttpQuery` (the header query wins, as before), with POST, with a trailing `/` on the endpoint path, with no endpoint path (`http://host:port?apiVersion=2`), (vertx-http only, see below) an already encoded path `/a%20b`, and a proxy route (`proxyRouteWithEndpointQuerySendsTheRemainingPath`: an undertow consumer with `matchOnUriPrefix=true` in front of the producer, and a second route that removes `CamelHttpPath`, as the upgrade guide suggests, to keep the old target). Each producer sends to an in-process JDK `HttpServer` that records the method, raw path and raw query of every request. - On main all tests but the control fail (undertow 6 of 7, vertx-http 7 of 8), for example: - undertow: `expected: <[GET /orders/123 ? apiVersion=2]> but was: <[GET /orders ? apiVersion=2]>`, and with no endpoint path `but was: <[GET / ? apiVersion=2]>`; - vertx-http: `expected: <[POST /orders/123/lines ? apiVersion=2]> but was: <[POST /orders ? apiVersion=2/123/lines]>`, and with `CamelHttpQuery` `but was: <[GET /orders ? expand=items]>`; - the proxy route, both modules: `expected: <[GET /svc/orders/123 ? expand=items, GET /svc ? expand=items]> but was: <[GET /svc ? expand=items, GET /svc ? expand=items]>`. - `pathHeaderWithoutEndpointQuery` is a control that passes on main and with the fix (path header with and without `CamelHttpQuery`, endpoint URI without a query). - Unit tests with the fix: camel-undertow 245 run, 0 failures, 1 skipped; camel-vertx-http 116 run, 0 failures, 1 skipped. - The formatter and import-sort plugins ran. I built offline with `-Dasm-version=9.11` because asm 9.11.1 was not in my local repository. Not changed (follow-up JIRA if wanted): the undertow producer writes the request target from the decoded `URI.getPath()` and `getQuery()` (`URISupport.pathAndQueryOf`). An encoded path such as `/a%20b` is sent as `/orders/a b?apiVersion=2`, and the server reads the path `/orders/a` and no query. This does not depend on the endpoint query (same code without one), so it is not in this PR and the undertow test has no encoded-path case. # Target - [x] I checked that the commit is targeting the correct branch (Camel 4 uses the `main` branch) # Tracking - [x] If this is a large change, bug fix, or code improvement, I checked there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for the change (usually before you start working on it): [CAMEL-26051](https://issues.apache.org/jira/browse/CAMEL-26051). # Apache Camel coding standards and style - [x] I checked that each commit in the pull request has a meaningful subject line and body. - [ ] I have run `mvn clean install -DskipTests` locally from root folder and I have committed all auto-generated changes. (I built camel-undertow and camel-vertx-http and ran their tests, including the formatter and import-sort plugins. No generated file changes. I did not run the full root build.) # AI-assisted contributions - [x] If this PR includes AI-generated code, commits have proper co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR description identifies the AI tool used. This PR was prepared with Claude Code (Claude Opus 5.5). The commit carries a `Co-Authored-By` trailer. _Claude Code on behalf of allthingssecurity_ 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
