matrei commented on code in PR #16760:
URL: https://github.com/apache/grails-core/pull/16760#discussion_r4401993840
##########
grails-doc/src/en/guide/upgrading/upgrading90x.adoc:
##########
@@ -1229,3 +1229,15 @@ See <<asyncPromises,Promises>> and <<events,Events>>.
`grails-async-rxjava3` carries a `null` value as the RxJava 1 factory and
every other promise factory do: `createPromise()` and `createPromise(Class)`
give a promise whose `get()` returns `null`, a task that returns `null`
resolves to `null`, and a `null` value keeps its place in the list that
`onComplete`, `onError` and `waitAll` deliver.
`grails-async-rxjava2` does not: there `createPromise()` and `onComplete` over
a list holding a bound promise of `null` fail with a `NullPointerException`,
and a task that returns `null` resolves to the `java.lang.Void` class.
+
+==== 20. Spring Boot Registers the Character Encoding Filter
+
+Grails no longer registers a character encoding filter of its own. It used to,
and Spring Boot's backed off, so `spring.servlet.encoding` had no effect in a
Grails application. Spring Boot's filter now decodes requests: it runs at
`Ordered.HIGHEST_PRECEDENCE`, ahead of every other filter, and
`spring.servlet.encoding` configures it.
+
+* The request encoding is now overridden by default, as in any Spring Boot
application, so a request that declares a charset of its own is still decoded
as UTF-8: its parameters, a body read through `getReader()`, `request.JSON` and
`request.XML`, and a JSON or XML body bound to a command object or domain
class. The parameters of a PUT, PATCH or DELETE form are the exception, as in
Grails 8: the `FormContentFilter` that parses them decodes them with the
declared charset, forced or not. To keep the charset a request declares, as
Grails 8 did, set `spring.servlet.encoding.force-request: false`.
+* Filters ordered between `Ordered.HIGHEST_PRECEDENCE + 1` and -181, which
used to run before Grails' encoding filter, now run after Spring Boot's, with
the request encoding set. asset-pipeline's filter at -190 is one: in a packaged
application (a WAR or an executable jar) it copies the request's encoding to
the precompiled assets it serves, so every asset response now declares a
charset, for example `text/css;charset=UTF-8`, and browsers use it for
stylesheets and scripts instead of detecting their encoding. A filter among
them that reads a request body sent without a charset through `getReader()` now
decodes it as UTF-8 instead of ISO-8859-1.
+* `grails.filter.encoding` and `grails.filter.forceEncoding` are deprecated.
Grails 9 translates them into `spring.servlet.encoding.charset` and
`spring.servlet.encoding.force` and logs a warning, and a
`spring.servlet.encoding` setting of the application wins over them. Use the
Spring Boot properties instead.
+* `GrailsFilters.CHARACTER_ENCODING_FILTER` is deprecated, and its order is
now `Ordered.HIGHEST_PRECEDENCE`, the order of Spring Boot's encoding filter,
where Grails 8.0 had -180. A filter ordered at
`GrailsFilters.CHARACTER_ENCODING_FILTER.order + 1` therefore runs right after
the encoding filter. Order it at `Ordered.HIGHEST_PRECEDENCE + 1` instead.
Review Comment:
I asked for this order last round, and I only looked at what it means for
the encoding filter. A filter at `CHARACTER_ENCODING_FILTER.order + 1` moves
from -179 to `HIGHEST_PRECEDENCE + 1`. That puts it ahead of
`FormContentFilter` (-9900) and Grails' security headers filter at
`GrailsFilters.FIRST` (-200) as well. It no longer sees the parameters of a
PUT, PATCH or DELETE form. A response it sends without continuing the chain no
longer gets the security headers. Moving to `Ordered.HIGHEST_PRECEDENCE + 1`,
as the bullet advises, leaves it there. Perhaps:
> A filter ordered at `GrailsFilters.CHARACTER_ENCODING_FILTER.order + 1`
therefore runs right after the encoding filter, and now also ahead of
`FormContentFilter` and of Grails' security headers filter at
`GrailsFilters.FIRST`: it no longer sees the parameters of a PUT, PATCH or
DELETE form, and a response it sends without continuing the chain gets no
security headers. Order it at `Ordered.HIGHEST_PRECEDENCE + 1` instead, or at
`GrailsFilters.ASSET_PIPELINE_FILTER.order + 1` to keep the place it had in
Grails 8.0.
The skill's bullet (`SKILL.md:436`) needs the same change. The constant
moves on 8.1.x too, so #16768's upgrade notes have the same gap.
##########
grails-doc/src/en/guide/plugins/hookingIntoRuntimeConfiguration.adoc:
##########
@@ -384,11 +384,11 @@ However, if you want to control the order of filter
registrations you will need
myFilter(FilterRegistrationBean) {
filter = bean(MyFilter)
urlPatterns = ['/*']
- order = Ordered.HIGHEST_PRECEDENCE
+ order = Ordered.HIGHEST_PRECEDENCE + 1
}
----
-NOTE: Grails' internal registered filters (`GrailsWebRequestFilter`,
`HiddenHttpMethodFilter` etc.) are defined by incrementing `HIGHEST_PRECEDENCE`
by 10 thus allowing several filters to be inserted before or between Grails'
filters.
+NOTE: Spring Boot registers the character encoding filter at
`Ordered.HIGHEST_PRECEDENCE`, ahead of every other filter. Once any filter
reads a request parameter, the servlet container has decoded the request body,
so a filter that reads parameters needs a later order than the encoding filter,
or form input arrives decoded as ISO-8859-1. A filter registered at exactly
`Ordered.HIGHEST_PRECEDENCE` through a `FilterRegistrationBean` runs before it.
Grails' own filters (`HiddenHttpMethodFilter`, `GrailsWebRequestFilter` etc.)
have orders from -200 to -150, ten apart, and `GrailsFilters.LAST` is at -110,
ahead of the Spring Security filter chain at -100, which leaves room to insert
filters before or between them.
Review Comment:
Nit, about my own wording from last round: nothing is at -180, so the
filters from -200 to -150 aren't all ten apart. From -190 to -170 the gap is
20. "at least ten apart" would be accurate. #16768 has the same sentence.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]