The resolved URI instance is also being cached now. This should not make a difference in a real Servlet environment but does affect tests which assumed they could modify an HttpServletRequest path behind a pre-created ServletServerHttpRequest instance. Our WebSocket test base class has been revised accordingly, re-creating the ServletServerHttpRequest in such a case.
Issue: SPR-16414
After this commit, AbstractSockJsService uses the configured allowed
origins when generating the CorsConfiguration instead of "*".
As a consequence, forbidden origin requests still result in a 403
response but now with no CORS headers in order to improve consistency
between the status code and the headers.
Issue: SPR-16304
This commit introduces the following changes.
1) It adds a new Spring @NonNull annotation which allows to apply
@NonNullApi semantic on a specific element, like @Nullable does.
Combined with @Nullable, it allows partial null-safety support when
package granularity is too broad.
2) @Nullable and @NonNull can apply to ElementType.TYPE_USE in order
to be used on generic type arguments (SPR-15942).
3) Annotations does not apply to ElementType.TYPE_PARAMETER anymore
since it is not supported yet (applicability for such use case is
controversial and need to be discussed).
4) @NonNullApi does not apply to ElementType.FIELD anymore since in a
lot of use cases (private, protected) it is not part for the public API
+ its usage should remain opt-in. A dedicated @NonNullFields annotation
has been added in order to set fields default to non-nullable.
5) Updated Javadoc and reference documentation.
Issue: SPR-15756
This commit applies the Dependency Management Plugin to modules that
require it; right now Spring Framework is importing BOMs for Netty and
Reactor dependencies only.
Instead of applying those BOMs to all modules, they're applied only
where they're needed.
Issue: SPR-15885
The main `build.gradle` file contains now only the common build
infrastructure; all module-specific build configurations have
been moved to their own build file.
Issue: SPR-15885
This commit ensure that null-safety is consistent between
getters and setters in order to be able to provide beans
with properties with a common type when type safety is
taken in account like with Kotlin.
It also add a few missing property level @Nullable
annotations.
Issue: SPR-15792
This commits extends nullability declarations to the field level, formalizing the interaction between methods and their underlying fields and therefore avoiding any nullability mismatch.
Issue: SPR-15720
Beyond just formally declaring the current behavior, this revision actually enforces non-null behavior in selected signatures now, not tolerating null values anymore when not explicitly documented. It also changes some utility methods with historic null-in/null-out tolerance towards enforced non-null return values, making them a proper citizen in non-null assignments.
Some issues are left as to-do: in particular a thorough revision of spring-test, and a few tests with unclear failures (ignored as "TODO: NULLABLE") to be sorted out in a follow-up commit.
Issue: SPR-15540
This commit introduces 2 new @Nullable and @NonNullApi
annotations that leverage JSR 305 (dormant but available via
Findbugs jsr305 dependency and already used by libraries
like OkHttp) meta-annotations to specify explicitly
null-safety of Spring Framework parameters and return values.
In order to avoid adding too much annotations, the
default is set at package level with @NonNullApi and
@Nullable annotations are added when needed at parameter or
return value level. These annotations are intended to be used
on Spring Framework itself but also by other Spring projects.
@Nullable annotations have been introduced based on Javadoc
and search of patterns like "return null;". It is expected that
nullability of Spring Framework API will be polished with
complementary commits.
In practice, this will make the whole Spring Framework API
null-safe for Kotlin projects (when KT-10942 will be fixed)
since Kotlin will be able to leverage these annotations to
know if a parameter or a return value is nullable or not. But
this is also useful for Java developers as well since IntelliJ
IDEA, for example, also understands these annotations to
generate warnings when unsafe nullable usages are detected.
Issue: SPR-15540
Failures in JettySockJsIntegrationTests after the upgrade to 9.4 were
hidden due to the PERFORMANCE test group but were failing on the CI
performance build with IllegalStateException inside Jetty on
"Failure find the required ServletContext attribute
org.eclipse.jetty.util.DecoratedObjectFactory".
Rename classes not specific to Tomcat:
TomcatWebSocketSession -> StandardWebSocketSession
TomcatWebSocketHandlerAdapter -> StandardWebSocketHandlerAdapter
WebSocketSessionSupport is renamed to AbstractWebSocketSession since it
actually is a WebSocketSession and pre-implements a number of methods.
ServerEndpointRegistration is now package private (mainly for use in
upgrade strategies) and renamed to DefaultServerEndpointConfig.
This commit makes it possible for a ChannelInterceptor to override the
user header in a Spring Message that contains a STOMP CONNECT frame.
After the message is sent, the updated user header is observed and
saved to be associated with session thereafter.
Issue: SPR-14690
Due to a few changes in `WebSocketServerFactory` and `Session` API, our
`JettyRequestUpgradeStrategy` and `JettyWebSocketSession` needed to
adapt. As of 9.3.15+ and 9.4.0+, some reflection is required to support
previous versions.
Spring 5.0 supports Jetty 9.3 and 9.4.
Issue: SPR-14940
When processing a "close" notification from the server make an effort
to cancel any outstanding heartbeat but avoid going as far as acquiring
the responseLock since the server itself may already hold a lock of its
own leading to a potential deadlock.
The heartbeat task is now also further protected with an isClosed()
check in case the heartbeat does not get cancelled in a concurrent
scenario.
Issue: SPR-14917
This commits adds a validation check whether the SockJS session type
matches the transport type and rejects requests for which they
don't match.
Issue: SPR-14867
Create an explicit heartbeat task with an experiration flag so that
it can be cancelled reliably vs relying on the ScheduledFutureTask
cancel method which may return true even if the task is already
running.
Issue: SPR-14356
This commit adds a test runtime dependency on log4j 2 for every project
and migrates all log4j.properties files to log4j2-test.xml files.
Issue: SPR-14431
Prior to this commit, any attempt to include a bean of type
ServletServerContainerFactoryBean in the WebApplicationContext for an
integration test class annotated with @WebAppConfiguration in
conjunction the Spring TestContext Framework (TCF) would have resulted
in an IllegalStateException stating that "A ServletContext is required
to access the javax.websocket.server.ServerContainer instance."
In such scenarios, the MockServletContext was in fact present in the
WebApplicationContext; however there was no WebSocket ServerContainer
stored in the ServletContext.
This commit addresses this issue by introducing the following.
- MockServerContainer: a private mock implementation of the
javax.websocket.server.ServerContainer interface.
- MockServerContainerContextCustomizer: a ContextCustomizer that
instantiates a new MockServerContainer and stores it in the
ServletContext under the attribute named
"javax.websocket.server.ServerContainer".
- MockServerContainerContextCustomizerFactory: a
ContextCustomizerFactory which creates a
MockServerContainerContextCustomizer if WebSocket support is present
in the classpath and the test class is annotated with
@WebAppConfiguration. This factory is registered by default via the
spring.factories mechanism.
Issue: SPR-14367
Even before this change SockJS sessions always cancelled the heartbeat
task first prior to sending messages. However when the heartbeat task
is already in progress, cancellation of it is not enough and we must
wait until the heartbeat is sent.
This commit adds a heartbeat write lock which is obtained and held
during the sending of a heartbeat. Now when sessions send a message
they still cancel the heartbeat task but if that fails they also wait
for the heartbeat write lock.
Issue: SPR-14356
Prior to this change, getting header values with `HttpHeaders` when
headers are multi-valued would cause issues.
For example, for a given HTTP message with headers:
Cache-Control: public, s-maxage=50
Cache-Control: max-age=42
Getting a `List` of all values would return <"public", "s-maxage=50">
and getting the header value would return "public, s-maxage=50".
This commit takes now into account multi-valued HTTP headers and adds
new getters/setters for "If-Match" and "If-Unmodified-Since" headers.
Note that for ETag-related headers such as "If-Match" and
"If-None-Match", a special parser has been implemented since ETag values
can contain separator characters.
Issue: SPR-14223, SPR-14228
Previous refactoring (fcf6ae and also 43d937) in the SockJsSession
hierarchy consolidated access to the request and response in the
base class AbstractHttpSockJsSession in order to keep synchronization
concerns there. However that also unintentionally removed the call to
resetRequest() after sending a heartbeat for any of the
PollingSockJsSession classes. In general a polling session should call
resetRequest after every frame written.
This commit brings back the writeFrame override in PollingSockJsSession
with an extra call to resetRequest().
Issue: SPR-14107
Commit 48236b from 2014 introduced a logging improvement to avoid
logging each removed session per line and instead log one line at
the end with all removed sessions ids. However that list of removed
session ids wasn't populated. This commit fixes that.
Issue: SPR-14111
Before this commit the DefaultUserDestinationResolver did not support
well broker destinations that use dot as separator with a built in
assumptions that the destinations it resolves must start with slash.
This change adds PathMatcher property that is used to determine if
an alternative path separator is in use and if so the leading slash is
left out.
Issue: SPR-14044
This commit adds a new "validator" XML attribute to the
`<websocket:message-broker/>` element. This allows configuring a
specific Validator to be used for payload validation.
Issue: SPR-13996
Before this commit the concurrent session wrapper mainly protected the
sending of messages. The close itself however may also cause a message
to be sent as is the case of the SockJS protocol.
This change protects the close and checks if the session has exceeded
send time or buffer limits in which case the close status is changed
to SESSION_NOT_RELIABLE (introduced in commit cbd5af3a) which in turn
signals that extra care should be exercised when closing the session.
Issue: SPR-13904
As of Tyrus 1.9, `TyrusEndpointWrapper`'s constructor has a new Boolean
argument (which is mandatory).
This commit reflectively chooses the right constructor method for Tyrus
1.9+ versions.
Issue: SPR-13566
As of Undertow 1.3.0, several APIs have been changed: replacing Xnio's
Pool/Pooled references to Undertow's new ByteBufferPool abstraction.
This move has been made, as part of
https://issues.jboss.org/browse/UNDERTOW-522, to prepare deprecations in
the Xnio API.
This commit adds a new strategy to deal with both 1.0-1.2 and 1.3
Undertow generations.
Issue: SPR-13366
Xnio 3.4.0 will introduce a new source of ByteBuffers: ByteBufferPool.
Previously this feature was offered by Pooled/Pool/ByteBufferSlicePool;
those classes are now marked as deprecated.
As of 1.3.0.Beta9, Undertow still implements the following method in its
ClientConnection interface, using those deprecated types:
Pool<ByteBuffer> getBufferPool();
This commit prepares compatibility by suppressing warnings in order to
avoid build failures in our build. Once appropriate changes are made in
Undertow, a specific implementation with new types could be introduced.
Issue: SPR-13366
In an attempt to make our Jetty-based integration tests more robust,
this commit discontinues use of SocketUtils for picking a random,
available port and instead lets the Jetty Server pick its own port.
The StompSubProtcolHandler now checks the outcome of the send to the
inbound client channel. If the message was prevented from being sent,
e.g. as part of authorization, events are not published
Issue: SPR-13339
Before this change, XhrTransport implementations had to be configured
with the headers to use for HTTP requests other than the initial
handshake.
After this change the handshake headers passed to SockJsClient by
default are used for all other HTTP requests related to the SockJS
connection (e.g. info request, xhr send/receive). A property on
SockJsClient allows restricting the headers to use for other HTTP
requests to a subset of the handshake headers.
Issue: SPR-13254
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