go-common/app/interface/main/answer/http/local.go
2019-04-22 18:49:16 +08:00

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
}