diff --git a/i18n.go b/i18n.go index a9b5974..2ee77c1 100644 --- a/i18n.go +++ b/i18n.go @@ -64,7 +64,7 @@ func WithI18n(cfg ...I18nConfig) Option { } // i18nMiddleware returns Gin middleware that parses Accept-Language, matches -// it against supported locales, and stores the result in the context. +// it against supported locales, and stores the resolved BCP 47 tag in the context. func i18nMiddleware(matcher language.Matcher, cfg I18nConfig) gin.HandlerFunc { return func(c *gin.Context) { accept := c.GetHeader("Accept-Language") @@ -75,8 +75,7 @@ func i18nMiddleware(matcher language.Matcher, cfg I18nConfig) gin.HandlerFunc { } else { tags, _, _ := language.ParseAcceptLanguage(accept) tag, _, _ := matcher.Match(tags...) - base, _ := tag.Base() - locale = base.String() + locale = tag.String() } c.Set(i18nContextKey, locale) diff --git a/i18n_test.go b/i18n_test.go index 66189e7..32ab926 100644 --- a/i18n_test.go +++ b/i18n_test.go @@ -133,6 +133,33 @@ func TestWithI18n_Good_QualityWeighting(t *testing.T) { } } +func TestWithI18n_Good_PreservesMatchedLocaleTag(t *testing.T) { + gin.SetMode(gin.TestMode) + e, _ := api.New(api.WithI18n(api.I18nConfig{ + DefaultLocale: "en", + Supported: []string{"en", "fr", "fr-CA"}, + })) + e.Register(&i18nTestGroup{}) + + h := e.Handler() + w := httptest.NewRecorder() + req, _ := http.NewRequest(http.MethodGet, "/i18n/locale", nil) + req.Header.Set("Accept-Language", "fr-CA, fr;q=0.8") + h.ServeHTTP(w, req) + + if w.Code != http.StatusOK { + t.Fatalf("expected 200, got %d", w.Code) + } + + var resp i18nLocaleResponse + if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { + t.Fatalf("unmarshal error: %v", err) + } + if resp.Data["locale"] != "fr-CA" { + t.Fatalf("expected locale=%q, got %q", "fr-CA", resp.Data["locale"]) + } +} + func TestWithI18n_Good_CombinesWithOtherMiddleware(t *testing.T) { gin.SetMode(gin.TestMode) e, _ := api.New(