This change introduces SimpUserRegistry exposing an API to access
information about connected users, their sessions, and subscriptions
with STOMP/WebSocket messaging. Provides are methods to access users
as well as a method to find subscriptions given a Matcher strategy.
The DefaultSimpUserRegistry implementation is also a
SmartApplicationListener which listesn for ApplicationContext events
when users connect, disconnect, subscribe, and unsubscribe to
destinations.
The MultiServerUserRegistry implementation is a composite that
aggregates user information from the local SimpUserRegistry as well
as snapshots of user on remote application servers.
UserRegistryMessageHandler is used with MultiServerUserRegistry. It
broadcats user registry information through the broker and listens
for similar broadcasts from other servers. This must be enabled
explicitly when configuring the STOMP broker relay.
The existing UserSessionRegistry which was primiarly used internally
to resolve a user name to session id's has been deprecated and is no
longer used. If an application configures a custom UserSessionRegistr
still, it will be adapted accordingly to SimpUserRegistry but the
effect is rather limited (comparable to pre-existing functionality)
and will not work in multi-server scenarios.
Issue: SPR-12029
Since SPR-10954, the SimpleBrokerMessageHandler supports `heart-beats`.
Even if the STOMP spec states that the `heart-beat` header is OPTIONAL,
and if absent considered as `heart-beat: 0,0`,
some clients rely on this to be set in CONNECTED frames.
This commit adds this header information even if no task
scheduler/heart-beat have been configured.
See: https://stomp.github.io/stomp-specification-1.2.html#Heart-beating
Issue: SPR-10954
This commit adds CORS related headers to HttpHeaders
and update DefaultCorsProcessor implementation to
use ServerHttpRequest and ServerHttpResponse instead
of HttpServletRequest and HttpServletResponse. Usage
of ServerHttpResponse allows to avoid using Servlet 3.0
specific methods in order keep CORS support Servlet 2.5
compliant.
Issue: SPR-12885
This change adds support for broadcasting messages with unresolved
user destinations so that other servers can try to resolve it.
That enables sending messages to users who may be connected to a
different server.
Issue: SPR-11620
This commit introduces support for CORS in Spring Framework.
Cross-origin resource sharing (CORS) is a mechanism that allows
many resources (e.g. fonts, JavaScript, etc.) on a web page to
be requested from another domain outside the domain from which
the resource originated. It is defined by the CORS W3C
recommandation (http://www.w3.org/TR/cors/).
A new annotation @CrossOrigin allows to enable CORS support
on Controller type or method level. By default all origins
("*") are allowed.
@RestController
public class SampleController {
@CrossOrigin
@RequestMapping("/foo")
public String foo() {
// ...
}
}
Various @CrossOrigin attributes allow to customize the CORS configuration.
@RestController
public class SampleController {
@CrossOrigin(origin = { "http://site1.com", "http://site2.com" },
allowedHeaders = { "header1", "header2" },
exposedHeaders = { "header1", "header2" },
method = RequestMethod.DELETE,
maxAge = 123, allowCredentials = "true")
@RequestMapping(value = "/foo", method = { RequestMethod.GET, RequestMethod.POST} )
public String foo() {
// ...
}
}
A CorsConfigurationSource interface can be implemented by HTTP request
handlers that want to support CORS by providing a CorsConfiguration
that will be detected at AbstractHandlerMapping level. See for
example ResourceHttpRequestHandler that implements this interface.
Global CORS configuration should be supported through ControllerAdvice
(with type level @CrossOrigin annotated class or class implementing
CorsConfigurationSource), or with XML namespace and JavaConfig
configuration, but this is not implemented yet.
Issue: SPR-9278
Prior to this commit, the `client-library-url` XML attribute was not
effective in the MVC namespace, leaving the default value configured:
```xml
<websocket:sockjs client-library-url="/js/sockjs.js" />
```
This commit fixes the sockjs namespace handler and makes sure that this
attribute is configured on the `SockJsService` Bean to be created.
Issue: SPR-12874
The getter in TransportHandlingSockJsService now returns a mutable
List. The immutable wrapper doesn't make sense since it's possible
anyway to modify the list by creating a new list and calling the
setter again. It's also consistent with the same field on
WebSocketHttpRequestHandler.
This is related to work for SPR-12845.
This change adds support for global @MessageExceptionHandler methods
with STOMP over WebSocket messages. Such methods can be added to
@ControllerAdvice annotated components, much like @ExceptionHandler
methods for Spring MVC.
Issue: SPR-12696
WebSocketStompClient can be used with any implementation of
org.springframework.web.socket.client.WebSocketClient, which includes
org.springframework.web.socket.sockjs.client.SockJsClient.
Reactor11TcpStompClient can be used with reactor-net and provides STOMP
over TCP. It's also possible to adapt other WebSocket and TCP client
libraries (see StompClientSupport for more details).
For example usage see WebSocketStompClientIntegrationTests.
Issue: SPR-11588
This commit adds support for a same origin check that compares
Origin header to Host header. It also changes the default setting
from all origins allowed to only same origin allowed.
Issues: SPR-12697, SPR-12685
Before this change the WebSocketTransportHandler passed
Collections.emptyMap as attributes to the HandshakeHandler because
it didn't matter what attributes the underlying WebSocketSession has
since it is wrapped by the SockJsSession and that's what exposed for
use everywhere.
This change has the WebSocketTransportHandler passing the attributes
from the SockJsSession instead since it's more accurate for the
underlying WebSocketSession to have access to the same map instance
and it allows the HandshakeHandler to change the attributes even if
it doesn't need to do that today.
Issue: SPR-12716
Add support for annotation-based event listeners. Enabled automatically
when using Java configuration or can be enabled explicitly via the
regular <context:annotation-driven/> XML element. Detect methods of
managed beans annotated with @EventListener, either directly or through
a meta-annotation.
Annotated methods must define the event type they listen to as a single
parameter argument. Events are automatically filtered out according to
the method signature. When additional runtime filtering is required, one
can specify the `condition` attribute of the annotation that defines a
SpEL expression that should match to actually invoke the method for a
particular event. The root context exposes the actual `event`
(`#root.event`) and method arguments (`#root.args`). Individual method
arguments are also exposed via either the `a` or `p` alias (`#a0` refers
to the first method argument). Finally, methods arguments are exposed via
their names if that information can be discovered.
Events can be either an ApplicationEvent or any arbitrary payload. Such
payload is wrapped automatically in a PayloadApplicationEvent and managed
explicitly internally. As a result, users can now publish and listen
for arbitrary objects.
If an annotated method has a return value, an non null result is actually
published as a new event, something like:
@EventListener
public FooEvent handle(BarEvent event) { ... }
Events can be handled in an aynchronous manner by adding `@Async` to the
event method declaration and enabling such infrastructure. Events can
also be ordered by adding an `@Order` annotation to the event method.
Issue: SPR-11622
This commit introduces the following changes:
- Requests without Origin header are not rejected anymore
- Disable Iframe when allowedOrigins is not empty and not equals to *
- The Iframe is not cached anymore in order to have a reliable origin check
- allowedOrigins must not be null or empty
- allowedOrigins format is now validated (should be * or start by http(s)://)
Issue: SPR-12660
A logical follow-up on commit 43d937, this change also removes (or
rather deprecates for now) writePrelude that is only of concern to
streaming SockJS session implementations.
Issue: SPR-12427
This change removes the need for the isStreaming field from the base
class AbstractHttpSockJsSession. This field was used to account for
differences between polling vs streaming SockJS sessions without having
to expose to sub-classes private fields that are otherwise protected
from concurrent access by the base class. The change manages to delegate
to sub-classes without providing direct access to protected fields.
Issue: SPR-12427
This change designates Jetty SockJS integration tests to run as part of
the "performance", but not the main "publication", CI build due to
recurring low-level failures suspected to be Jetty issues, e.g.
"java.io.IOException: Cannot append to finished buffer" or
"java.io.IOException: Out of order Continuation frame encountered".
The tests will still run at once a day with the performance build but
should not fail the main build with false negatives. Also note that
an Undertow variant of the exact same tests, which hasn't been failing,
will continue to run as part of the main build.
The following two refinements have been added:
1) SockJS doesn't support binary messages so don't even try
2) don't bother if payload.length == 0
Issue: SPR-12475
This commit introduces the SpringHandlerInstantiator
class, a Jackson HandlerInstantiator that allows to autowire
Jackson handlers (JsonSerializer, JsonDeserializer, KeyDeserializer,
TypeResolverBuilder and TypeIdResolver) if needed.
SpringHandlerInstantiator is automatically used with
@EnableWebMvc and <mvc:annotation-driven />.
Issue: SPR-10768
With this commit, Jackson builder is now used in spring-websocket
to create the ObjectMapper instance.
It is not possible to use the builder for spring-messaging
and spring-jms since these modules don't have a dependency on
spring-web, thus they now just customize the same features:
- MapperFeature#DEFAULT_VIEW_INCLUSION is disabled
- DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES is disabled
Issue: SPR-12293
Upgrade undertow dependency to 1.1.0.Final.
Add support for undertow 1.1.0.Final in the
UndertowRequestUpgradeStrategy, after a breaking change in the
`io.undertow.websockets.jsr.ConfiguredServerEndpoint` constructor.
Issue: SPR-12302