parseAcceptLanguage function
Parses header into language ranges ordered most-preferred first.
Returns an empty list for an empty/whitespace header. Malformed entries
(empty tag, unparseable or out-of-range q) are skipped rather than
failing the whole header, since a single bad client value should not deny
content negotiation.
Example:
parseAcceptLanguage('en-US,en;q=0.9,fr;q=0.8')
.map((r) => r.tag); // ('en-us', 'en', 'fr')
Audited: 2026-06-12 11:26 EDT
Implementation
List<LanguageRange> parseAcceptLanguage(String header) {
final List<LanguageRange> ranges = <LanguageRange>[];
if (header.trim().isEmpty) {
return ranges;
}
for (final String raw in header.split(',')) {
final LanguageRange? range = _parseEntry(raw);
// Drop unparseable entries and explicit q=0 (not acceptable).
if (range != null && range.quality > 0) {
ranges.add(range);
}
}
// Stable sort by quality descending: equal-weight tags keep header order,
// which is the documented tie-break clients rely on.
final List<int> order = List<int>.generate(ranges.length, (int i) => i);
order.sort((int i, int j) {
final int byQuality = ranges[j].quality.compareTo(ranges[i].quality);
return byQuality != 0 ? byQuality : i.compareTo(j);
});
return <LanguageRange>[for (final int i in order) ranges[i]];
}