Prior to this commit, the reconnection attempt count provided to the
reconnect strategy would not give the updated, incremented value but
instead the previous one.
This commit fixes this and ensures the value is incremented before it's
given to the strategy.
Fixes gh-37223
Prior to this commit, the `DefaultClientResponseBuilder` would assume
that an original client HTTP response, when mutated, would not be reused
nor read anymore. While this is the advised use case, there was some
inconsistency with the builder API here when mutating: some data like
the response status would copied, but the HTTP headers and cookies would
refer directly to the previous entries, making all changes visible to
the previous response instance.
This commit ensures that deep copies are performed when mutating a
client response with the builder API.
Fixes gh-37086
MIME type parameter names are case-insensitive, and MimeType already
stores them in a LinkedCaseInsensitiveMap. Several code paths, however,
still compared them with case-sensitive String.equals().
As a result, MimeType.hashCode() disagreed with MimeType.equals() for
parameter names that differ only in case, breaking the equals/hashCode
contract: text/plain;FOO=bar and text/plain;foo=bar are equal but hash
differently, so one is not found in a hash-based collection holding the
other. MimeType.compareTo() had the same blind spot for the charset
parameter.
MediaType was affected in two further ways: an out-of-range quality
value escaped validation when spelled Q=, and removeQualityValue() left
a Q= parameter in place.
Signed-off-by: Artyom Tsvirko <36863599+lArtiquel@users.noreply.github.com>
FlashMap.startExpirationPeriod(int) and MockMvcWebConnection's cookie
handling both multiplied an int number of seconds by 1000 without
widening to long. Above 2_147_483 seconds (about 24.9 days) the
multiplication overflows to a negative offset, so the computed
expiration time lands in the past.
For FlashMap, a flash map configured through
AbstractFlashMapManager.setFlashMapTimeout(int) with a large timeout is
then treated as expired immediately. For MockMvcWebConnection, a cookie
with a large max-age is removed from the CookieManager instead of being
stored.
This applies the same widening already used for this pattern in
gh-25613.
Closes gh-37208
Signed-off-by: kogun <akogun@gmail.com>
MIME type parameter names are case-insensitive, but MimeTypeParser
accumulates parameters in a case-sensitive LinkedHashMap. As a result,
duplicate parameters differing only in case (such as "charset" and
"CHARSET") were not rejected and were silently collapsed to the last
value by the case-insensitive parameter map of MimeType.
Accumulate parameters in a LinkedCaseInsensitiveMap so that duplicates
differing only in case map to the same key and are rejected consistently
with exact duplicates.
Signed-off-by: junhyeong9812 <pickjog@gmail.com>
Co-authored-by: Yash <190389954+yashsiwacha@users.noreply.github.com>
This commit picks up where 97067f9c9c left off by removing the four
trailing collection-clearing calls in clear(), which are now redundant
since the removal loop already empties contextMap, hierarchyMap,
contextUsageMap, and unusedContexts as an invariant. This commit also
adds regression tests in LruContextCacheTests for closing a context
hierarchy via clear() and reset(), asserting bottom-up close order with
Mockito.inOrder(), and confirming that getParentContextCount() and
getContextUsageCount() return to zero.
See gh-36825
This updates the TestContext Framework cache so that clearing the
cache also closes cached ConfigurableApplicationContext instances
instead of only dropping the internal references. The implementation
reuses the existing removal path, preserving the hierarchy-aware close
behavior already used by cache eviction/removal.
The ContextCache contract now documents the close behavior for
clear(), and LruContextCacheTests covers both clear() and reset(),
since reset() delegates to clear().
See gh-26196
Closes gh-36825
Signed-off-by: Will-thom <116388885+Will-thom@users.noreply.github.com>
Previously, canonicalPropertyName() located the end of a [key]
expression via a naive indexOf("]") search, while
AbstractNestablePropertyAccessor.getPropertyNameKeyEnd() -- used during
actual property resolution -- tracked bracket nesting depth. This meant
the two methods could disagree on the canonical form of a property
path whose map key itself contains bracket characters (e.g.,
map['key[0]']).
Similarly, getNestedPropertySeparatorIndex() tracked whether a dot
separator occurs inside a [key] expression using a simple boolean
toggle that flips on both '[' and ']', which produces an incorrect
result when a key contains an odd net count of inner bracket
characters.
To address those inconsistencies, this commit extracts the private
getPropertyNameKeyEnd() method from AbstractNestablePropertyAccessor to
a package-private static utility method in PropertyAccessorUtils, so
that canonicalPropertyName() can reuse the same depth-aware bracket
matching, and getNestedPropertySeparatorIndex() has been reworked to
track bracket nesting depth instead of toggling a boolean flag.
Closes gh-36999
Prior to this commit, the `DefaultApiVersionStrategy` reactive variant
would attempt to resolve the API version with the first resolver that
replies with a version. This contradicts the API that registers
resolvers in order.
This commit ensures that each resolver is called in order.
Signed-off-by: Gimin Kim <138752849+Gimini-3@users.noreply.github.com>
HtmlUnit 5 moved its Cookie type to org.htmlunit.http, so
Spring Test's HtmlUnit integration now uses the new API.
Constraint: Keep HtmlUnit and htmlunit3-driver versions compatible.
Rejected: Upgrade HtmlUnit alone | driver requires HtmlUnit 5.4.0.
Confidence: high
Scope-risk: narrow
Directive: Keep HtmlUnit and the driver version aligned.
Tested: JAVA_HOME=/opt/homebrew/opt/openjdk@25 ./gradlew build
Not-tested: None
Signed-off-by: jungh8n <jh981113@naver.com>
BodyState.flush() emits every queued buffer and only clears the queue
afterwards, so a cancellation arriving while it emits makes dispose()
release buffers whose ownership has already been transferred to the sink.
Such a buffer is then released twice: once by the parser, and once by the
downstream consumer or the discard hook. With Netty, body buffers are
slices of the inbound buffer, so the second release frees the inbound
buffer prematurely, which surfaces as
IllegalReferenceCountException: refCnt: 0, decrement: 1
io.netty.handler.codec.http.DefaultHttpContent.release
reactor.netty.channel.FluxReceive.drainReceiver
when reactor-netty releases its own share right after onNext.
Remove each buffer from the queue before emitting it, mirroring what
enqueue() already does, so that dispose() only ever releases buffers the
parser still owns.
Signed-off-by: Hyunsik Kang <cj848@hanmail.net>
When a multipart subscriber cancels while MultipartParser has already
emitted body tokens beyond the downstream demand, those tokens are held
in the Flux.create sink queue (and in downstream operator queues such
as windowUntil). On cancellation, Reactor discards the queued tokens,
but BodyToken is not a DataBuffer, so the buffers inside the discarded
tokens are never released and Netty reports "LEAK: ByteBuf.release()
was not called before it's garbage-collected".
Register a doOnDiscard hook for BodyToken in MultipartParser.parse() so
that a discarded body token releases its buffer, both in the sink queue
and in any downstream operator queue that supports discarding.
Closes gh-37115
Signed-off-by: Hyunsik Kang <cj848@hanmail.net>
This commit builds on the previous commit and ensures that
"must-understand" is only used with "no-store". This check is performed
at runtime as a staged interface/builder would be a major breaking
change for a behavior that is highlighted as "SHOULD" in the
specification.
This commit also performs similar runtime checks for:
* cache-public + cache-private
* cache-public + no-store
See gh-36918
This commits simplifies the Jetty buffer support by consolidating
the shared logic and delegating operations to the parent class
thanks to the new `JettyVirtualDataBuffer`.
Signed-off-by: Istvan Verhas <vi@mocker.guru>
Prior to this commit,
`MockHttpServletRequest.isRequestedSessionIdValid()` would return `true`
by default and could only be changed manually with a setter. This does
not align with the Servlet spec because of 1) its default value and 2)
it does not react to `changeSessionId()` calls.
This commit fixes that behavior while still allowing "manual" booleans
being set here.
Fixes gh-36631
Previously, PropertyEditorRegistrySupport.addStrippedPropertyPaths()
recursively enumerated every combination of stripped/retained [key]
segments in a property path, producing 2^n - 1 variants for a path
with n bracket pairs.
To address that, this commit limits the recursion at a depth of 8,
preserving existing behavior for realistic property paths while
bounding the work done for paths with an unusually large number of
bracket segments.
Closes gh-37020
Previously, createMap() invoked createIndexedValue() – and therefore
createObject() for non-simple value types – once per matching parameter
name rather than once per distinct map key, causing redundant nested
object construction for map entries whose value type has multiple
constructor parameters.
To address that, this commit aligns createMap() with createList() and
createArray() by skipping construction for keys that have already been
resolved.
Closes gh-37019