72 lines
2.0 KiB
Go
72 lines
2.0 KiB
Go
package server
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
const webLocaleCookieName = "verstak_locale"
|
|
|
|
func isSupportedWebLocale(locale string) bool {
|
|
return locale == "en" || locale == "ru"
|
|
}
|
|
|
|
// resolveWebLocale has a deliberately small, documented locale model. The
|
|
// cookie is a user preference; "system" delegates to Accept-Language, then
|
|
// the configured server default, and finally English.
|
|
func resolveWebLocale(r *http.Request, cfg *Config) string {
|
|
configured := "en"
|
|
if cfg != nil && isSupportedWebLocale(cfg.Web.DefaultLocale) {
|
|
configured = cfg.Web.DefaultLocale
|
|
}
|
|
if cookie, err := r.Cookie(webLocaleCookieName); err == nil {
|
|
switch cookie.Value {
|
|
case "ru", "en":
|
|
return cookie.Value
|
|
case "system":
|
|
if locale := localeFromAcceptLanguage(r.Header.Get("Accept-Language")); locale != "" {
|
|
return locale
|
|
}
|
|
return configured
|
|
default:
|
|
return configured
|
|
}
|
|
}
|
|
if locale := localeFromAcceptLanguage(r.Header.Get("Accept-Language")); locale != "" {
|
|
return locale
|
|
}
|
|
return configured
|
|
}
|
|
|
|
func localeFromAcceptLanguage(header string) string {
|
|
for _, part := range strings.Split(header, ",") {
|
|
language := strings.ToLower(strings.TrimSpace(strings.SplitN(part, ";", 2)[0]))
|
|
if language == "ru" || strings.HasPrefix(language, "ru-") {
|
|
return "ru"
|
|
}
|
|
if language == "en" || strings.HasPrefix(language, "en-") {
|
|
return "en"
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (s *Server) webLocale(r *http.Request) string {
|
|
return resolveWebLocale(r, s.cfg)
|
|
}
|
|
|
|
func (s *Server) webLocalePreference(r *http.Request) string {
|
|
if cookie, err := r.Cookie(webLocaleCookieName); err == nil && (cookie.Value == "ru" || cookie.Value == "en" || cookie.Value == "system") {
|
|
return cookie.Value
|
|
}
|
|
return "system"
|
|
}
|
|
|
|
func (s *Server) setWebLocale(w http.ResponseWriter, r *http.Request, locale string) {
|
|
secure := s.requestIsHTTPS(r)
|
|
http.SetCookie(w, &http.Cookie{
|
|
Name: webLocaleCookieName, Value: locale, Path: "/", HttpOnly: true,
|
|
Secure: secure, SameSite: http.SameSiteLaxMode, MaxAge: 365 * 24 * 60 * 60,
|
|
})
|
|
}
|