Federico Mariani created CAMEL-25917:
----------------------------------------
Summary: camel-undertow - close WebSocket connections opened
before the consumer starts
Key: CAMEL-25917
URL: https://issues.apache.org/jira/browse/CAMEL-25917
Project: Camel
Issue Type: Improvement
Components: camel-undertow
Reporter: Federico Mariani
Assignee: Federico Mariani
Fix For: 4.24.0, 4.22.3
Follow-up to CAMEL-25375.
h3. Behaviour today
When a WebSocket producer and a WebSocket consumer share the same Undertow
endpoint URI and the consumer is started for the first time after the server is
already serving that path (for example a route with {{autoStartup(false)}}
started later, or a route added at runtime), connections opened while only the
producer served the path stay open after the consumer starts. The consumer's
{{handlers}} option was never applied to those connections, because
producer-only paths do not run {{handlers}} during the handshake (CAMEL-25375).
The per-channel handshake result in {{CamelWebSocketHandler}} records only the
endpoint URIs whose checks passed, not whether the {{handlers}} chain ran, so
{{isAuthenticated(channel, endpoint, consumer=true)}} accepts those channels
for the consumer and their messages reach the consumer route without having
gone through its {{handlers}}.
h3. Behaviour after the change
A connection is accepted by a consumer that configures {{handlers}} only if the
consumer's {{handlers}} chain ran during its handshake. Connections opened on
the path before the consumer started are closed with {{1008}} (policy
violation) when the consumer is registered, and clients reconnect so the
handshake runs the consumer's {{handlers}}. Producer-only paths keep their
current behaviour (no {{handlers}} at handshake). This mirrors what already
happens for OAuth-protected endpoints (see
{{UndertowWsOAuthProfileConsumerWindowTest}}).
h3. Classes involved
* {{org.apache.camel.component.undertow.handlers.CamelWebSocketHandler}}
({{HandshakeResult}}, {{upgrade()}}, {{isAuthenticated(...)}},
{{setConsumer(...)}})
* possibly {{org.apache.camel.component.undertow.UndertowConsumer}}, if the
close of existing connections is triggered from there
h3. Code change
# Record in {{HandshakeResult}} which checks were applied: keep the endpoint
URIs that passed with the consumer checks ({{handlers}} included) separately
from those that passed with the producer checks, or capture {{path.consumer}}
at handshake time.
# In {{isAuthenticated(channel, endpoint, consumer=true)}}, when
{{endpoint.getHandlers() != null}}, require the consumer-check record for that
URI; a producer-check record is no longer enough.
# In {{setConsumer(consumer, handler)}}, after installing the consumer, close
({{CloseMessage.MSG_VIOLATES_POLICY}}) the existing peers that no longer pass
{{isAuthenticated(peer, pathSecurity())}}. {{send()}} already filters peers
with {{isAuthenticated}}.
# Leave producer-only behaviour unchanged.
h3. Tests
New test class in
{{components/camel-undertow/src/test/java/org/apache/camel/component/undertow/spi/}}
(or new methods in {{SecurityProviderWebSocketTest}}), reusing
{{AbstractSecurityProviderTest}}:
* {{connectionOpenedBeforeConsumerStartsIsClosedWhenConsumerHasHandlers}}:
producer and consumer on the same URI with {{allowedRoles}} and {{handlers}},
consumer with {{autoStartup(false)}}; connect, start the consumer, send; the
consumer mock receives nothing and the connection is closed.
* {{connectionOpenedAfterConsumerStartsRunsConsumerHandlers}}: the normal path
keeps working.
* {{producerOnlyPathStillAcceptsConnectionsWithoutHandlers}}: producer-only
paths keep working.
h3. Upgrade guide
Add a note to the 4.24 and 4.22 upgrade guides: WebSocket connections opened on
an Undertow path before its consumer was started for the first time are closed
when that consumer configures {{handlers}}; clients must reconnect.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)