i18n: move out from httperrors pkg

This commit is contained in:
Yousong Zhou
2020-09-18 11:29:23 +08:00
parent b075447f95
commit 1c1dcbde45
11 changed files with 91 additions and 72 deletions
+4 -3
View File
@@ -38,6 +38,7 @@ import (
"yunion.io/x/onecloud/pkg/appctx"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/i18n"
"yunion.io/x/onecloud/pkg/proxy"
"yunion.io/x/onecloud/pkg/util/httputils"
)
@@ -283,7 +284,7 @@ func (app *Application) defaultHandle(w http.ResponseWriter, r *http.Request, ri
if cancel != nil {
defer cancel()
}
ctx = httperrors.WithRequestLang(ctx, r)
ctx = i18n.WithRequestLang(ctx, r)
session := hand.workerMan
if session == nil {
if r.Method == "GET" || r.Method == "HEAD" {
@@ -339,11 +340,11 @@ func (app *Application) defaultHandle(w http.ResponseWriter, r *http.Request, ri
fw.closeChannels()
return hand, appParams
} else {
ctx := httperrors.WithRequestLang(context.TODO(), r)
ctx := i18n.WithRequestLang(context.TODO(), r)
httperrors.InternalServerError(ctx, w, "Invalid handler %s", r.URL)
}
} else if !isCors {
ctx := httperrors.WithRequestLang(context.TODO(), r)
ctx := i18n.WithRequestLang(context.TODO(), r)
httperrors.NotFoundError(ctx, w, "Handler not found")
}
return nil, nil
+3 -2
View File
@@ -27,6 +27,7 @@ import (
"yunion.io/x/onecloud/pkg/appctx"
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/i18n"
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
)
@@ -294,13 +295,13 @@ func getSpecHandler(ctx context.Context, w http.ResponseWriter, r *http.Request)
}
func writeErrNoRequestKey(ctx context.Context, w http.ResponseWriter, r *http.Request, key string) {
ctx = httperrors.WithRequestLang(ctx, r)
ctx = i18n.WithRequestLang(ctx, r)
httperrors.InvalidInputError(ctx, w,
"No request key: %s", key)
}
func writeErrInvalidRequestHeader(ctx context.Context, w http.ResponseWriter, r *http.Request, err error) {
ctx = httperrors.WithRequestLang(ctx, r)
ctx = i18n.WithRequestLang(ctx, r)
httperrors.InvalidInputError(ctx, w,
"Invalid request header: %v", err)
}
+2 -1
View File
@@ -33,6 +33,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/i18n"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/util/rbacutils"
@@ -347,7 +348,7 @@ func (manager *SQuotaBaseManager) setQuotaHandler(ctx context.Context, w http.Re
err := body.Unmarshal(quota, manager.KeywordPlural())
if err != nil {
log.Errorf("Fail to decode JSON request body: %s", err)
httperrors.InvalidInputError(httperrors.WithRequestLang(ctx, r), w, "fail to decode body")
httperrors.InvalidInputError(i18n.WithRequestLang(ctx, r), w, "fail to decode body")
return
}
+2 -2
View File
@@ -31,7 +31,7 @@ import (
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/i18n"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
@@ -55,7 +55,7 @@ func init() {
}
func getLangSuffix(ctx context.Context) string {
lang := httperrors.Lang(ctx)
lang := i18n.Lang(ctx)
switch lang {
case language.English:
return "en"
+3 -56
View File
@@ -19,53 +19,13 @@ import (
"net/http"
"runtime/debug"
"golang.org/x/text/language"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/i18n"
"yunion.io/x/onecloud/pkg/util/httputils"
)
type ctxLang uintptr
const ctxLangKey = ctxLang(0)
const LangHeader = "X-Yunion-Lang"
func SetLangHeader(ctx context.Context, header http.Header) bool {
langv := ctx.Value(ctxLangKey)
langTag, ok := langv.(language.Tag)
if ok {
header.Set(LangHeader, langTag.String())
}
return ok
}
func WithLangTag(ctx context.Context, tag language.Tag) context.Context {
return context.WithValue(ctx, ctxLangKey, tag)
}
func WithLang(ctx context.Context, lang string) context.Context {
tag, err := language.Parse(lang)
if err != nil {
tag = language.English
}
return WithLangTag(ctx, tag)
}
func WithRequestLang(ctx context.Context, req *http.Request) context.Context {
if val := req.URL.Query().Get("lang"); val != "" {
return WithLang(ctx, val)
}
if val := req.Header.Get(LangHeader); val != "" {
return WithLang(ctx, val)
}
if cookie, err := req.Cookie("lang"); err == nil {
return WithLang(ctx, cookie.Value)
}
return WithLangTag(ctx, language.English)
}
func SendHTTPErrorHeader(w http.ResponseWriter, statusCode int) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(statusCode)
@@ -100,29 +60,16 @@ func formatDetails(ctx context.Context, errData httputils.Error, msg string) str
if errData.Id == "" {
details = msg
} else {
lang := Lang(ctx)
lang := i18n.Lang(ctx)
a := make([]interface{}, len(errData.Fields))
for i := range errData.Fields {
a[i] = errData.Fields[i]
}
details = P(lang, errData.Id, a...)
details = i18n.P(lang, errData.Id, a...)
}
return details
}
func Lang(ctx context.Context) language.Tag {
var (
langv = ctx.Value(ctxLangKey)
lang language.Tag
)
if langv != nil {
lang = langv.(language.Tag)
} else {
lang = language.English
}
return lang
}
func HTTPError(ctx context.Context, w http.ResponseWriter, msg string, statusCode int, class string, errData httputils.Error) {
details := formatDetails(ctx, errData, msg)
if statusCode >= 300 && statusCode <= 400 {
+65
View File
@@ -0,0 +1,65 @@
package i18n
import (
"context"
"net/http"
"golang.org/x/text/language"
)
type ctxLang uintptr
const (
ctxLangKey = ctxLang(0)
)
func WithLangTag(ctx context.Context, tag language.Tag) context.Context {
return context.WithValue(ctx, ctxLangKey, tag)
}
func WithLang(ctx context.Context, lang string) context.Context {
tag, err := language.Parse(lang)
if err != nil {
tag = language.English
}
return WithLangTag(ctx, tag)
}
func WithRequestLang(ctx context.Context, req *http.Request) context.Context {
if val := req.URL.Query().Get("lang"); val != "" {
return WithLang(ctx, val)
}
if val := req.Header.Get(LangHeader); val != "" {
return WithLang(ctx, val)
}
if cookie, err := req.Cookie("lang"); err == nil {
return WithLang(ctx, cookie.Value)
}
return WithLangTag(ctx, language.English)
}
func Lang(ctx context.Context) language.Tag {
var (
langv = ctx.Value(ctxLangKey)
lang language.Tag
)
if langv != nil {
lang = langv.(language.Tag)
} else {
lang = language.English
}
return lang
}
const (
LangHeader = "X-Yunion-Lang"
)
func SetHTTPLangHeader(ctx context.Context, header http.Header) bool {
langv := ctx.Value(ctxLangKey)
langTag, ok := langv.(language.Tag)
if ok {
header.Set(LangHeader, langTag.String())
}
return ok
}
+1
View File
@@ -0,0 +1 @@
package i18n // import "yunion.io/x/onecloud/pkg/i18n"
+1 -1
View File
@@ -1,4 +1,4 @@
package httperrors
package i18n
import (
"golang.org/x/text/language"
+3 -3
View File
@@ -30,7 +30,7 @@ import (
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/identity"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/i18n"
"yunion.io/x/onecloud/pkg/util/httputils"
)
@@ -209,7 +209,7 @@ func (this *ClientSession) RawBaseUrlRequest(
populateHeader(&tmpHeader, headers)
}
populateHeader(&tmpHeader, this.Header)
httperrors.SetLangHeader(this.ctx, tmpHeader)
i18n.SetHTTPLangHeader(this.ctx, tmpHeader)
ctx := this.ctx
if this.ctx == nil {
ctx = context.Background()
@@ -245,7 +245,7 @@ func (this *ClientSession) JSONVersionRequest(
populateHeader(&tmpHeader, headers)
}
populateHeader(&tmpHeader, this.Header)
httperrors.SetLangHeader(this.ctx, tmpHeader)
i18n.SetHTTPLangHeader(this.ctx, tmpHeader)
ctx := this.ctx
if this.ctx == nil {
ctx = context.Background()
+5 -3
View File
@@ -24,6 +24,7 @@ import (
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/i18n"
)
type EndpointGenerator func(context.Context, *http.Request) (string, error)
@@ -54,14 +55,15 @@ func NewHTTPReverseProxy(ef *SEndpointFactory, m RequestManipulator) *SReversePr
}
func (p *SReverseProxy) ServeHTTP(ctx context.Context, w http.ResponseWriter, r *http.Request) {
ctx = i18n.WithRequestLang(ctx, r)
endpoint, err := p.generator(ctx, r)
if err != nil {
httperrors.InternalServerError(httperrors.WithRequestLang(ctx, r), w, "%v", err)
httperrors.InternalServerError(ctx, w, "%v", err)
return
}
remoteUrl, err := url.Parse(endpoint)
if err != nil {
httperrors.InternalServerError(httperrors.WithRequestLang(ctx, r), w, "failed parsing url %q: %v", endpoint, err)
httperrors.InternalServerError(ctx, w, "failed parsing url %q: %v", endpoint, err)
return
}
log.Debugf("Forwarding to servie: %q, url: %q", p.serviceName, remoteUrl.String())
@@ -73,7 +75,7 @@ func (p *SReverseProxy) ServeHTTP(ctx context.Context, w http.ResponseWriter, r
}
r, err = p.manipulator(ctx, r)
if err != nil {
httperrors.InternalServerError(httperrors.WithRequestLang(ctx, r), w, "%v", err)
httperrors.InternalServerError(ctx, w, "%v", err)
return
}
proxy.ServeHTTP(w, r)
+2 -1
View File
@@ -22,6 +22,7 @@ import (
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/i18n"
"yunion.io/x/onecloud/pkg/webconsole/session"
)
@@ -34,7 +35,7 @@ func NewConnectionServer() *ConnectionServer {
func (s *ConnectionServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
ctx := context.Background()
ctx = httperrors.WithRequestLang(ctx, req)
ctx = i18n.WithRequestLang(ctx, req)
query, err := jsonutils.ParseQueryString(req.URL.RawQuery)
if err != nil {
httperrors.GeneralServerError(ctx, w, err)