Rather than formatting the expected value, and be susceptible to
minor formatting differences (e.g. 01 vs 1 for day of month), parse the
actual header value leniently with HttpHeaders and compare time values.
Issue: SPR-17330
If the content has not been consumed, cause it to be produced, and
wait for a certain amount of time before giving up, so the raw content
can be made available. This can occur when:
1) In a mock server scenario the Flux representing the client request
content is passed directly to the mock server request, but is never
consumed because of an error before the body is read.
2) Test obtains FluxExchangeResult (e.g. for streaming) but instead of
consuming the Flux, it calls getResponseBodyContent() instead.
Issue: SPR-17363
This commit adds special processing of some HTTP response headers in
Jetty and Tomcat; they both consider some headers like "Content-Length"
as specific and require explicit calls on the `HttpServletResponse`
itself on top of setting the HTTP response header.
Issue: SPR-17250
This commit avoids copying HTTP headers when mutating an HTTP request.
Instead, we're now unwrapping the `ReadOnlyHttpHeaders` (which is most
likely backed by the native request headers).
Issue: SPR-17250
Several benchmarks underlined a few hotspots for CPU and GC pressure in
the Spring Framework codebase:
1. `org.springframework.util.MimeType.<init>(String, String, Map)`
2. `org.springframework.util.LinkedCaseInsensitiveMap.convertKey(String)`
Both are linked with HTTP request headers parsing and response headers
writin during the exchange processing phase.
1) is linked to repeated calls to `HttpHeaders.getContentType`
within a single request handling. The media type parsing operation
is expensive and the result doesn't change between calls, since
the request headers are immutable at that point.
This commit improves this by caching the parsed `MediaType` for the
`"Content-Type"` request header in the `ReadOnlyHttpHeaders` class.
This change is available for both Spring MVC and Spring WebFlux.
2) is linked to insertions/lookups in the `LinkedCaseInsensitiveMap`,
which is the data structure behind `HttpHeaders`.
Those operations are creating a lot of garbage (including a lot of
`String` created by `toLowerCase`). We could choose a more efficient
data structure for storing HTTP headers data.
As a first step, this commit is focusing on Spring WebFlux and
introduces `MultiValueMap` implementations mapped by native HTTP headers
for the following servers: Tomcat, Jetty, Netty and Undertow.
Such implementations avoid unnecessary copying of the headers
and leverages as much as possible optimized operations provided by the
native implementations.
This change has a few consequences:
* `HttpHeaders` can now wrap a `MultiValueMap` directly
* The default constructor of `HttpHeaders` is still backed by a
`LinkedCaseInsensitiveMap`
* The HTTP request headers for the websocket HTTP handshake now need to
be cloned, because native headers are likely to be pooled/recycled by
the server implementation, hence gone when the initial HTTP exchange is
done
Issue: SPR-17250
Previously, if a DeferredImportSelector was identified at a later stage
as part of processing the collected set of deferred imports, such
selector was processed as a regular import selector.
Semantically, it makes sense as we already are in the deferred phase at
this point and it doesn't make much sense to bother about the extra
contract.
However, Spring Framework 5 introduced the notion of Group that a
deferred import selector can define. When it does, the container has to
honour the contract of the Group rather than calling the simpler
ImportSelector parent contract.
This commit restructures the processing of such case. When a deferred
import selector is detected while processing deferred import selectors,
a group is created with only that selector and the group API is invoked.
Issue: SPR-17351
Includes use of Files.getLastModifiedTime for NIO Paths, preservation of NIO-based resolution on createRelative, deprecation of PathResource, and consistent use of getContentLengthLong over getContentLength.
Issue: SPR-17320
This was a package private class in spring-messaging since 5.0, and was
recently made public in 5.1. This commit promotes it to spring-core
where it belongs next to all other ListenableFuture support classes.
Follow-up refactoring for SPR-17336
Collapse the package private AbstractMonoToListenableFutureAdapter into
its only sub-class MonoToListenableFutureAdapter. There is no need for
such an abstract class that makes it possible to adapt from one source
to a different target type. That's already covered by
ListenableFutureAdapter.
Follow-up refactoring for SPR-17336.
Spring Framework 5.1.0 exposed by mistake context in the Kotlin bean DSL
API in order to fix SPR-16269. Now that BeanFactory#getBeanprovider is
available, it should be exposed via a provider<Foo>() function in order
to provide a more clean API instead.
Issue: SPR-17352