[
https://issues.apache.org/jira/browse/CAMEL-26083?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen updated CAMEL-26083:
--------------------------------
Fix Version/s: 4.24.0
> camel-support - RestConsumerContextPathMatcher: stopping one consumer of a
> wildcard path stops the wildcard matching of every other consumer with the
> same path
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-26083
> URL: https://issues.apache.org/jira/browse/CAMEL-26083
> Project: Camel
> Issue Type: Bug
> Components: camel-netty-http, camel-servlet, camel-support,
> camel-undertow
> Reporter: shashank
> Assignee: shashank
> Priority: Major
> Fix For: 4.24.0
>
>
> {{RestConsumerContextPathMatcher}} keeps the compiled regex of each wildcard
> consumer path in a static map keyed only by the path string
> ({{PATH_PATTERN}}, main 6a2f66ddec3e line 43). {{register(path)}} puts it,
> {{unRegister(path)}} removes it (lines 245-272), and {{matchWildCard}}
> returns false for a path without a pattern (line 388), the last step of
> {{matchBestPath}}. The map is one per JVM, so all consumers with the same
> path share one entry: the same wildcard path for two HTTP methods ({{GET
> /files/*}} and {{POST /files/*}}), on two ports, in two CamelContexts or two
> components. Stopping, suspending (netty-http with
> {{send503whenSuspended=false}}), removing or reloading one of them removes
> the pattern for all: every other consumer of that path, still started, no
> longer matches. Its requests get 404, or are routed to a broader wildcard
> consumer of the same server ({{/*}}). Callers: netty-http
> {{HttpServerMultiplexChannelHandler}}, servlet/jetty
> {{CamelServlet.connect/disconnect}} (camel-http-common), undertow
> {{RestRootHandler}}.
> *Fix*: each entry counts the consumers that registered the path;
> {{unRegister}} removes the pattern only when no consumer is left
> ({{ConcurrentHashMap.compute}}/{{computeIfPresent}}). Compiling on demand was
> not chosen, as it would change matching for camel-rest-openapi and
> camel-rest-postman, which call {{matchBestPath}} without registering.
> {{CamelServlet.disconnect}} (servlet, jetty) now unregisters only when
> {{consumers.remove(endpointUri, consumer)}} removed this consumer: with an
> {{httpRegistry}} shared by servlets of different names,
> {{CamelHttpTransportServlet.connect}} registers a consumer only in the
> servlet of its name while {{disconnect}} ran for every servlet, and a connect
> refused as "Duplicate request path" was followed by a {{disconnect}} that
> unregistered a path it never registered (and removed the other consumer's map
> entry).
> *Tests*: new {{NettyHttpTwoRoutesSameWildcardPathStopOneRouteTest}}, 2 tests,
> both fail on main ({{expected: <post> but was: <>}} after stopping the GET
> route of the same path; {{expected: <other-port> but was: <catch-all>}} after
> stopping the same path on another port); new
> {{ServletSharedHttpRegistryWildcardPathTest}} (shared {{httpRegistry}} with
> servlets {{a}} and {{b}}; stop one of two consumers of a path; a duplicate
> consumer), 2 tests, fail on main and with only the matcher change; new
> {{RestConsumerContextPathMatcherTest#wildcardPathStaysRegisteredWhileAnotherConsumerUsesIt}}
> fails on main ({{expected: not <null>}}). Unit tests with the fix:
> camel-netty-http 316 run, 0 failures, 8 skipped; camel-servlet 112 run, 0
> failures, 2 skipped; camel-http-common 48 run, 0 failures.
> *How it was found*: spec mining of {{RestConsumerContextPathMatcherTest}} and
> a stateful lifecycle-sequence harness over HTTP consumers sharing a server.
> *Affected*: main, camel-4.22.x, camel-4.18.x and camel-4.14.x (same code).
> Read, not run.
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)