allthingssecurity opened a new pull request, #28377:
URL: https://github.com/apache/camel/pull/28377

   # Description
   
   [CAMEL-25854](https://issues.apache.org/jira/browse/CAMEL-25854)
   
   `DefaultUndertowHost` gave the server of a port only one handler, chosen 
from the first consumer that registered: the rest-dsl handler 
(`RestRootHandler`) or the handler for plain `undertow:` endpoints 
(`CamelRootHandler`). Consumers of the other kind were added to a handler the 
server never called. Their routes started without any warning, and every 
request to them got 404. A plain route usually starts first, so the REST API 
was usually the part that answered 404. `unregisterHandler` also checked only 
the kind being removed: when the last consumer of one kind stopped, it stopped 
the server while consumers of the other kind were still started, and their 
clients got connection refused.
   
   Changes:
   - The server always calls `CamelRootHandler`. Its default handler (used when 
no plain endpoint matches) is now the `RestRootHandler` instead of 
`NotFoundHandler`. The `RestRootHandler` answers 404 "No matching path found" 
(the same response as before) or 405 when none of its consumers matches either. 
A port with only plain endpoints, or only rest-dsl consumers, behaves as before.
   - The server stops when neither kind has a consumer left.
   - When a path is served by both a plain endpoint and a rest-dsl consumer, 
the plain endpoint takes it. Before this change only one of the two kinds was 
ever served.
   - `CamelPathHandler`: Undertow keeps a plain endpoint on `/` with 
`matchOnUriPrefix=true` as the default handler of its `PathHandler`, and 
removing it leaves no default handler, so once that endpoint stopped, the 
requests that no other plain endpoint matches (now including those of the 
rest-dsl consumers) got 404. It now puts its default handler back when the 
prefix path `/` is removed.
   - `CamelPathTemplateHandler` / `CamelRootHandler` (found in review): a plain 
endpoint with a path template (such as `/api/{name}`) registers a template 
handler on the static part of its path (`/api`). A request under `/api` that no 
template matches went to the template handler's default, an empty 
`CamelMethodHandler` when no plain endpoint has the path `/api`, which answered 
405, so a rest-dsl consumer under that path (`/api/orders/{id}`) never got it; 
with a template on `/` (such as `/{file}`) the template handler became the 
default of the whole port and every rest-dsl consumer got 405. The template 
handler now gets the server's default handler (the `RestRootHandler`) as a 
fallback, used when its default method handler has no handler at all; a static 
base path that only lacks the request's method still answers 405. On a port 
with only plain endpoints, such a request now gets 404 "No matching path found" 
instead of 405 (the upgrade note says so).
   
   `NotFoundHandler` is no longer used by the component; it is a public class, 
used by `CamelRootHandlerTest`, so it is kept.
   
   A port with only plain endpoints or only rest-dsl consumers answers as 
before. With both kinds on one port, the requests that got 404 (or connection 
refused after the other kind stopped) are now served. One working setup can 
notice it: when the rest-dsl consumers registered first, the plain endpoints of 
the port were never served, and a plain endpoint whose path overlaps a rest-dsl 
path (for example `matchOnUriPrefix=true` on `/`) now takes those requests. A 
`camel-undertow` note in the 4.24 upgrade guide says so, next to the other 
camel-undertow note.
   
   Tests:
   - New `RestUndertowAndPlainConsumerSamePortTest` (a rest-dsl `GET 
/users/{id}` and a plain `undertow:http://localhost:{{port}}/plain` on the same 
port). Without the change the first 4 tests fail. `testBothKindsAreServed` and 
`testPlainConsumerAddedAfterRestConsumer` fail with `/users/123 ==> expected: 
<200> but was: <404>`. `testServerKeepsServingWhenOneKindStops` fails with 
`/plain ==> expected: <200> but was: <null>`: the REST route was stopped, which 
also stopped the server. `testPlainConsumerOnRootTakesThePathsUntilItStops` 
adds a plain endpoint on `/` with `matchOnUriPrefix=true`, which takes 
`/users/123`, then stops it: without the `CamelPathHandler` change `/users/123 
==> expected: <200> but was: <404>`. With the change all 4 pass.
   - `testRestPathUnderTheBaseOfAPlainTemplatePath` (plain `/api/{name}` next 
to rest-dsl `/api/orders/{id}`) and 
`testPlainTemplatePathOnRootKeepsTheRestConsumers` (plain `/{file}`), the 
red-team probe cases: without the template fallback they fail with 
`/api/orders/1 ==> expected: <200> but was: <405>` and `/users/123 ==> 
expected: <200> but was: <405>`. With the change both pass.
   - camel-undertow unit tests with the change: 241 run, 0 failures, 1 skipped.
   
   How it was found: a review of shared per-port server state in the HTTP 
consumer components. The JUnit test above confirmed it.
   
   `mvn formatter:format impsort:sort` on camel-undertow made no change. What 
was not run: the full root build.
   
   # 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-25854](https://issues.apache.org/jira/browse/CAMEL-25854).
   
   # 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 camel-undertow. No option changed. 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