Commit Graph

435 Commits

Author SHA1 Message Date
Rossen Stoyanchev
05f163b37d Avoid duplicates from <websocket:decorator-factory>
Before this change <websocket:decorator-factory> decorated to
the SubProtocolWebSocketHandler RootBeanDefinition rather than
using a RuntimeBeanReference, which led to a separate instance
of SubProtocolWebSocketHandler to be created.

Issue: SPR-13190
2015-07-02 16:09:39 -04:00
Sebastien Deleuze
6c58258d11 Update AbstractSockJsService and ref doc to SockJS client 1.0.0
Issue: SPR-12422
2015-07-02 15:38:36 +02:00
Rossen Stoyanchev
e083683f4f Update WebSocket support for Jetty 9.3
Issue: SPR-13140
2015-06-22 22:30:44 -04:00
Rossen Stoyanchev
25ff34f3c7 JettyRequestUpgradeStrategy implements Lifecycle
After this change JettyRequestUpgradeStrategy implements Lifecyle,
which is used to init and cleanup the Jetty WebSocketServerFactory.

Since a RequestUpgradeStrategy is typically created reflectively
within DefaultHandshakeHandler, the Lifecycle events are propagated
from the top, i.e. the Spring MVC HandlerMapping through the
WebSocket/SockJsHttpRequestHandler.

Issue: SPR-13140
2015-06-22 22:30:44 -04:00
Rossen Stoyanchev
b6b76ad1b4 Polish WebMvcStompEndpointRegistry 2015-06-22 22:30:44 -04:00
Rossen Stoyanchev
d1cc8bac5c Add config option for StompSubProtocolErrorHandler
Issue: SPR-13142
2015-06-22 22:30:44 -04:00
Juergen Hoeller
92bf32b9be Polishing 2015-05-23 20:04:48 +02:00
Juergen Hoeller
e0a11f2ae7 SockJsTransportFailureException provides constructor variant without session id 2015-05-23 20:02:42 +02:00
Juergen Hoeller
05d475a275 Polishing 2015-05-22 23:50:47 +02:00
Rossen Stoyanchev
c48e8708a7 Fix NPE in DefaultSimpUserRegistry 2015-05-22 13:44:09 -04:00
Rossen Stoyanchev
92bd7bba50 Restore userSessionRegistry field in StompSubProtocolHandler
This change ensures that the deprecated UserSessionRegistry is still
used if configured.
2015-05-22 13:44:09 -04:00
Juergen Hoeller
b4095c3e1d Class identity comparisons wherever possible
Issue: SPR-12926
2015-05-20 14:34:16 +02:00
Rossen Stoyanchev
696a010e81 Add SubProtocolErrorHandler
Issue: SPR-12732
2015-05-15 18:18:05 -04:00
Juergen Hoeller
02d28ae9ee Actual hasText assertion in SockJsFrame
Issue: SPR-13019
2015-05-13 14:54:36 +02:00
Juergen Hoeller
49c600b234 Resolved cyclic dependency between handler.invocation and handler.annotation
Issue: SPR-12696
2015-05-12 22:04:59 +02:00
Rossen Stoyanchev
281588d7bb Add SimpUserRegistry with multi-server support
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
2015-05-12 15:29:12 -04:00
Brian Clozel
4b07bc39da Always set heart-beat header in STOMP CONNECTED frames
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
2015-05-05 16:09:42 +02:00
Rossen Stoyanchev
49e90575e9 Disable ShallowEtagHeaderFilter for HTTP streaming
Issue: SPR-12960
2015-05-04 06:08:25 -04:00
Rossen Stoyanchev
68ecb92d1f Allow "ws" and "wss" for isValidCorsOrigin checks
Issue: SPR-12956
2015-05-04 06:08:25 -04:00
Rossen Stoyanchev
222f6998e4 Add userProperties to StandardWebSocketClient
Issue: SPR-12955
2015-05-04 06:08:25 -04:00
Rossen Stoyanchev
c29eae3307 Support user destinations with multiple app servers
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
2015-04-17 11:55:44 -04:00
Rossen Stoyanchev
a3df66931f Add path-helper attribute for websocket namespace
Issue: SPR-11771
2015-04-13 22:39:50 -04:00
Rossen Stoyanchev
de9675bf5a Support heartbeat in SimpleBrokerMessageHandler
Issue: SPR-10954
2015-04-06 16:57:23 -04:00
Sebastien Deleuze
b0e1e66b7f Add CORS support
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
2015-04-02 16:12:11 +02:00
Brian Clozel
100d75da26 Fix client-library-url ignored in MVC namespace
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
2015-04-01 14:44:12 +02:00
Rossen Stoyanchev
73d6d30951 Add flag whether to create HTTP session
Issue: SPR-12840
2015-03-26 17:28:26 -04:00
Juergen Hoeller
d23893fd25 Consistent javadoc param declarations for type variables 2015-03-25 00:44:01 +01:00
Rossen Stoyanchev
e81862eed6 Allow modifying HandshakeInterceptor list
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.
2015-03-24 18:03:15 -04:00
Rossen Stoyanchev
0c9cd4cc32 SubProtocolWebSocketHandler checks if session is open
Issue: SPR-12812
2015-03-20 17:45:27 -04:00
Rossen Stoyanchev
41e437066e Support @MessageExceptionHandler w/ @ControllerAdvice
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
2015-03-19 14:21:24 -04:00
Sam Brannen
9930a8715f Clean up & suppress warnings in spring-messaging 2015-03-17 17:58:32 +01:00
Rossen Stoyanchev
d30b3eaf55 Add STOMP client
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
2015-03-12 21:48:29 -04:00
Juergen Hoeller
2b3409461f Polishing 2015-02-27 22:29:42 +01:00
Sebastien Deleuze
90e6304b49 Adjust log level for invalid SockJS or Websocket requests 2015-02-19 16:52:19 +01:00
Rossen Stoyanchev
917eb1de0b Ignore Pong messages in StompSubProtocolHandler
Issue: SPR-12728
2015-02-18 11:52:59 -05:00
Rossen Stoyanchev
1f990c3df6 Fix handling of empty payload Pong message on Jetty
Issue: SPR-12727
2015-02-18 11:36:22 -05:00
Sebastien Deleuze
6062e15572 Change SockJS and Websocket default allowedOrigins to same origin
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
2015-02-18 09:30:15 +01:00
Rossen Stoyanchev
b4fa1c24cc Pass SockJS session attributes to HandshakeHandler
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
2015-02-16 14:12:12 -05:00
Sebastien Deleuze
9b3319b3b3 Fix SockJS origin check
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
2015-02-09 11:56:51 +01:00
Ralph Schaer
e0d407dad0 Fix javadoc 2015-02-03 10:41:56 -05:00
Rossen Stoyanchev
52b8f34468 Add JdkIdGenerator and use it in SockJS client
Issue: SPR-12658
2015-01-22 21:27:36 -05:00
Rossen Stoyanchev
ab629a0e26 Deprecate writePrelude in AbstractHttpSockJsSession
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
2015-01-13 10:26:59 -05:00
Rossen Stoyanchev
43d93712f1 Remove isStreaming flag from AbstractHttpSockJsSession
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
2015-01-12 14:48:09 -05:00
Rossen Stoyanchev
51367dec05 Refine condition to send WebSocket binary messages
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
2014-12-29 15:13:09 -05:00
Rossen Stoyanchev
670974d76a Allow sending binary messages with STOMP
After this change the StompSubProtocolHandler sends STOMP frames
with content-type=octet-stream as a binary WebSocket message.

Issue: SPR-12475
2014-12-23 14:24:43 -05:00
Rossen Stoyanchev
b796c1e87e Synchronize message sending
Issue: SPR-12516
2014-12-07 16:10:40 -05:00
Sebastien Deleuze
2fccf3ff44 Add support for autowiring Jackson handlers
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
2014-12-05 17:37:28 +01:00
Sebastien Deleuze
fbd85925de Use Jackson improved default configuration everywhere
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
2014-12-03 09:49:41 +01:00
Rossen Stoyanchev
dc5b5ca8ee Check the user of a SockJS request
Issue: SPR-12497
2014-12-02 12:13:35 -05:00
Juergen Hoeller
e6d7af4ea8 Polishing 2014-11-28 17:36:58 +01:00