Commit Graph

2177 Commits

Author SHA1 Message Date
Brian Clozel
5efb385e64 Read Expires cookie attribute in HttpComponents connector
Prior to this commit, the HttpComponents implementation for the
`WebClient` would only consider the max-age attribute of response
cookies when parsing the response. This is not aligned with other client
implementations that consider the max-age attribute first, and then the
expires if the former was not present. The expires date is then
translated into a max-age duration. This behavior is done naturally by
several implementations.

This commit updates the `HttpComponentsClientHttpResponse` to do the
same.

Fixes gh-33157
2024-09-13 15:49:06 +02:00
Sébastien Deleuze
4b7292f431 Fix an off-by-one bug in ForwardedHeaderTransformer
Consistently with what is done in ForwardedHeaderFilter.

Closes gh-33465
2024-09-04 16:12:44 +02:00
Brian Clozel
debba6545b Listen to multiple async operations in ServerHttpObservationFilter
Prior to this commit, the `ServerHttpObservationFilter` was fixed to
re-enable instrumentation for async dispatches. This fix involves using
an AsyncListener to be notified of exchange completion.

This change was incomplete, as this would not work in some cases.
If another filter starts the async mode and initiates an ASYNC dispatch,
before async handling at the controller level, the async listener is not
registered against subsequent async starts.

This commit not only ensures that the async listener registers
against new async starts, but also ensure that the initial creation and
registration only happens during the initial REQUEST dispatch.

Fixes gh-33451
2024-08-30 20:09:21 +02:00
Brian Clozel
50be08480d Open observation scope in RestClient
Prior to this commit, the `RestClient` instrumentation would create and
close observations for HTTP requests, but would not open an observation
scope for the lifetime of the exchange.
This means that custom `ClientHttpRequestInterceptor` and
`ResponseErrorHandler` would not get access to the current observation
scope in case of tracing, possibly leading to missing trace ids in logs.

This commit ensures that an observation scope is managed for the
lifetime of the HTTP exchange.

Fixes gh-33397
2024-08-19 11:48:26 +02:00
rstoyanchev
bb17ad8314 Efficient ETag parsing 2024-08-14 07:19:59 +03:00
rstoyanchev
fe4fd00429 Polishing contribution
Closes gh-33374
2024-08-13 16:59:13 +03:00
Riley Park
1703b71563 Fix incorrect weak ETag assertion
See gh-33374
2024-08-13 16:31:14 +03:00
Stéphane Nicoll
76b2d13b2c Add support for changing context path in ServletRequestPath
This commit implements modifyContextPath in ServletRequestPath and
apply the same logic of concatenating the servlet path with the
context path.

Closes gh-33251
2024-08-07 16:28:17 +02:00
Stéphane Nicoll
6e9a19212f Consistently check for Content-Length value
This commit makes sure to consistently check that the content length
is not set above 2GB. Previously it was only checked in
setContentLength.

Closes gh-33256
2024-07-23 10:43:48 +02:00
Dawid Olbiński
83ff8e4e98 Support JAXBElement subtypes in Jaxb2XmlEncoder
Closes gh-33258
2024-07-23 09:19:11 +02:00
kevin.kep
2fe7ab1f92 Trim last allowed origin in comma-delimited list
See gh-33181
2024-07-15 15:17:03 +01:00
Stéphane Nicoll
69850cad27 Polish "Implement DefaultErrorResponseBuilder#headers(Consumer)"
See gh-33156
2024-07-08 13:11:31 +02:00
Sam Brannen
89338c91a9 Stop using using legacy locale data for Date/Time formatting tests
Commit 84714fbae9 introduced usage of the
-Djava.locale.providers=COMPAT command-line argument for javac in order
to allow our JDK 20 builds to pass by using legacy locale data.

That was done to ensure that Date/Time formats using AM/PM produced a
standard space (" ") before the "AM" or "PM" instead of a narrow
non-breaking space (NNBSP "\u202F"), which was introduced in Java 20
due to adoption of Unicode Common Locale Data Repository (CLDR-14032).

This commit removes usage of the -Djava.locale.providers=COMPAT
command-line argument and updates all affected tests to:

- Use an NNBSP before "AM" or "PM" in input text when running on Java 20
  or higher.

- Leniently match against any Unicode space character in formatted
  values containing "AM" or "PM".

See https://jdk.java.net/20/release-notes#JDK-8284840
See https://unicode-org.atlassian.net/browse/CLDR-14032
See gh-30185
Closes gh-33144
2024-07-04 17:03:15 +02:00
Brian Clozel
ab236c7741 Re-enable async dispatches in Observation Filter
Prior to this commit, the fix for gh-32730 disabled the involvment of
the osbervation filter for async dispatches. Instead of relying on ASYNC
dispatches to close the observation for async requests, this is now
using an async listener instead: async dispatches are not guaranteed to
happen once the async request is handled.

This change caused another side-effect: because async dispatches are not
considered anymore by this filter, the observation scope is not
reinstated for async dispatches. For example, `ResponseBodyAdvice`
implementations do not have the observation scope opened during their
execution.

This commit re-enables async dispatches for this filter, but ensures
that observations are not closed during such dispatches as this will be
done by the async listener.

Fixes gh-33091
2024-07-01 11:42:48 +02:00
Juergen Hoeller
fea237c065 Lazily start and retain HttpClient once resource factory is running
Closes gh-33093
2024-06-27 12:03:10 +02:00
Brian Clozel
f7307c9e07 Avoid recording RestClient observations twice
Prior to this commit, the fix for gh-32575 introduced cases where the
client observation would be stopped twice.

This commit ensures that `RestClient` observations are stopped only once
when the response is closed, or before throwing an unhanlded exception.

Fixes gh-33068
2024-06-19 12:46:21 +02:00
Arjen Poutsma
c38e9896c7 Remove use of ServletException in ModelFactory
This commit changes the use of HttpSessionRequiredException in
ModelFactory::initModel to an IllegalStateException, because the former
extends ServletException and cannot be used in WebFlux.

Closes gh-33043
2024-06-17 14:19:19 +02:00
Brian Clozel
0ca393c0dc Restrict memory allocation in ContentCachingRequestWrapper
Prior to this commit, the `ContentCachingRequestWrapper` could allocate
a `FastByteArrayOutputStream` block that was larger than the content
cache limit given as a consturctor argument. This was due to an
optimization applied in gh-31834 for allocating the right content cache
size when the request size is known.

Fixes gh-32987
2024-06-10 09:46:01 +02:00
Brian Clozel
6681394886 Stop observations for async requests in Servlet filter
Prior to this commit, the `ServerHttpObservationFilter` would support
async dispatches and would do the following:

1. start the observation
2. call the filter chain
3. if async has started, do nothing
4. if not in async mode, stop the observation

This behavior would effectively rely on Async implementations to
complete and dispatch the request back to the container for an async
dispatch. This is what Spring web frameworks do and guarantee.

Some implementations complete the async request but do not dispatch
back; as a result, observations could leak as they are never stopped.

This commit changes the support of async requests. The filter now
opts-out of async dispatches - the filter will not be called for those
anymore. Instead, if the application started async mode during the
initial container dispatch, the filter will register an AsyncListener to
be notified of the outcome of the async handling.

Fixes gh-32730
2024-06-07 19:01:57 +02:00
Thomas Deblock
47a5ebfde6 Support canEncode() for JAXBElement in Jaxb2XmlEncoder
Commit d7970e4ab8 introduced support for JAXBElement in
Jaxb2XmlEncoder's encodeValue() method; however, canEncode() still
returned false for a JAXBElement element type.

This commit revises canEncode() so that it returns true for an element
type that is assignable from JAXBElement.

See gh-30552
See gh-32972
Closes gh-32977
2024-06-07 14:13:59 +02:00
Juergen Hoeller
c0bef2c693 Lazily start resources on demand (if necessary outside of lifecycle)
See gh-32945
2024-06-06 08:54:32 +02:00
Brian Clozel
404c4d9d92 Support @Valid on container elements for handler arguments
Prior to this commit, #31870 added support for constraint annotations on
container elements for handler method argument validation. Supporting
this use case:

```
public void addNames(List<@NotEmpty String> names)
```

This commit does the same for `@Valid` annotation:

```
public void addPeople(List<@Valid Person> people)
```

Fixes gh-32964
2024-06-05 20:02:46 +02:00
Juergen Hoeller
7785f94c4c Revise and align Reactor client lifecycle management
Closes gh-32945
2024-06-05 16:32:40 +02:00
Juergen Hoeller
524da905db Consistently throw IOException from ReactorNettyClientRequest
This commit renames ReactorNettyClientRequestFactoryTests.

Closes gh-32952
2024-06-04 22:59:29 +02:00
Juergen Hoeller
4323c60513 Common context lifecycle management for ReactorResourceFactory
This commit moves ReactorResourceFactoryTests to same package.

Closes gh-32945
2024-06-04 22:59:18 +02:00
Sam Brannen
8feb842df5 Upgrade to AssertJ 3.26.0
See https://github.com/assertj/assertj/issues/3322
2024-05-27 16:43:22 +02:00
Brian Clozel
47c5cd208c Add missing "Content-Length: 0" header with HttpComponents
Prior to this commit, HTTP requests sent with the
`HttpComponentsClientHttpRequestFactory` would not set a
"Content-Length" header for empty request bodies. Setting a request
entity is the expected behavior for unsafe HTTP methods, and this would
align the behavior with other HTTP clients.
Developers would often rely on `BufferingClientHttpRequestFactory` to
set this information on the request.

This commit ensures that a `NullEntity` is used for unsafe HTTP methods,
when no body has been set for the request. This result in a
"Content-Length:0" request header.

Fixes gh-32678
2024-05-02 15:42:35 +02:00
Stéphane Nicoll
f90bdbef42 Add noop implementation for ResponseErrorHandler
Closes gh-32750
2024-05-02 11:44:42 +02:00
Brian Clozel
64b0283042 Revert "Do not set 0 Content-Length header in BufferingClientHttpRequestFactory"
This reverts commit b3a45670f9.

See gh-32650
2024-05-02 09:11:54 +02:00
Johnny Lim
cc73ccefef Polish
See gh-32696
2024-04-23 15:31:48 +02:00
Brian Clozel
5aa576f5c6 Register status handler exceptions in observations
Prior to this commit, `RestClientException` thrown by status handlers
would not be registered as observation errors. This commit ensures that
such exceptions are first caught, registered in the observation and
rethrown as expected.

Closes gh-32575
2024-04-20 19:44:11 +02:00
Brian Clozel
da4547a27e Extend observations to RestClient ResponseSpec
Prior to this commit, the `RestClient` observations would be stopped as
soon as the exchange function was called. This means that all errors
related to response decoding or mapping would not be recorded by the
obsevations.

This commit extends the observation recording to the `ResponseSpec` DSL
calls as well as custom exchange functions.

Fixes gh-32575
2024-04-18 21:26:18 +02:00
Brian Clozel
b3a45670f9 Do not set 0 Content-Length header in BufferingClientHttpRequestFactory
Prior to this commit, the `BufferingClientHttpRequestFactory`, through
the `AbstractBufferingClientHttpRequest`, would set a "Content-Length"
header value, even if the buffered body was empty.

This behavior is invalid since no request body would be set by the
client code in the first place.

This commit ensures that this header is only set if a request body has
been buffered and is about to be written to the request.

Fixes gh-32650
2024-04-17 22:44:36 +02:00
Juergen Hoeller
39cd31613b Polishing 2024-04-10 18:06:32 +02:00
Brian Clozel
019ce4418c BufferingClientHttpRequestWrapper should not write empty body
Prior to this commit, `BufferingClientHttpRequestWrapper` would always
write to the actual client request body, even if the buffered content
was empty (empty byte array).
This would cause issues with specific client request factories,
especially the OkHttp variant, that would consider empty byte arrays as
non-empty body and would reject such cases for GET requests with an
"IllegalArgumentException: method GET must not have a request body".

This commit only writes to the request if the buffered content is not
empty.

Fixes gh-32612
2024-04-10 16:41:16 +02:00
rstoyanchev
8d05028c2e RequestParam resolver supports empty array suffix
Closes gh-32577
2024-04-09 18:24:57 +01:00
rstoyanchev
4a68c44a27 Update content-length when reconstructing body
Closes gh-32471
2024-04-09 18:24:57 +01:00
Juergen Hoeller
07472758ee Detect Undertow RequestTooBigException message in handleParseFailure
Closes gh-32549
2024-04-05 18:03:44 +02:00
Sam Brannen
ef02f0bad8 Wrap InvalidMimeTypeException in HttpMediaTypeNotAcceptableException
The fix for #31254 resulted in an InvalidMimeTypeException being thrown
by MimeTypeUtils.sortBySpecificity() instead of an
IllegalArgumentException. However, InvalidMimeTypeException extends
IllegalArgumentException. Consequently, the change from
IllegalArgumentException to InvalidMimeTypeException did not result in
the desired effect in HeaderContentNegotiationStrategy.

HeaderContentNegotiationStrategy.resolveMediaTypes() still allows the
InvalidMimeTypeException to propagate as-is without wrapping it in an
HttpMediaTypeNotAcceptableException.

To address this issue, this commit catches InvalidMediaTypeException
and InvalidMimeTypeException in HeaderContentNegotiationStrategy and
wraps the exception in an HttpMediaTypeNotAcceptableException.

See gh-31254
See gh-31769
Closes gh-32483
2024-03-19 15:51:27 +01:00
Sam Brannen
836a0b3a40 Polishing 2024-03-19 14:19:01 +01:00
Juergen Hoeller
54a6d89da7 Additional unit tests for operations on empty UriTemplate
See gh-32432
2024-03-13 18:06:17 +01:00
Stéphane Nicoll
a34ceb405c Polish "Allow UriTemplate to be built with an empty template"
See gh-32432
2024-03-13 17:21:46 +01:00
Kasper Bisgaard
1b25a1506a Allow UriTemplate to be built with an empty template
See gh-32432
2024-03-13 17:20:08 +01:00
Maksim Sasnouski
abdccffa39 Fix Javadoc
This commit fixes various Javadoc issues across the code base.

See gh-32403
2024-03-09 16:02:00 +01:00
rstoyanchev
ef0717935b Test wrapping of response for async request
The following adjustments are also made as a result:
- Use int to check if lock is held and unlock is needed, given that
for non-async requests we don't need to obtain a lock.
- Protect access methods getOutputStream and getWriter with the
same locking and state checks.

Closes gh-32340
2024-03-05 11:42:03 +00:00
rstoyanchev
822e2447a0 Polishing StandardServletAsyncWebRequestTests
See gh-32340
2024-03-05 11:42:03 +00:00
Sébastien Deleuze
7493ce86b6 Fix ServletResponseHttpHeaders#get null handling
ServletResponseHttpHeaders#get should be annotated with `@Nullable` and
return null instead of a singleton list containing null when there is no
content type header.

Closes gh-32362
2024-03-04 14:43:09 +01:00
rstoyanchev
379ffac508 Add state and response wrapping to StandardServletAsyncWebRequest
The wrapped response prevents use after AsyncListener onError or completion
to ensure compliance with Servlet Spec 2.3.3.4.

The wrapped response is applied in RequestMappingHandlerAdapter.

The wrapped response raises AsyncRequestNotUsableException that is now
handled in DefaultHandlerExceptionResolver.

See gh-32340
2024-03-03 20:44:36 +00:00
Arjen Poutsma
33705516ff Polishing external contribution
See gh-32318
2024-02-29 15:51:29 +01:00
Patrick Strawderman
beb415dfa3 Optimize HttpHeaders.getAcceptLanguageAsLocales
The HttpHeaders.getAcceptLanguageAsLocales was incurring overhead from
using a Stream, as well as calling the fairly expensive
Locale.getDisplayName method.

Switch to using an ArrayList, and skipping over wildcard ranges to avoid
needing to check the display name.

Closes gh-32318
2024-02-29 15:36:55 +01:00