fix: respect Accept-Language quality factors in language detection (#1380)

The Accept-Language header parsing was not correctly handling quality
factors. When a browser sends "en-GB,de-DE;q=0.5", the expected behavior
is to prefer English (q=1.0 by default) over German (q=0.5).

The fix uses golang.org/x/text/language.ParseAcceptLanguage to properly
parse and sort language preferences by quality factor. It also adds base
language fallbacks (e.g., "en" for "en-GB") to ensure regional variants
match their parent languages when no exact match exists.

Fixes #1022

Signed-off-by: majiayu000 <1835304752@qq.com>
This commit is contained in:
lif 2026-01-02 21:01:43 +08:00 committed by GitHub
parent cee7871ef8
commit 71147b4857
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 60 additions and 1 deletions

View file

@ -3,6 +3,7 @@ package localization
import (
"encoding/json"
"fmt"
"net/http/httptest"
"sort"
"testing"
@ -138,3 +139,40 @@ func TestComprehensiveTranslations(t *testing.T) {
})
}
}
func TestAcceptLanguageQualityFactors(t *testing.T) {
service := NewLocalizationService()
testCases := []struct {
name string
acceptLanguage string
expectedLang string
}{
{"simple_en", "en", "en"},
{"simple_de", "de", "de"},
{"en_GB_with_lower_priority_de", "en-GB,de-DE;q=0.5", "en"},
{"en_GB_only", "en-GB", "en"},
{"de_with_lower_priority_en", "de,en;q=0.5", "de"},
{"de_DE_with_lower_priority_en", "de-DE,en;q=0.5", "de"},
{"fr_with_lower_priority_de", "fr,de;q=0.5", "fr"},
{"zh_CN_regional", "zh-CN", "zh-CN"},
{"zh_TW_regional", "zh-TW", "zh-TW"},
{"pt_BR_regional", "pt-BR", "pt-BR"},
{"complex_header", "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7,de;q=0.5", "fr"},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
req := httptest.NewRequest("GET", "/", nil)
req.Header.Set("Accept-Language", tc.acceptLanguage)
localizer := service.GetLocalizerFromRequest(req)
sl := &SimpleLocalizer{Localizer: localizer}
gotLang := sl.GetLang()
if gotLang != tc.expectedLang {
t.Errorf("Accept-Language %q: expected %s, got %s", tc.acceptLanguage, tc.expectedLang, gotLang)
}
})
}
}