Prior to this commit, configuring a custom handshakeHandler when setting
up a stomp-endpoint with SockJS would not be taken into account:
<websocket:stomp-endpoint path="/foo">
<websocket:handshake-handler ref="customHandler"/>
<websocket:sockjs/>
</websocket:stomp-endpoint>
This commit fixes this by creating and registering a
WebsocketTransportHandler (with this handshakeHandler) as a
transportHandler override for the SockJSService.
Issue: SPR-11568
Prior to this commit, the codebase was using a mix of log4j.xml
and log4j.properties for test-related logging configuration. This
can be an issue as log4j takes the xml variant first when looking
for a default bootstrap configuration.
In practice, some modules declaring the properties variant were
taking the xml variant configuration from another module.
The general structure of the configuration has also been
harmonized to provide a standard console output as well as an
easy way to enable trace logs for the current module.
The clientInboundChannel and clientOutboundChannel now use twice
the number of available processors by default to accomodate for some
degree of blocking in task execution on average.
In practice these settings still need to be configured explicitly in
applications but these should serve as better default values than
the default values in ThreadPoolTaskExecutor.
Issue: SPR-11450
This change exposes the WebSocketSession attributes through a message header.
The StompSubProtocolHandler adds this to incoming messages.
For now messaging handling methods can access the map via @Header, e.g.:
@Header(StompHeaderAccessor.SESSION_ATTRIBUTES) Map<String, Object> attrs) {
Issue: SPR-11566
Add accessor for brokerAvailable in AbstractBrokerMessageHandler
Ensure brokerAvailable is set even if eventPublisher is not
Add tests BrokerMessageHandlerTests
Turn off brokerAvailable when StompBrokerRelayMessageHandler stops
Actually stop message handling when brokerAvailable=false
Improve log messages
Issue: SPR-11563
Prior to this commit, the `relay-port` attribute of the
`<websocket:stomp-broker-relay />` tag was of type `xsd:int`.
This prevents developers from using `PropertyPlaceholderConfigurer`,
even though this configuration key is a good candidate for such use
(this value depends on prod/staging/etc environment).
This commit changes that type to `xsd:string`.
Issue: SPR-11537
After this change, AbstractSockJsService does not add CORS headers if
the response already contains an "Access-Control-Allow-Origin" header.
Essentially it backs off assuming CORS headers are handled centrally
e.g. through a Filter.
In order to support this, the ServletServerHttpResponse now returns an
instance of HttpHeaders that also provides access to headers already
present in the HttpServletResponse.
Issue: SPR-11443
- Deleted empty AbstractWebSocketClientTests class.
- AbstractServletHandlerMethodTests and AbstractHttpRequestTests are
now actually declared as abstract.
- The following classes are not abstract but currently have an
"Abstract" prefix and therefore get ignored by the Gradle build.
This commit renames each of these by deleting the "Abstract" prefix.
- AbstractFlashMapManagerTests
- AbstractMappingContentNegotiationStrategyTests
- AbstractSockJsServiceTests
- AbstractWebSocketHandlerRegistrationTests
The Servlet API does not provide notifications when a client
disconnects, see see https://java.net/jira/browse/SERVLET_SPEC-44.
Therefore network IO failures may occur simply because a client has
gone away. Before this change that could fill logs with unnecessary
stack traces.
After this change we make a best effort to identify such network
failures, on a per-server basis (tested with Jetty, Tomcat, Glassfish,
and WildFly), and log them under a separate log category.
A simple one-line message is logged at DEBUG level (i.e. no stack trace)
while a full stack trace is shown at TRACE level.
Issue: SPR-11438
Before this change CompositeMessageConverter had a ContentTypeResolver
field that was in turn set on all contained converters.
After this change that field is removed and effectively
CompositeMessageConverter is a simple container of other converters.
Each converter in turn must have been configured with a
ContentTypeResolver.
Doing so means it is less likely to have unexpected consequences when
configuring converters, the ContentTypeResolver set in the composite
converter overriding the one configured in a contained converter.
Also commit 676ce6 added default ContentTypeResolver initialization
to AbstractMessageConverter, which ensures that converters are still
straight forward to configure.
Issue: SPR-11462
Before this change, when a client subscribed to a "user" destination
(e.g. /user/foo), actual messages received in response to that
subscription contained the server-translated, unique user destination
(e.g. /foo-user123).
This is not an issue for clients such as stomp.js since the
subscription is unique and sufficient to match subscription responses.
However, other STOMP clients do additional checks on the destination
of the subscription and the response.
This change ensures that messages sent to clients on user destionations
always contain a destination that matches the one on the original
subscription.
Issue: SPR-11423
The interface is to be implemented in addition to
java.security.Principal when Principal.getName() is not globally unique
enough for use in user destinations.
Issue: SPR-11327
sockjs-client expects a prelude to be written on every request with
streaming transports. The protocol tests don't make this clear and
don't expose this issue.
The test case for SPR-11183 (writing 20K messages in succession) did
expose the issue and this commit addresses it.
Issue: SPR-11183
This change adds a protected method to DefaultHandshakeHandler to
determine the user for the WebSocket session. By default it's
implemeted to obtain it from the request.
Issue: SPR-11228
The Jetty ServletWebUpgradeRequest implements getUserPrincipal to
return the Principal from the HttpServletRequest on the upgrade.
This change ensures we can fall back on that.
However the JettyRequestUpgradeStrategy still passes the user from
HttpServletRequest from the upgrade, in order to work with Jetty
9.0.x and avoid running into this 9.1.x issue:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=423118
The observed behavior was that the client does not get a response from
the WebSocket HTTP handshake. On the server the handshake actually
succeeds, the response is set correctly to status 101, and the
WebSocketHandler gets notified of the successfully established
connection.
This change flushes the ServletResponse just before returning from the
GlassfishRequestUpgradeStrategy. This is actually what Glassfish's own
TyrusServletFilter does as well at the end along with a comment that it
is a possible bug.