Based on feedback from several members of the community, we have
decided to revert the caching of the Content-Type header that was
introduced in ContentCachingResponseWrapper in 375e0e6827.
This commit therefore completely removes Content-Type caching in
ContentCachingResponseWrapper and updates the existing tests
accordingly.
To provide guards against future regressions in this area, this commit
also introduces explicit tests for the 6 ways to set the content length
in ContentCachingResponseWrapper and modifies a test in
ShallowEtagHeaderFilterTests to ensure that a Content-Type header set
directly on ContentCachingResponseWrapper is propagated to the
underlying response even if content caching is disabled for the
ShallowEtagHeaderFilter.
See gh-32039
See gh-32317
Closes gh-32322
Commit 375e0e6827 introduced a regression in
ContentCachingResponseWrapper (CCRW). Specifically, CCRW no longer
honors Content-Type and Content-Length headers that have been set in
the wrapped response and now incorrectly returns null for those header
values if they have not been set directly in the CCRW.
This commit fixes this regression as follows.
- The Content-Type and Content-Length headers set in the wrapped
response are honored in getContentType(), containsHeader(),
getHeader(), and getHeaders() unless those headers have been set
directly in the CCRW.
- In copyBodyToResponse(), the Content-Type in the wrapped response is
only overridden if the Content-Type has been set directly in the CCRW.
Furthermore, prior to this commit, getHeaderNames() returned duplicates
for the Content-Type and Content-Length headers if they were set in the
wrapped response as well as in CCRW.
This commit fixes that by returning a unique set from getHeaderNames().
This commit also updates ContentCachingResponseWrapperTests to verify
the expected behavior for Content-Type and Content-Length headers that
are set in the wrapped response as well as in CCRW.
See gh-32039
See gh-32317
Closes gh-32322
This commit ensures that setting the Content-Length through
setHeader("Content-Length", x") has the same effect as calling
setContentLength in the ShallowEtagHeaderFilter. It also filters out
Content-Type headers similarly to Content-Length.
See gh-32039
Closes gh-32051
This commit adds CORS support for Private Network Access
by adding an Access-Control-Allow-Private-Network response
header when the preflight request is sent with an
Access-Control-Request-Private-Network header and that
Private Network Access has been enabled in the CORS
configuration.
See https://developer.chrome.com/blog/private-network-access-preflight/
for more details.
Closes gh-31974
(cherry picked from commit 318d460256)
Prior to this commit, the Jackson 2.x encoders, in case of encoding a
stream of data, would first release the `ByteArrayBuilder` and then the
`JsonGenerator`. This order is inconsistent with the single value
variant (see `o.s.h.codec.json.AbstractJackson2Encoder#encodeValue`) and
invalid since the `JsonGenerator` uses internally the
`ByteArrayBuilder`.
In case of a CSV Encoder, the codec can buffer data to write the column
names of the CSV file. Writing an empty Flux with this Encoder would not
fail but still log a NullPointerException ignored by the reactive
pipeline.
This commit fixes the order and avoid such issues at runtime.
Fixes gh-31657
This commit changes the FatalBeanException previously thrown for
an IllegalArgumentException which seems more suitable for that
use case.
Closes gh-29860
Prior to this commit, extracting the path within handler mapping would
result in "" if the matching path element would be a Regex and contain
".*". This could cause issues with resource handling if the handler
mapping pattern was similar to `"/folder/file.*.extension"`.
This commit introduces a new `isLiteral()` method in the `PathElement`
abstract class that expresses whether the path element can be compared
as a String for path matching or if it requires a more elaborate
matching process.
Using this method for extracting the path within handler mapping avoids
relying on wildcard count or other properties.
See gh-29712
Fixes gh-29716
When running on JDK 16+, we are not able to spy() on JDK types. To
address this, this commit stops using Mockito to spy on JDK I/O streams
(such as ByteArrayInputStream and ByteArrayOutputStream).
Conditional requests using "If-Unmodified-Since" headers are generally
used as precondition checks for state-changing methods (POST, PUT,
DELETE). See https://datatracker.ietf.org/doc/html/rfc7232#section-3.4
The spec also allows for idempotent methods like GET and HEAD.
Prior to this commit, the "If-Unmodified-Since" processing done in
`checkNotModified` (see `ServletWebRequest` and
`DefaultServerWebExchange`) would only focus on the state changing
methods and not take into account the safe methods. For those cases, the
"ETag" and "Last-Modified" would be missing from the response.
This commit ensures that such headers are added as expected in these
cases.
Fixes gh-29362
Prior to this commit, `ServletContextResource` could rely on
`ServletContext#getRealPath` to check whether a resource exists.
This behavior is not enforced on some Servlet containers, as this method
is only meant to translate virtual paths to real paths, but not
necessarily check for the existence of the file.
See https://bz.apache.org/bugzilla/show_bug.cgi?id=55837#c3 for a
rationale of this behavior in Tomcat.
This commit enforces an additional check, resolving the path as a `File`
and checking that is exists and is a file.
Closes gh-26707
This commit fixes Kotlin Serialization converter
registration logic in RestTemplate,
AbstractMessageBrokerConfiguration and
AllEncompassingFormHttpMessageConverter classes
to be similar to the one in
WebMvcConfigurationSupport.
Closes gh-29008
Prior to this commit, getPort() in HierarchicalUriComponents threw a
NumberFormatException for an invalid port supplied as a String, which
was inconsistent with exception handling elsewhere in the class as well
as within the same method.
This commit introduces a try-catch block in getPort() to consistently
throw IllegalStateExceptions for ports that cannot be parsed.
Closes gh-28521
SocketUtils was introduced in Spring Framework 4.0, primarily to assist
in writing integration tests which start an external server on an
available random port. However, these utilities make no guarantee about
the subsequent availability of a given port and are therefore
unreliable. Instead of using SocketUtils to find an available local
port for a server, it is recommended that users rely on a server's
ability to start on a random port that it selects or is assigned by the
operating system. To interact with that server, the user should query
the server for the port it is currently using.
SocketUtils is now deprecated in 5.3.16 and will be removed in 6.0.
Closes gh-28052