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]

Reply via email to