be-hase opened a new pull request, #1119:
URL: https://github.com/apache/tomcat/pull/1119
Follow-up to c639c7ef99 ("Allow maxLocaleCount to soft fail") and the
discussion in https://lists.apache.org/thread/6wtt1tks7y3c1lz76rpb0pcgn0om3dnc
## Problem
Now that extra locales are ignored rather than the request being rejected,
*which* locales are kept matters. Currently, `parseLocalesHeader()` stops
parsing after `maxLocaleCount + 1` entries and the sorting by quality only
happens afterwards, so the locales that are kept depend on the order of the
entries in the header rather than on their quality values.
For example, with `maxLocaleCount=2`:
```
Accept-Language: de;q=0.1, fr;q=0.2, it;q=0.3, ja;q=1.0
```
results in `[it, fr]`, so `getLocale()` returns `it` and the most preferred
language (`ja`) is silently dropped.
[RFC 9110, section
12.5.4](https://www.rfc-editor.org/rfc/rfc9110#section-12.5.4) says that the
order of the entries cannot be relied upon:
> Note that some recipients treat the order in which language tags are
listed as an indication of descending priority, particularly for tags that are
assigned equal quality values (no value is the same as q=1). However, this
behavior cannot be relied upon.
Listing entries in descending quality order is common practice among user
agents, but it is not required, so a well-behaved client can be affected.
## Change
The aim of the limit (not creating `Locale` objects for entries that can
never be used) is kept:
- `AcceptLanguage` creates its `Locale` lazily, on the first call to
`getLocale()`. The parsers only record the language tag and the quality value.
- `parseLocalesHeader()` parses the whole header and retains the
`maxLocaleCount + 1` entries with the highest quality values across all
`Accept-Language` headers. Entries with the same quality value keep header
order, as before. The `+ 1` is kept so that `parseLocales()` can still detect
that the limit was exceeded and log the existing message.
- A `Locale` is only created for the retained entries, so at most
`maxLocaleCount + 1` `Locale` objects are created per header. Tokenizing the
rest of the header is cheap and is already bounded by the maximum header size.
- The signature of the protected `parseLocalesHeader()` method is unchanged.
- The documentation for `maxLocaleCount` (HTTP and AJP connectors) now
describes which locales are retained.
## Tests
- `TestRequest`:
- the highest quality locales are retained regardless of header order
- entries with the same quality value keep header order
- selection across multiple `Accept-Language` headers
- a header with ~1000 entries in ascending quality order
- `TestAcceptLanguage`: the `Locale` is created lazily, and only once
--
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]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]