61 lines
1.5 KiB
Go
61 lines
1.5 KiB
Go
|
// Package http detect localized from http header
|
||
|
// and set localized info to metadata as key 'locale'
|
||
|
// The locale used following the specification defined at
|
||
|
// http://www.rfc-editor.org/rfc/bcp/bcp47.txt.
|
||
|
// Examples are: "en-US", "fr-CH", "es-MX"
|
||
|
package http
|
||
|
|
||
|
import (
|
||
|
"net/url"
|
||
|
"sort"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
|
||
|
bm "go-common/library/net/http/blademaster"
|
||
|
)
|
||
|
|
||
|
type language struct {
|
||
|
Name string
|
||
|
Weighting float64
|
||
|
}
|
||
|
|
||
|
// detectLocalizedWeb detect locale from HTTP Accept-Language header
|
||
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language
|
||
|
func detectLocalizedWeb(c *bm.Context) (langs []string) {
|
||
|
parseLang := func(s string) (language, error) {
|
||
|
seps := strings.SplitN(s, ";", 2)
|
||
|
lang := language{Name: seps[0]}
|
||
|
if len(seps) == 1 {
|
||
|
lang.Weighting = 1
|
||
|
return lang, nil
|
||
|
}
|
||
|
params, err := url.ParseQuery(seps[1])
|
||
|
if err != nil {
|
||
|
return lang, err
|
||
|
}
|
||
|
lang.Weighting, err = strconv.ParseFloat(params.Get("q"), 32)
|
||
|
return lang, err
|
||
|
}
|
||
|
items := strings.Split(c.Request.Header.Get("Accept-Language"), ",")
|
||
|
if items[0] == "" {
|
||
|
return
|
||
|
}
|
||
|
// three language is most common accept language send by browser
|
||
|
languages := make([]language, 0, len(items))
|
||
|
for _, s := range items {
|
||
|
l, err := parseLang(s)
|
||
|
if err != nil {
|
||
|
//TODO(weicheng): deal with error
|
||
|
continue
|
||
|
}
|
||
|
languages = append(languages, l)
|
||
|
}
|
||
|
sort.Slice(languages, func(i, j int) bool {
|
||
|
return languages[i].Weighting > languages[j].Weighting
|
||
|
})
|
||
|
for i := range languages {
|
||
|
langs = append(langs, languages[i].Name)
|
||
|
}
|
||
|
return
|
||
|
}
|