Before this commit UriComponents was capable of expanding URI vars that
may have contained a regular expressions (as supported with
@RequestMapping for example). However if the regular expressions
contained any nested "{}" the expand did not work correctly.
This commit sanitizes a URI template source removing any content
between nested "{}" prior to expanding. This works since we only care
about the URI variable name.
Issue: SPR-13311
Prior to this change, trying to set an unquoted ETag with
`ResponseEntity`'s API would throw an `IllegalArgumentException`.
This commit automatically quotes ETag values set using ResponseEntity.
Issue: SPR-13378
In an attempt to make our Jetty-based integration tests more robust,
this commit discontinues use of SocketUtils for picking a random,
available port and instead lets the Jetty Server pick its own port.
Before this commit RequestPartServletServerHttpRequest simply did an
instanceof check for MultipartHttpServletRequest. That hasn't failed
because request wrapping typically happens in filters before the
DispatcherServlet calls the MultipartResolver.
With Spring MVC Test and the Spring Security integraiton however,
this order is reversed since there we prepare the multipart request
upfront, i.e. there is no actual parsing.
The commit unwraps the request if necessary.
Issue: SPR-13317
This change ensures that an onError outcome from an async request is
also routed to onCompletion handlers registered with
StandardServletAsyncWebRequest.
Issue: SPR-13292
Prior to this change, calling the `setDateHeader` method on a
Spring Test MockHttpServletResponse instance would just store the given
long value in a Map, not writing it as a formatted date String.
Also, calling `getDateHeader` on a MockHttpServletRequest would not
support date strings and could not parse those values.
This can be problematic when testing features related to date headers
such as "Expires", "If-Modified-Since", "Last-Modified", etc.
This commit adds formatting and parsing capabilities to Servlet Mocks
for date strings in HTTP headers.
When formatting dates to Strings, the date format used is the one
preferred by the HTTP RFC. When parsing date Strings, multiple date
formats are supported for better compatibility.
Issue: SPR-11912
Prior to this change, calling the `setDateHeader` method on a
MockHttpServletResponse instance (internal implementation for testing
the spring-web module) would just store the given long value in a Map,
not writing it as a formatted date String.
This can be problematic when testing features related to date headers
such as "Expires", "If-Modified-Since", "Last-Modified", etc.
This commit formats long dates into date Strings using the date format
recommended by the RFC and the GMT time zone.
When using an Apache Http components based infrastructure, a null header
value is handled as the empty string. The exact same infrastructure using
HttpURLConnection generates a header with no colon. This is actually not
proper HTTP and some components fail to read such request.
We now make sure to call HttpURLConnection#addRequestProperty with the
empty String for a null header value.
Issue: SPR-13225
Browsers like Chrome or Safari include an Origin header for same-origin
POST/PUT/DELETE requests, not only for cross-origin requests.
Before this commit, these same-origin requests would have been detected
as potential cross-origin requests, and rejected if the same-origin domain
is not part of the configured allowedOrigins.
This commit avoid to reject same-origin requests by reusing the logic
introduced in Spring 4.1 for detecting reliably Websocket/SockJS
same-origin requests with the WebUtils.isValidOrigin() method. This
logic has been extracted in a new WebUtils.isSameOrigin() method.
Issue: SPR-13206
This commit introduces the following changes:
- The new CorsConfigurationMapping class allows to share the mapped
CorsConfiguration logic between AbstractHandlerMapping and CorsFilter
- In AbstractHandlerMapping, the Map<String, CorsConfiguration>
corsConfiguration property has been renamed to corsConfigurations
- CorsFilter allows to process CORS requests at filter level, using any
CorsConfigurationSource implementation (for example
CorsConfigurationMapping)
Issue: SPR-13192
When using Appache Commons FileUpload, multi parts with binary data
(i.e. that are not actual files) are saved and then accessed as
String request parameters.
Before this change however the RequestPartServletServerHttpRequest
used a fixed encoding (UTF-8) while the parsing code in
CommonsFileUploadSupport/Resolver used the encoding from the
content-type header, or the request, or the FileUpload component.
This change does a best effort to determine the encoding of the
request parameter using a similar algorithm as the parsing side
that should work the same unless the encoding comes from the
FileUpload component which is not accessible.
Issue: SPR-13096
This split avoids a package tangle (between core and core.annotation) and also allows for selective use of raw annotation exposure versus synthesized annotations, with the latter primarily applicable to web and message handler processing at this point.
Issue: SPR-13153
Prior to this commit, `HttpEntityMethodProcessor` would rely on
`ServletWebRequest` to process conditional requests and with incoming
`"If-Modified-Since"` / `"If-None-Match"` request headers.
This approach is problematic since in that class:
* response is wrapped in a `ServletServerHttpResponse`
* this wrapped response does not write response headers right away
* `ServletWebRequest.checkNotModified` methods can't apply their
logic with incomplete response headers
This solution adds some minimal code duplication and applies
the conditional request logic within the Processor.
A possible alternative would be to improve the
`ServletServerHttpResponse$ServletResponseHttpHeaders` implementation
with write methods - but this solution would only work for Servlet 3.x
applications.
Issue: SPR-13090
Prior to this commit, Spring's MimeType checked for equality between
two MIME types based on the equality of their properties maps; however,
the properties maps contain string representations of the "charset"
values. Thus, "UTF-8" is never equal to "utf-8" which breaks the
contract for character set names which must be compared in a
case-insensitive manner.
This commit addresses this issue by ensuring that "charset" properties
in MimeType instances are compared as Java Charset instances, thereby
ignoring case when checking for equality between charset names.
Issue: SPR-13157
This commit adds canWrite() and write() methods to the
GenericHttpMessageConverter interface. These are type aware variants
of the methods available in HttpMessageConverter, in order to keep
parametrized type information when serializing objects.
AbstractMessageConverterMethodProcessor now calls those type aware
methods when the message converter implements GenericHttpMessageConverter.
AbstractJackson2HttpMessageConverter and GsonHttpMessageConverter uses
these new methods to make @ResponseBody method return type available
for type resolution instead of just letting the JSON serializer trying
to guess the type to use from the object to serialize.
Issue: SPR-12811
- Simplified "check" algorithms in CorsConfiguration
- Improved robustness of setter methods in CorsConfiguration in order to
avoid attempts to modify immutable lists
- Improved CORS documentation and fixed typo
- Introduced constants in CorsConfiguration
- Removed auto-boxing in CorsRegistration
Before this change HandlerMethodReturnValueHandler's were invoked in a
specific order (type-based, annotation-based, custom). However handlers
that deal with asynchronous return value handling need to always be
considered first. This affects custom handlers in particular since they
are normally ordered last.
This change introduces an AsyncHandlerMethodReturnValueHandler
sub-interface with a single method to determine if the return value is
asynchronous and if it is to look for a matching handler only among
those that are of type AsyncHandlerMethodReturnValueHandler.
Issue: SPR-13083