allthingssecurity opened a new pull request, #27469: URL: https://github.com/apache/camel/pull/27469
# Description [CAMEL-25306](https://issues.apache.org/jira/browse/CAMEL-25306) Reported by Serdar Gökay, with a reproducer that serves the same route through a contract-first `rest-openapi` consumer and through the Rest DSL. `RestOpenApiProcessor` maps the operation's path placeholders from `Exchange.HTTP_PATH`, which is the raw request path (`RoutingContext.normalizedPath()` in camel-platform-http-vertx, the request URI in the Spring Boot engine). So a contract-first route got `id=A%221`, `X%20Y` or `caf%C3%A9`, while the Rest DSL route got `A"1`, `X Y` and `café`. With `clientRequestValidation=true` the validator even checks the decoded value while the route gets the encoded text. As proposed in the ticket, `RestOpenApiProcessor` now passes a `BiConsumer` to the existing `HttpHelper.evalPlaceholders(BiConsumer, String, String)` overload, which decodes each value after the path has been split: - percent-encoded octets are decoded as UTF-8; - an encoded `/` stays inside its parameter, because the path is split before decoding (matching is still done on the raw path); - a `+` stays a `+`, since in a path it is a literal and only form-encoded query strings use it for a space; - a value with a malformed escape (such as `100%`) is kept as it is; - values without `%` are unchanged. The decoding is a new `HttpHelper.decodePathParameter(String)` in camel-http-base (the existing `evalPlaceholders` methods are unchanged, so the Rest DSL consumers are not affected). camel-rest-postman (`RestPostmanProcessor`, new in 4.23) built its headers the same way from `HTTP_PATH`, so it uses the same decoding now; as that component has not been released, its change needs no upgrade-guide note. Found and checked with a Lean 4 model of `evalPlaceholders` (including Java's `split("/")`) and of RFC 3986 segment encoding: - On main every value that needs an escape reaches the route still encoded. - For every template and all (ASCII, non-empty) values, the fix gives exactly the values the client encoded. - Decoding the whole path first would split `a%2Fb` into two parameters, and form decoding would turn `+` into a space. - The fix equals main for every value without `%`. This gives the same values as the Rest DSL. I checked it end to end with the Vert.x engine (camel-platform-http-vertx), with the reproducer of the ticket: a contract-first operation and a Rest DSL operation for `/items/{id}`, called with `A%221`, `X%20Y`, `caf%C3%A9`, `a+b`, `a%2Bb`, `%2541`, `a%2Fb`, `100%25`, `%7E1` and `a;x=y`. On main the contract-first values are still encoded (as in the ticket's table); with this change both consumers give the same value for every request, for example `%2541` gives `%41` (decoded once: the Vert.x engine only decodes unreserved characters in `HTTP_PATH`). The Spring Boot engine also decodes each segment after splitting for the Rest DSL. Tests: the new `RestOpenApiPathParameterDecodingTest` (11 cases) sends requests through `RestOpenApiProcessor`. 8 of them fail without the change (`expected: <A"1> but was: <A%221>`, `<café>`/`<caf%C3%A9>`, `<a/b>`/`<a%2Fb>`, `<%41>`/`<%2541>`, ...). The `a+b`, `100%` and `plain` cases pass with and without the change. The new `RestPostmanPathParameterDecodingTest` (3 cases) fails without the change (`expected: <café> but was: <caf%C3%A9>`, ...), and `HttpHelperTest.testDecodePathParameter` covers the helper. The `camel-http-base` (51 tests), `camel-rest-openapi` (176) and `camel-rest-postman` (173) modules pass, and so do the rest-openapi tests of camel-platform-http-vertx (run before the decoding moved to `HttpHelper`; the code is the same). As routes that decoded these headers themselves would now decode twice, the 4.23 upgrade guide has a short `=== camel-rest-openapi - path parameters are decoded` section. # 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). # 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 and tested `components/camel-rest-openapi`, including the formatter and import-sort plugins. No generated files change. 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]
