Polish a few issue identified when adding checkstyle to the
build. Although checkstyle is not enforcing rules on tests,
these are a few minor changes that are still worth making.
Issue: SPR-16968
Reorganize imports to ensure consistent ordering. This commit also
expands any `.*` static imports in favor of using fully-qualified
method references.
Issue: SPR-16968
Update all classes so that inner classes are always last. Also
ensure that utility classes are always final and have a private
constructor and make exceptions final whenever possible.
Issue: SPR-16968
In SPR-16892, the `EncoderHttpMessageWriter` has been improved to write
`"Content-Length"` HTTP response headers if the response body is of type
`Mono` (i.e. the actual content length is easily accessible without
buffering a possibly large response body). That change was relying on
the fact that the server side is using a `ChannelSendOperator` to delay
the writing of the body until the first signal is received.
This strategy is not effective on the client side, since no such channel
operator is used for `WebClient`. This commit improves
`EncoderHttpMessageWriter` and delays, for `Mono` HTTP message bodies
only, the writing of the body so that we can write the
`"Content-Length"` header information once we've got the body resolved.
Issue: SPR-16949
This commit adds support for the "SameSite" attribute in response
cookies. As explained in rfc6265bis, this attribute can be used to limit
the scope of a cookie so that it can't be attached to a request unless
it is sent from the "same-site".
This feature is currently supported by Google Chrome and Firefox, other
browsers will ignore this attribute.
This feature can help prevent CSRF attacks; this is why this commit adds
this attribute by default for SESSION Cookies in WebFlux.
See: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis
Issue: SPR-16418
Also, ZeroCopyHttpOutputMessage provides writeWith(Path, int, int), enforcing that variant as the implementation target in 5.1 (analogous to FilePart).
Issue: SPR-16925
@PathVariable's javadoc states that it supports MultiValueMap
parameters (introduced by commit df0902), but by reading through the
code, that does not seem to be the case (compare, e.g.,
PathVariableMapMethodArgumentResolver to
RequestParamMapMethodArgumentResolver).
Moreover, parsing MultipleValueMap is done according to the ";"
character, and placing such a character in a path (e.g., consider
something like "/app/{param}/show" would just break the path.
This patch fixes PathVariable's javadoc by removing the mention of
MultiValueMap.
This commit fixes the write checks for
`ResourceRegionHttpMessageConverter`, which was previously not checking
properly the parameterized type (e.g. in case of a `List<Something>`).
Issue: SPR-16932
This commit restricts the allowed HTTP methods on HiddenHttpMethodFilter
(Reactive variant) to the following: PUT, DELETE, PATCH.
This filter is meant to be used to simulate those methods from HTML
forms sent by browsers, so no other methods are allowed.
Issue: SPR-16836
This commit restricts the allowed HTTP methods on HiddenHttpMethodFilter
(Servlet variant) to the following: PUT, DELETE, PATCH.
This filter is meant to be used to simulate those methods from HTML
forms sent by browsers, so no other methods are allowed.
Issue: SPR-16836
Prior to this commit, the generated POMs for Spring Framework modules
would contain unneeded/harmful information from the Spring Framework
build:
1. The BOM imports applied to each module by the dependency
management plugin, for example for Netty or Reactor Netty.
Spring should not export that opinion to its POMs.
2. The exclusion of "org.slf4:jcl-over-slf4j" from *all* dependencies,
which made the POMs much larger than necessary and suggested to
developers that they should exclude it as well when using all those
listed dependencies. In fact, only Apache Tiles currently brings that
transitively.
This commit removes that information from the POMs.
The dependencyManagement Gradle plugin is disabled for POM generation
and we manually resolve the dependency versions during the generation
phase.
The Gradle build is streamlined to exclude "org.slf4:jcl-over-slf4j"
only when necessary.
Issue: SPR-16893
This commit adds FormContentFilter, which is the same as the
HttpPutFormContentFilter but also supports DELETE.
The HttpPutFormContentFilter is now deprecated.
Issue: SPR-16874
DefaultMultipartHttpServletRequest always returned mulitpart parameter
values only rather than aggregating with query parameters, which
contradicts with Servlet spec, section 3.1, and is inconsistent with
StandardMultipartHttpServletRequest.
Issue: SPR-16590
This commit removes all places where forwarded headers are checked
implicitly, on an ad-hoc basis.
ForwardedHeaderFilter is expected to be used instead providing
centralized control over using or discarding such headers.
Issue: SPR-16668
With this commit, WebFlux server uses warning instead of error log level
for request handling, and also just print the message instead of the
stacktrace which is mostly meaningless in reactive world.
Complementary to this change, Reactor Netty removed additional logging
as part of https://github.com/reactor/reactor-netty/issues/339.
Issue: SPR-16688
ServerSentEventHttpMessageReader had logic to split on new lines
and buffer until an empty new line (start of a new event). To account
for random data chunking, it later re-assembled the lines for each
event and split again on new lines. However bufferUntil was still
unreliable a chunk may contain nothing but a newline, which doesn't
necessarily mean an empty newline in the overall SSE stream.
This commit simplifies the above by delegating the splitting of the
stream along newlines to StringDecoder.
Issue: SPR-16744
Prior to this commit, the various `HttpMessageConverter` instances
configured for a given `RestTemplate` instance could all contribute
`MediaType` values to the "Accept:" request header.
This could lead to duplicate media types in that request header,
cluttering for the HTTP request for no reason.
This commit ensures that only distinct values are added to the request.
Issue: SPR-16690
Using the simple example shown in the ticket but switching from
Mono<String> to Flux<String> (and 5,000,000 onNext calls) shows that
constant pausing causes significant overhead and is not worth the
trouble vs ignoring the onWritePossible in REQUESTED state.
Issue: SPR-16702
Undertow does not provide a way to check if we can write so with the
current implementation of isWritePossible, deep recursion can occur
when writing slows down. We now use a flag to keep track of write
ChannelListener callbacks.
This commit also addresses a related issue in
AbstractListenerWriteProcessor that went undected since #3c2d186
where after a large (single) buffer that is not written fully, the
completion signal is processed before the all data is written.
Issue: SPR-16702
This commit documents the difference between configuring the socket
timeout on the `RequestConfig` and on the `SocketConfig`.
The first one does not affect timeouts when establishing an SSL
connection or sending a CONNECT request to a proxy. For these use cases,
it is required to configure `SocketConfig` on the `HttpClient` instance
directly.
Issue: SPR-16697
This breaks the package dependency cycle between web.server/web.method and makes ServerErrorException more generally applicable. Includes deprecation of the plain reason constructor variant, in favor of providing a Method or MethodParameter context (which MatrixVariableMethodArgumentResolver does now).
Consistently return "*/*" if no media types were requested rather than
an empty list. Existing code has to check for both in any case to see
if nothing was requested.
Issue: SPR-16624
The web.server package is quite low-level and should not depend on web.bind in order to avoid a dependency cycle. Extracting the introspection of the ResponseStatus annotation into a WebFlux-level subclass resolves the cycle.
Issue: SPR-16567
Undertow does not provide a way to check if data is available to read
but instead we have to try to read and see if any data is returned.
This makes it impossible to implement checkOnDataAvailable without
trying to read and that can lead to infinite recursion like this:
...
UndertowServerHttpRequest$RequestBodyPublisher.checkOnDataAvailable(UndertowServerHttpRequest.java:156)
AbstractListenerReadPublisher.changeToDemandState(AbstractListenerReadPublisher.java:177)
AbstractListenerReadPublisher.access$900(AbstractListenerReadPublisher.java:47)
AbstractListenerReadPublisher$State$4.onDataAvailable(AbstractListenerReadPublisher.java:319)
AbstractListenerReadPublisher.onDataAvailable(AbstractListenerReadPublisher.java:85)
UndertowServerHttpRequest$RequestBodyPublisher.checkOnDataAvailable(UndertowServerHttpRequest.java:156)
This commit prevent the call to checkOnDataAvailable() when switching
states from READING->DEMAND which implies we exited the readAndPublish
loop because there was no more data to read.
Issue: SPR-16545
When checking whether there is still request body the first method
that should be checked is ServletInputStream.isReady() and then
ServletInputStream.isFinished(). ServletInputStream.isReady() is the active
method whereas the ServletInputStream.isFinished() is not.
It is important to call ServletInputStream.isReady() because if it returns
false it will schedule a dispatch and if the request body is already read it will
send onAllDataRead event.
Issue: SPR-16521