codeconsole opened a new pull request, #16768: URL: https://github.com/apache/grails-core/pull/16768
Part of #15921. Review of #16759 split it: #16759 fixes the reported case on 7.0.x by registering the CAS single sign-out filter right after the encoding filter, and this PR moves the encoding filter itself, in the next minor. Once any filter reads a request parameter, the servlet container decodes the request body, and it uses ISO-8859-1 unless a character encoding has been set by then. Grails registers its encoding filter at order -180, so any filter ordered ahead of it that reads a parameter garbles every non-ASCII form field for the rest of the request: a controller receives `Café – ðŸ‚` for `Café – 🍂`. Spring Boot registers its own encoding filter at `Ordered.HIGHEST_PRECEDENCE` for this reason, and this PR does the same for Grails': `GrailsFilters.CHARACTER_ENCODING_FILTER` is now `Ordered.HIGHEST_PRECEDENCE`. Every filter ordered between `HIGHEST_PRECEDENCE + 1` and -181 now runs after the encoding filter instead of before it. [The measurements in #16759](https://github.com/apache/grails-core/pull/16759#issuecomment-6419783494) show what that changes, and the upgrade guide lists it: - In a packaged application, asset-pipeline copies the request's encoding to the precompiled assets it serves, so asset responses gain a charset, for example `text/css;charset=UTF-8`. That was measured on 7.0.17 with asset-pipeline 5.0.35, and `AssetPipelineFilter` in 5.2.2, the version 8.1.x uses, has the same code. Its development runtime sets no charset: in app1, with this change, `/assets/application.css` is `text/css` and `/assets/application.js` is `text/javascript`. - 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. - With `grails.filter.forceEncoding: true`, a response such a filter writes gets the forced encoding, and a request encoding such a filter sets is no longer overridden. #### CAS #16759 registers the single sign-out filter at `GrailsFilters.CHARACTER_ENCODING_FILTER.order + 1`, so once it merges up, the single sign-out filter follows the encoding filter to `HIGHEST_PRECEDENCE + 1`. Until then it stays at `HIGHEST_PRECEDENCE` on 8.1.x, the same order as the encoding filter, and still runs first, as it does today. #### Tests - app1: `CharacterEncodingSpec` posts a form, with no charset, through a filter at `HIGHEST_PRECEDENCE + 1` that reads one of its parameters, and checks that the filter and the controller both get the text as typed. It fails without the change (`Café – ðŸ‚`) and passes with it. - Also passing: the `grails-web-common` tests (342), app1's integration tests (712; `RedirectWithAndWithoutParamsFunctionalSpec` failed once in the full run and passed when run on its own, twice), Checkstyle on `grails-web-common`, and `rat`. #### Docs - The filter-ordering note in the plugin guide now says where the encoding filter sits. Its example moved to `HIGHEST_PRECEDENCE + 1`. - The 8.1 upgrade guide has a new section, "5. The Character Encoding Filter Runs First". For 9.0.x, #16760 drops Grails' encoding filter in favour of Spring Boot's, which also runs at `HIGHEST_PRECEDENCE`. If #16760 is in 9.0.x by the 8.1.x → 9.0.x merge, `GrailsFilters` conflicts there, because #16760 deprecates `CHARACTER_ENCODING_FILTER`. -- 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]
