Since its inception, instantiating an `HttpEntity` makes its
`HttpHeaders` read-only. While immutability is an interesting design
principle, here we shouldn't enforce this.
For example, developers can expect to instantiate a `ResponseEntity`
and still mutate its headers.
Closes gh-35888
Prior to this commit, `RestTestClient` tests could only perform
expectations on the response without consuming the body. In this case,
the client could leak HTTP connections with the underlying HTTP library
because the response was not entirely read.
This commit ensures that the response is always fully drained before
performing expectations. The client is configured to buffer the response
content, so further body expectations are always possible.
Fixes gh-35784
This commit adds an integration test for `WebClient`, specifically
testing that a failure happening while pulishing the request body is
reported on the main reactive pipeline.
See gh-35678
Prior to this commit, `WebClientResponseException` would only support
the deprecated "unprocessable entity" status.
This commit adds the missing support for "unprocessable content" when
creating exceptions with `WebClientResponseException#create`.
Fixes gh-35802
Prior to this commit, `HttpMessageConverters` would assert that the
given converter in `withXmlConverter` has a media type that is equal to
"application/xml" in its list of supported converters.
This approach would not work if the given converter supports
"application/xml;charset=UTF-8" because of the strict equal check being
performed.
This commit ensures that we only consider the type and subtype of the
considered media types when comparing, removing the parameters from the
picture.
Fixes gh-35801
Prior to this commit, the `ReactorClientHttpRequestFactory` and the
`ReactorClientHttpRequest` would use the `Executor` from the current
event loop for performing write operations.
Depending on I/O demand, this work could be blocked and would result in
blocked Netty event loop executors and the HTTP client hanging.
This commit ensures that the client uses a separate Executor for such
operations. If the application does not provide one on the request
factory, a `Schedulers#boundedElastic` instance will be used.
Fixes gh-34707
This commit ensures that the JAR verification task runs on JDK 25 as
this feature has been introduced in https://bugs.openjdk.org/browse/JDK-8355940
Fixes gh-35777
See gh-35773
This commit ensures that both `VirtualThreadDelegate` implementations
expose the same public API. If not, JAR verification fails with the
following message:
```
jar --validate --file spring-core-6.2.13-SNAPSHOT.jar
entry: META-INF/versions/21/org/springframework/core/task/VirtualThreadDelegate.class, contains a class with different api from earlier version
```
Fixes gh-35773
Prior to this commit, gh-35213 allowed wildcard path elments at the
start of path patterns. This came with an additional constraint that
rejected such patterns if the pattern segment following the wildcard one
was not a literal:
* `/**/{name}` was rejected
* `/**/something/{name}` was accepted
The motivation here was to make the performance impact of wildard
patterns as small as possible at runtime.
This commit relaxes this constraint because `/**/*.js` patterns are very
popular in the security space for request matchers.
Closes gh-35686
This commit improves the reference document to better reflect the
different between `*` or `{name}` on one side, and `**` or `{*path}` on
the other.
The former patterns only consider a single path segment and its content,
while the latter variants consider zero or more path segments. This
explains why `/test/{*path}` can match `/test`.
Closes gh-35727
Prior to this commit, the `MappingMediaTypeFileExtensionResolver` would
resolve file extensions for a given media type by using a direct lookup
using the given media type provided by the request.
If the request contains a quality parameter like
"application/json;q=0.9", this would not resolve configured file
extensions for this media type.
While other media type parameters can be meaningful, the quality
parameter should not be used for lookups. This commit ensures that the
quality parameter is dropped before performing lookups.
Fixes gh-35754
Prior to this commit, the `HttpComponentsClientHttpRequestFactory` would
set the connection timeout on the request configuration. This has been
deprecated by the client itself and this value should be set while
creating the client on the connection manager itself.
This commit deprecates this method, as there is no way for the factory
to set this value anymore.
Closes gh-35748
Prior to this commit, `HttpMessageConverters` would consider the Kotlin
Serialization JSON converter as an alternative to the Jackson variant.
As seen in related issues, this converter is more commonly used for
annotated classes specifically and applications often rely on Jackson
acting as a fallback for types not supported by Kotlin Serialization.
This commit enables applications to configure such a converter on
`HttpMessageConverters` and order it ahead of of the JSON one.
Closes gh-35733
Prior to this commit, the `HttpMessageConverters` builder API had
methods like "jsonMessageConverter" for configuring a specific converter
for JSON support. This converter would be always configured at a given
position, even if default converters registration is not requested.
On the other hand, `customMessageConverter` would add any converter
ahead of the list, in all cases. This difference was not conveyed as it
should by the API.
This commit makes the following changes:
* builder methods are renamed to `withJsonConverter` and variants, to
better convey the fact that those are replacing the default converter
for a given format.
* `customMessageConverter` is renamed to `addCustomConverter` to better
reflect the additive aspect.
* the JavaDoc has been updated accordingly
* `withJsonConverter` and others are now only effective if the default
registration of auto-detected converters is requested. This better
aligns with the behavior in the reactive codecs configuration
Closes gh-35704
Prior to this commit, a regexp path segment ending with a double wilcard
(like "/path**") would be incorrectly parsed as a double wildcard
segment ("/**").
This commit fixes the incorrect parsing.
See gh-35679
Prior to this commit, the `PathPattern` and `PathPatternParser` would
allow multiple-segments matching and capturing with the following:
* "/files/**" (matching 0-N segments until the end)
* "/files/{*path}" (matching 0-N segments until the end and capturing
the value as the "path" variable)
This would be only allowed as the last path element in the pattern and
the parser would reject other combinations.
This commit expands the support and allows multiple segments matching at
the beginning of the path:
* "/**/index.html" (matching 0-N segments from the start)
* "/{*path}/index.html" (matching 0-N segments until the end and capturing
the value as the "path" variable)
This does come with additional restrictions:
1. "/files/**/file.txt" and "/files/{*path}/file.txt" are invalid,
as multiple segment matching is not allowed in the middle of the
pattern.
2. "/{*path}/files/**" is not allowed, as a single "{*path}" or "/**"
element is allowed in a pattern
3. "/{*path}/{folder}/file.txt" "/**/{folder:[a-z]+}/file.txt" are
invalid because only a literal pattern is allowed right after
multiple segments path elements.
Closes gh-35679
This commit improve the reference documentation in order to:
* highlight the deprecation status of `RestTemplate`
* improve the migration guide for `RestClient`, better explaining
possible behavior differences and a migration strategy.
Closes gh-35620
Prior to this commit, gh-35225 introduced HTTP response body
decompression support for "gzip" and "deflate" encodings for the
`JdkClientHttpRequestFactory`.
While body decompression works, the client keeps the "Content-Encoding"
and "Content-Length" response headers intact, which misleads further
response handling: the body size has changed and it is not compressed
anymore.
This commit ensures that the relevant response headers are removed from
the HTTP response after decompression.
Fixes gh-35668
Prior to this commit, Spring Framework would ship several abstract
`*View` implementations for rendering PDF, RSS or XLS documents using
well-known libraries. More recently, supporting libraries evolved a lot
with new versions and forks. Spring Framework is not in a position to
efficiently support all variants within the project.
This commit deprecates the relevant classes. Instead, libraries can
reuse existing code and ship optional support for Spring directly.
Often, updating imports and library usage is enough.
As an alternative, applications can decide to perform rendering
direclty in web handlers.
Closes gh-35451
As reported in gh-34651, `DataBuffer#getByte` can be inefficient for
some implementations, as bound checks are performed for each call.
This commit introduces a new `forEachByte` method that helps with
traversing operations without paying the bound check cost for each byte.
Closes gh-35623
Prior to this commit, configuring a custom `StringHttpMessageConverter`
would be overwritten when the `registerDefaults()` option is enabled.
Fixes gh-35563
This commit adds new `GsonEncoder` and `GsonDecoder` for serializing and
deserializing JSON in a reactive fashion.
Because `Gson` itslef does not support decoding JSON in a non-blocking
way, the `GsonDecoder` does not support decoding to `Flux<*>` types.
Closes gh-27131
Prior to this commit, the `IntrospectingClientHttpResponse` would try
and read the HTTP response stream in order to check for the presence of
a non-empty message body.
Developers reported that in some cases, an `EOFException` is thrown
instead of returning -1 from the `read()` method. This commit ensures
that this case is taken into account and that we report the response as
an empty body in these cases.
Closes gh-35361
Prior to this commit, the Micrometer context-propagation project would
help propagating information from `ThreadLocal`, Reactor `Context` and
other context objects. This is already well supported for Micrometer
Observations.
In the case of Kotlin suspending functions, the processing of tasks
would not necessarily update the `ThreadLocal` when the function is
scheduled on a different thread.
This commit introduces the `PropagationContextElement` operator that
connects the `ThreadLocal`, Reactor `Context` and Coroutine `Context`
for all libraries using the "context-propagation" project.
Applications must manually use this operator in suspending functions
like so:
```
suspend fun suspendingFunction() {
return withContext(PropagationContextElement(currentCoroutineContext())) {
logger.info("Suspending function with traceId")
}
}
```
Closes gh-35185
Prior to this commit, gh-32097 added native support for Jetty for both
client and server integrations. The `JettyDataBufferFactory` was
promoted as a first class citizen, extracted from a private class in the
client support. To accomodate with server-side requirements, an extra
`buffer.retain()` call was performed.
While this is useful for server-side support, this introduced a bug in
the data buffer factory, as wrapping an existing chunk means that this
chunk is already retained.
This commit fixes the buffer factory implementation and moved existing
tests from mocks to actual pooled buffer implementations from Jetty.
The extra `buffer.retain()` is now done from the server support, right
before wrapping the buffer.
Fixes gh-35319
As of gh-33616, Spring now supports metadata reading with the ClassFile
API on JDK 24+ runtimes. This commit fixes a bug where
`ArrayStoreException` were thrown when reading annotation attribute
values for arrays.
Fixes gh-35252
This commit updates the `HttpStatus` enum with the latest changes in
RFC9110:
* deprecate "413 Payload Too Large" in favor of "413 Content Too Large"
* deprecate "418 I'm a teapot" as it was meant as a joke and is now
marked as unused
* Introduce new "421 Misdirected Request"
* deprecate "422 Unprocessable Entity" in favor of
"422 Unprocessable Content"
* deprecate "509 Bandwidth Limit Exceeded" as it's now unassigned
* deprecate "510 Not Extended" as it's now marked as "historic"
The relevant exceptions, test matchers and more have been updated as a
result.
Closes gh-32870
This commit mames `StartupStep` extend `AutoCloseable` in order to allow
the try/with resources syntax and making the `step.end()` call
transparent.
Closes gh-35277
Undertow does not support Servlet 6.1, we need to remove compatibility
tests as well as Undertow-specific classes for WebSocket and reactive
support.
Closes gh-35354
Prior to this commit, a regexp path segment ending with a double wilcard
(like "/path**") would be incorrectly parsed as a double wildcard
segment ("/**").
This commit fixes the incorrect parsing.
Fixes gh-35339
Prior to this commit, the `JmsTemplate` would use `MessagePostProcessor`
for mutating JMS messages before they are being sent, but only if the
method takes a post processor as an argument.
The main use case so far is to mutate messages after they've been
created by a `MessageConverter` from a payload.
This commit updates the `JmsClient` to use `MessagePostProcessor` more
broadly, for all outgoing messages (converted or not). This brings an
interception-like mechanism for clients to enrich the message before
being sent.
This change also updates the `JmsClient` static factories and
introduces a Builder, allowing for more configuration options: multiple
message converters and message post processors.
Closes gh-35271
This commit ensures that the original request URI is displayed in
`NoResourceFoundException` error messages when logged. Without this
change, it can be confusing to see only the attempted resource path.
There are cases where the original request was not meant for resource
handling and we want to understand why this wasn't processed by another
handler.
The Problem Detail attribute has not been changed as the "instance"
attribute already displays the request path.
Closes gh-34553
Prior to this commit, the `PathPattern` and `PathPatternParser` would
allow multiple-segments matching and capturing with the following:
* "/files/**" (matching 0-N segments until the end)
* "/files/{*path}" (matching 0-N segments until the end and capturing
the value as the "path" variable)
This would be only allowed as the last path element in the pattern and
the parser would reject other combinations.
This commit expands the support and allows multiple segments matching at
the beginning of the path:
* "/**/index.html" (matching 0-N segments from the start)
* "/{*path}/index.html" (matching 0-N segments until the end and capturing
the value as the "path" variable)
This does come with additional restrictions:
1. "/files/**/file.txt" and "/files/{*path}/file.txt" are invalid,
as multiple segment matching is not allowed in the middle of the
pattern.
2. "/{*path}/files/**" is not allowed, as a single "{*path}" or "/**"
element is allowed in a pattern
3. "/{*path}/{folder}/file.txt" "/**/{folder:[a-z]+}/file.txt" are
invalid because only a literal pattern is allowed right after
multiple segments path elements.
Closes gh-35213
This commit replaces the Mockito agent configuration with a single
bytebuddy agent configuration that addresses both Mockito and mockk on
tests.
Closes gh-35207
As of #33894, `HttpMessageConverters` auto-detects converters and use
custom-provided ones to configure a collection of converters for the
client or the server.
Right now the multipart converter is only configured if core converters
(JSON, XML...) are configured/detected. We do not reuse the base
converters (resource, string, byte array) for the multipart converter
as it applies different encoding defaults (ISO for the main ones, UTF-8
for multipart).
This commit refines the configuration to not only include the multipart
converter when core converters are present, but also if any other
converter was configured.
Closes gh-35203
As of #33894, we introduced a new `HttpMessageConverters` API.
While this achieved our goal of focusing converters classpath detection
in a single place and avoiding waste, a single `HttpMessageConverters`
instance for both client and server added more complexity for developers.
This commit aligns the API here with the WebFlux `CodecsConfigurer` to
opt for a client/server flavor as the first step in the builder.
While this make the sharing of converter instances between server and
client impossible, this allows for a simpler API and separates concerns.
Closes gh-35187
This commit aligns `HttpMessageConverters` with the WebFlux codecs
configuration by adding custom converters first, before the
auto-detected and well-known ones.
This is a general approach in Spring Framework, where custom
implementations are more likely to handle specific uses cases and should
be involved before considering the more general implementations.
Fixes gh-35177
Prior to this commit, `WebMvcConfigurationSupport` would configure file
extensions/media types registrations based on classpath detection.
Since gh-33894, the detection of message converters is located in a
single place, `HttpMessageConverters`.
This commit updates the `WebMvcConfigurationSupport` to use the actual
message converters configured to decide which file extensions should be
set up for content negotiation.
See gh-33894