Commit Graph
2509 Commits
Author SHA1 Message Date
Brian Clozel a5141b187a Fix '**' parsing within a PathPattern segment
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
2025-10-22 12:21:57 +02:00
Brian Clozel d3c1e678c2 Support wildcard path elements at the start of path patterns
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
2025-10-22 12:21:57 +02:00
Sam Brannen 2591cab561 Polishing 2025-10-13 15:12:21 +02:00
Sam Brannen 8456cd1e74 Polish contribution
See gh-35587
2025-10-13 15:12:21 +02:00
Igor Murzich 7699b4af9c Retain order of produces media types in @⁠ExceptionHandler
Closes gh-35587

Signed-off-by: Igor Murzich <imurzich@gmail.com>
2025-10-13 15:12:21 +02:00
rstoyanchev a19b51b7e0 Handle invalid position in ResourceHttpMessageWriter
Closes gh-35536
2025-10-01 14:44:05 +01:00
rstoyanchev e9fb5eb38a Respect forwarded path in UrlHandlerFilter
Closes gh-35509
2025-09-25 12:19:56 +01:00
rstoyanchev 5a858915ea Revise parsed path handling in UrlHandlerFilter
Closes gh-35538
2025-09-24 19:08:55 +01:00
Brian Clozel 0cc79ba366 Catch EOFException in IntrospectingClientHttpResponse
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
2025-09-19 17:49:12 +02:00
Sam Brannen 6d710d482a Find annotation on overridden method in type hierarchy with unresolved generics
Prior to this commit, the MergedAnnotations support (specifically
AnnotationsScanner) and AnnotatedMethod did not find annotations on
overridden methods in type hierarchies with unresolved generics.

The reason for this is that ResolvableType.resolve() returns null for
such an unresolved type, which prevents the search algorithms from
considering such methods as override candidates.

For example, given the following type hierarchy, the compiler does not
generate a method corresponding to processOneAndTwo(Long, String) for
GenericInterfaceImpl. Nonetheless, one would expect an invocation of
processOneAndTwo(Long, String) to be @⁠Transactional since it is
effectively an invocation of processOneAndTwo(Long, C) in
GenericAbstractSuperclass, which overrides/implements
processOneAndTwo(A, B) in GenericInterface, which is annotated with
@⁠Transactional.

However, the MergedAnnotations infrastructure currently does not
determine that processOneAndTwo(Long, C) is @⁠Transactional since it is
not able to determine that processOneAndTwo(Long, C) overrides
processOneAndTwo(A, B) because of the unresolved generic C.

interface GenericInterface<A, B> {

    @⁠Transactional
    void processOneAndTwo(A value1, B value2);
}

abstract class GenericAbstractSuperclass<C> implements GenericInterface<Long, C> {

    @⁠Override
    public void processOneAndTwo(Long value1, C value2) {
    }
}

static GenericInterfaceImpl extends GenericAbstractSuperclass<String> {
}

To address such issues, this commit changes the logic in
AnnotationsScanner.hasSameGenericTypeParameters() and
AnnotatedMethod.isOverrideFor() so that they use
ResolvableType.toClass() instead of ResolvableType.resolve(). The
former returns Object.class for an unresolved generic which in turn
allows the search algorithms to properly detect method overrides in
such type hierarchies.

Closes gh-35342
2025-08-19 12:28:12 +02:00
Sam Brannen f11a1e6f82 Polish tests 2025-08-11 11:27:10 +03:00
rstoyanchev ffc785471b Fix checkstyle error 2025-08-08 12:31:13 +01:00
rstoyanchev 600d6c6fc0 Update contribution
Closes gh-34721
2025-08-08 11:31:21 +01:00
giampaolo 7a55ce48a9 Handle CancellationException in JdkClientHttpRequest
Handle CancellationException in order to throw an HttpTimeoutException
when the timeout handler caused the cancellation.

See gh-34721

Signed-off-by: giampaolo <giampaorr@gmail.com>

fix: use timeoutHandler with a flag isTimeout

    Closes gh-33973

    Signed-off-by: giampaolo <giampaorr@gmail.com>
2025-08-08 11:31:21 +01:00
Patrick StrawdermanandSebastien Deleuze 24e66b63d1 Refine StringUtils#uriDecode and update documentation
Refine the StringUtils#uriDecode method in the following ways:
- Use a StringBuilder instead of ByteArrayOutputStream, and only decode
  %-encoded sequences.
- Use HexFormat.fromHexDigits to decode hex sequences.
- Decode to a byte array that is only allocated if encoded sequences are
  encountered.

This commit adds another optimization mainly for the use case where
there is no encoded sequence, and updates the Javadoc of both
StringUtils#uriDecode and UriUtils#decode to match the implementation.

Signed-off-by: Patrick Strawderman <pstrawderman@netflix.com>
Co-Authored-by: Sebastien Deleuze <sebastien.deleuze@broadcom.com>

Closes gh-35253
2025-07-29 21:44:26 +02:00
rstoyanchev f84552a97e Polishing contribution
Closes gh-35102
2025-06-25 12:37:42 +01:00
Daniil Razorenov 8d6117e419 Support StreamingHttpOutputMessage in RestClient
This commit allows RestClient to handle StreamingHttpOutputMessage
properly by checking the type of the request and invoking setBody()
when appropriate. This improves interoperability with components that
expect streamed output.

A new integration test has been added to verify the functionality.

See gh-35102

Signed-off-by: Daniil Razorenov <daniltmb@gmail.com>
2025-06-25 12:36:32 +01:00
Brian Clozel 45d887f973 Fix missing request body for GET and DELETE JdkClientHttpRequest
This commit fixes a regression introduced in gh-34971 where GET and
DELETE requests would not allow request bodies anymore for
`JdkClientHttpRequest`.
We are now using `builder.GET()` and `builder.DELETE()` methods only if
the provided body is null.

Fixes gh-35068
2025-06-17 17:19:21 +02:00
Spring Builds aee29b7f30 Update copyright headers in source files
This commit updates Java, Kotlin, and Groovy source files to use the
"<year>-present" pattern in copyright headers.

Closes gh-35070
2025-06-17 15:54:58 +02:00
Brian Clozel 696692f1ed Do not attempt to decode wildcard content-types as form-data
Prior to this commit, the `DefaultServerWebExchange` would attempt to
decode request bodies as form-data or multipart of the request
content-type was compatible with the expected media types.

If requests are sent with an invalid wildcard content-type such as "*/*"
or "multipart/*", we should not attempt to decode here.

Fixes gh-34660
2025-06-16 15:51:47 +02:00
Brian Clozel 8dee7d8fb6 Use concrete form-data type when reading request body
Prior to this commit, the WebFlux server support would try reading
form-data from the request by:

* first, checking that request content-type is compatible with a
  form-data content-type
* then by selecting a message reader that is compatible with the given
  request content-type

This approach is flawed because if the content-type provided by the
request is too broad, another message reader could be selected that's
not meant to be used for reading form-data. Typically, a JSON message
reader could be selected and would fail when reading the request.
This problem was previously hidden because message readers would not
support `MultiValueMap` as a target type. Now that some readers support
this type, this can lead to deserialization errors.

This commit now ensures that in all cases, we attempt to read form-data
with a message reader that supports the
"application/x-www-form-urlencoded" media type.

Fixes gh-34660
2025-06-13 16:45:46 +02:00
Brian Clozel f0e7b42704 Encode non-printable character in Content-Disposition parameter
Prior to this commit, the "filename" parameter value for the
"Content-Disposition" header would contain non-printable characters,
causing parsing issues for HTTP clients.
This commit ensures that all non-printable characters are encoded.

Fixes gh-35034
2025-06-12 08:39:29 +02:00
Sam Brannen 4d2cc4ae97 Polish contribution
See gh-35013
2025-06-10 11:45:20 +02:00
Mohammad Saeed Nouri c04902fefb Allow update of existing WebSession after max sessions limit is reached
Previously, when saving a WebSession, the system did not check whether
the session ID already existed. As a result, even if the session being
saved was an update to an existing one, it was incorrectly treated as a
new session, and a "maximum sessions exceeded" error was triggered.

This fix ensures that if a WebSession with the same ID already exists,
it will be updated rather than counted as a new session, thereby
preventing unnecessary session limit violations.

Closes gh-35013

Signed-off-by: Mohammad Saeed Nouri <msnsaeed71@gmail.com>
2025-06-10 11:44:59 +02:00
Sam Brannen 3c265e1044 Fix InMemoryWebSessionStoreTests.startsSessionImplicitly() test 2025-06-10 11:44:00 +02:00
Sam Brannen 222702f750 Polish WebSession support and tests 2025-06-10 11:43:56 +02:00
Sam Brannen 18d6a55e3e Polishing and removal of "this." for method invocations 2025-06-09 14:10:30 +02:00
Brian Clozel 4a46d957f3 Fix out of bounds exception for PathPattern#combine
Prior to this commit, combining the "/*" and  "/x/y" path patterns
would result in a `StringIndexOutOfBoundsException`.

This commit fixes this problem and revisits the implementation for
better consistency:

* "/*" + "/x/y" is now "/x/y"
* "/x/*.html" + "/y/file.*" is now rejected because they don't share the
  same prefix.

This change also adds the relevant Javadoc to the `PathPattern#combine`
method.

Fixes gh-34986
2025-06-04 20:18:33 +02:00
Tran Ngoc Nhan 3f0892b42c Fix typos
Closes gh-34876

Signed-off-by: Tran Ngoc Nhan <ngocnhan.tran1996@gmail.com>
2025-06-03 18:55:15 +01:00
Brian Clozel 659472f9e3 Use HTTP methods in JdkClientHttpRequest when possible
Prior to this commit, we would use the
`java.net.http.HttpRequest.Builder#method(String, BodyPublisher)` to
create HTTP requests for the JDK HttpClient. This method requires a
non-null body publisher; providing an empty publisher writes a
"Content-Length: 0" header to all requests.

As of Java 19, this behavior changes for `HttpRequest.Builder#GET` and
similar methods, where the body publisher is considered as null and no
"Content-Length" header is written.

This commit aligns with this behavior and favors dedicated HTTP methods
whenever available.`

Closes gh-34971
2025-06-02 15:36:20 +02:00
Brian Clozel 2af0323c21 Use Content-Type charset in JAXB message converters
Prior to this commit, the JAXB message converters would only rely on the
encoding declaration inside the XML document for reading the document.
This would then use the default UTF-8 encoding, even if the HTTP message
has the `"application/xml;charset=iso-8859-1"` Content-Type.

This commit ensures that both `Jaxb2CollectionHttpMessageConverter` and
`Jaxb2RootElementHttpMessageConverter` use the encoding declared in the
HTTP Content-Type, if present.

Fixes gh-34745
2025-05-19 16:57:57 +02:00
rstoyanchev c88ba6c90e Polishing contribution
Closes gh-34812
2025-04-28 14:23:30 +01:00
Yanming Zhou d7c13d6518 HttpEntity.EMPTY should be immutable
See gh-34812

Signed-off-by: Yanming Zhou <zhouyanming@gmail.com>
2025-04-28 14:22:59 +01:00
rstoyanchev c48ff357dc HTTP Service proxy sets body type
Closes gh-34793
2025-04-25 21:03:00 +01:00
rstoyanchev 858c2bd270 Polishing contribution
Closes gh-34783
2025-04-23 10:54:52 +01:00
whl 124582d910 Fix expansion of query param with same name
See gh-34783

Signed-off-by: whl <whlit.cola@gmail.com>
2025-04-23 10:54:52 +01:00
Sam Brannen 7095f4cb66 Use proper casing for parameter and variable names 2025-04-14 11:25:40 +02:00
Sébastien Deleuze 671d972454 Add RestClient.RequestHeadersSpec#exchangeForRequiredValue
This commit adds a variant to RestClient.RequestHeadersSpec#exchange
suitable for functions returning non-null values.

Closes gh-34692
2025-04-02 17:10:01 +02:00
Sébastien Deleuze 4db12806d1 Revert "Add a requiredExchange extension to RestClient"
This reverts commit dcb9383ba1.

See gh-34692
2025-04-02 17:10:01 +02:00
rstoyanchev 290c9c4a19 Use form charset in ServletServerHttpRequest
Closes gh-34675
2025-04-02 09:05:52 +01:00
rstoyanchev e01ad5a08d Polishing in ServletServerHttpRequest
See gh-34675
2025-04-02 09:05:52 +01:00
Sam Brannen 36d9357f94 Fix Kotlin compilation errors 2025-03-31 12:02:51 +02:00
Sébastien Deleuze dcb9383ba1 Add a requiredExchange extension to RestClient
Closes gh-34692
2025-03-31 11:55:41 +02:00
rstoyanchev 15c20c3e65 Fix regression with opaque URI determination
Before RfcUriParser we expected opaque URI's to not have ":/"
after the scheme while the new parser expect opaque URI's to
not have a slash anywhere after the scheme. This commit
restores the previous behavior.

Closes gh-34588
2025-03-21 09:05:41 +00:00
Sam Brannen 208d52d852 Introduce Checkstyle rule for separator symbol location 2025-03-19 15:35:44 +01:00
Dmitry Sulman 0c2ba4e38e Recursively box/unbox nested inline value classes
See gh-34592
Signed-off-by: Dmitry Sulman <dmitry.sulman@gmail.com>
2025-03-18 17:50:28 +01:00
Sam Brannen c6a9aa59a3 Remove BDDMockito Checkstyle rule
This commit removes the BDDMockito Checkstyle rule, since it did not
actually enforce the use of BDDMockito.

This commit also updates static imports to use Mockito instead of
BDDMockito where appropriate (automated via the Eclipse IDE Organize
Imports clean-up task).

Closes gh-34616
2025-03-18 16:35:57 +01:00
Russell Bolles 573e74b8bd Refine FormHttpMessageConverter exception handling
FormHttpMessageConverter could throw a more specific
HttpMessageNotReadableException instead of an IllegalArgumentException
when the http form data is invalid.

See gh-34594
Signed-off-by: Russell Bolles <rbolles@netflix.com>
2025-03-17 11:37:42 +01:00
rstoyanchev 9ab43b138a Enhancement in HandlerMethodValidationException
Add dedicated method to Visitor for constraints directly on a
RequestBody method parameter (rather than nested).

Closes gh-34549
2025-03-10 18:01:55 +00:00
rstoyanchev 09ae080b99 isDisconnectedClientException protected for null
Closes gh-34533
2025-03-10 17:19:13 +00:00