From 07881311b3dd1ef80e1b9776cefcf2c6ee337945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Sat, 24 May 2025 14:57:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E8=AE=BF=E9=97=AE?= =?UTF-8?q?=E5=85=A5=E5=8F=A3=E6=A3=80=E6=9F=A5=EF=BC=8Cfix=20#760?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .goreleaser.yaml | 2 +- internal/http/middleware/entrance.go | 42 ++++------------------- internal/http/middleware/helper.go | 21 ++++++++++++ internal/http/middleware/must_install.go | 15 ++------- internal/http/middleware/must_login.go | 43 ++++-------------------- internal/http/middleware/status.go | 29 +++------------- 6 files changed, 41 insertions(+), 111 deletions(-) create mode 100644 internal/http/middleware/helper.go diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 93bb5a7d..18d95ce5 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -57,7 +57,7 @@ upx: archives: - id: panel - builds: + ids: - web - cli formats: ["zip"] diff --git a/internal/http/middleware/entrance.go b/internal/http/middleware/entrance.go index 10fbf924..75ac5dbe 100644 --- a/internal/http/middleware/entrance.go +++ b/internal/http/middleware/entrance.go @@ -22,19 +22,11 @@ func Entrance(t *gotext.Locale, conf *koanf.Koanf, session *sessions.Manager) fu return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { sess, err := session.GetSession(r) if err != nil { - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusInternalServerError) - render.JSON(chix.M{ - "msg": err.Error(), - }) + Abort(w, http.StatusInternalServerError, "%v", err) return } - entrance := strings.TrimSuffix(conf.String("http.entrance"), "/") - if entrance == "" { - entrance = "/" - } + entrance := conf.String("http.entrance") if !strings.HasPrefix(entrance, "/") { entrance = "/" + entrance } @@ -50,12 +42,7 @@ func Entrance(t *gotext.Locale, conf *koanf.Koanf, session *sessions.Manager) fu } } if len(conf.Strings("http.bind_domain")) > 0 && !slices.Contains(conf.Strings("http.bind_domain"), host) { - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusTeapot) - render.JSON(chix.M{ - "msg": t.Get("invalid request domain: %s", r.Host), - }) + Abort(w, http.StatusTeapot, t.Get("invalid request domain: %s", r.Host)) return } ip, _, err := net.SplitHostPort(r.RemoteAddr) @@ -63,26 +50,16 @@ func Entrance(t *gotext.Locale, conf *koanf.Koanf, session *sessions.Manager) fu ip = r.RemoteAddr } if len(conf.Strings("http.bind_ip")) > 0 && !slices.Contains(conf.Strings("http.bind_ip"), ip) { - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusTeapot) - render.JSON(chix.M{ - "msg": t.Get("invalid request ip: %s", ip), - }) + Abort(w, http.StatusTeapot, t.Get("invalid request ip: %s", ip)) return } if len(conf.Strings("http.bind_ua")) > 0 && !slices.Contains(conf.Strings("http.bind_ua"), r.UserAgent()) { - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusTeapot) - render.JSON(chix.M{ - "msg": t.Get("invalid request user agent: %s", r.UserAgent()), - }) + Abort(w, http.StatusTeapot, t.Get("invalid request user agent: %s", r.UserAgent())) return } // 情况二:请求路径与入口路径相同,标记通过验证并重定向到登录页面 - if strings.TrimSuffix(r.URL.Path, "/") == entrance { + if strings.TrimSuffix(r.URL.Path, "/") == strings.TrimSuffix(entrance, "/") { sess.Put("verify_entrance", true) render := chix.NewRender(w, r) defer render.Release() @@ -107,12 +84,7 @@ func Entrance(t *gotext.Locale, conf *koanf.Koanf, session *sessions.Manager) fu if !conf.Bool("app.debug") && !cast.ToBool(sess.Get("verify_entrance", false)) && r.URL.Path != "/robots.txt" { - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusTeapot) - render.JSON(chix.M{ - "msg": t.Get("invalid access entrance"), - }) + Abort(w, http.StatusTeapot, t.Get("invalid access entrance")) return } diff --git a/internal/http/middleware/helper.go b/internal/http/middleware/helper.go new file mode 100644 index 00000000..3bdd1bc8 --- /dev/null +++ b/internal/http/middleware/helper.go @@ -0,0 +1,21 @@ +package middleware + +import ( + "fmt" + "net/http" + + "github.com/go-rat/chix" +) + +func Abort(w http.ResponseWriter, code int, format string, args ...any) { + render := chix.NewRender(w) + defer render.Release() + render.Header(chix.HeaderContentType, chix.MIMEApplicationJSONCharsetUTF8) // must before Status() + render.Status(code) + if len(args) > 0 { + format = fmt.Sprintf(format, args...) + } + render.JSON(chix.M{ + "msg": format, + }) +} diff --git a/internal/http/middleware/must_install.go b/internal/http/middleware/must_install.go index 7e8a654d..2b5e62ff 100644 --- a/internal/http/middleware/must_install.go +++ b/internal/http/middleware/must_install.go @@ -4,7 +4,6 @@ import ( "net/http" "strings" - "github.com/go-rat/chix" "github.com/leonelquinteros/gotext" "github.com/tnb-labs/panel/internal/biz" @@ -22,12 +21,7 @@ func MustInstall(t *gotext.Locale, app biz.AppRepo) func(next http.Handler) http } else if strings.HasPrefix(r.URL.Path, "/api/apps/") { pathArr := strings.Split(r.URL.Path, "/") if len(pathArr) < 4 { - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusForbidden) - render.JSON(chix.M{ - "msg": t.Get("app not found"), - }) + Abort(w, http.StatusForbidden, t.Get("app not found")) return } slugs = append(slugs, pathArr[3]) @@ -41,12 +35,7 @@ func MustInstall(t *gotext.Locale, app biz.AppRepo) func(next http.Handler) http } } if !flag && len(slugs) > 0 { - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusForbidden) - render.JSON(chix.M{ - "msg": t.Get("app %s not installed", slugs), - }) + Abort(w, http.StatusForbidden, t.Get("app %s not installed", slugs)) return } diff --git a/internal/http/middleware/must_login.go b/internal/http/middleware/must_login.go index a6d25201..3f4e2d1a 100644 --- a/internal/http/middleware/must_login.go +++ b/internal/http/middleware/must_login.go @@ -9,7 +9,6 @@ import ( "slices" "strings" - "github.com/go-rat/chix" "github.com/go-rat/sessions" "github.com/leonelquinteros/gotext" "github.com/spf13/cast" @@ -32,12 +31,7 @@ func MustLogin(t *gotext.Locale, session *sessions.Manager, userToken biz.UserTo return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { sess, err := session.GetSession(r) if err != nil { - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusInternalServerError) - render.JSON(chix.M{ - "msg": err.Error(), - }) + Abort(w, http.StatusInternalServerError, "%v", err) return } @@ -51,32 +45,17 @@ func MustLogin(t *gotext.Locale, session *sessions.Manager, userToken biz.UserTo if r.Header.Get("Authorization") != "" { // 禁止访问 ws 相关的接口 if strings.HasPrefix(r.URL.Path, "/api/ws") { - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusForbidden) - render.JSON(chix.M{ - "msg": t.Get("ws not allowed"), - }) + Abort(w, http.StatusForbidden, t.Get("ws not allowed")) return } // API 请求验证 if userID, err = userToken.ValidateReq(r); err != nil { - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusUnauthorized) - render.JSON(chix.M{ - "msg": err.Error(), - }) + Abort(w, http.StatusUnauthorized, "%v", err) return } } else { if sess.Missing("user_id") { - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusUnauthorized) - render.JSON(chix.M{ - "msg": t.Get("session expired, please login again"), - }) + Abort(w, http.StatusUnauthorized, t.Get("session expired, please login again")) return } @@ -86,12 +65,7 @@ func MustLogin(t *gotext.Locale, session *sessions.Manager, userToken biz.UserTo ip, _, _ := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)) clientHash := fmt.Sprintf("%x", sha256.Sum256([]byte(ip))) if safeClientHash != clientHash || safeClientHash == "" { - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusUnauthorized) - render.JSON(chix.M{ - "msg": t.Get("client ip/ua changed, please login again"), - }) + Abort(w, http.StatusUnauthorized, t.Get("client ip/ua changed, please login again")) return } } @@ -100,12 +74,7 @@ func MustLogin(t *gotext.Locale, session *sessions.Manager, userToken biz.UserTo } if userID == 0 { - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusUnauthorized) - render.JSON(chix.M{ - "msg": t.Get("invalid user id, please login again"), - }) + Abort(w, http.StatusUnauthorized, "%v", t.Get("invalid user id, please login again")) return } diff --git a/internal/http/middleware/status.go b/internal/http/middleware/status.go index 439bd4d9..a193b922 100644 --- a/internal/http/middleware/status.go +++ b/internal/http/middleware/status.go @@ -3,7 +3,6 @@ package middleware import ( "net/http" - "github.com/go-rat/chix" "github.com/leonelquinteros/gotext" "github.com/tnb-labs/panel/internal/app" @@ -15,36 +14,16 @@ func Status(t *gotext.Locale) func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch app.Status { case app.StatusUpgrade: - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusServiceUnavailable) - render.JSON(chix.M{ - "msg": t.Get("panel is upgrading, please refresh later"), - }) + Abort(w, http.StatusServiceUnavailable, t.Get("panel is upgrading, please refresh later")) return case app.StatusMaintain: - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusServiceUnavailable) - render.JSON(chix.M{ - "msg": t.Get("panel is maintaining, please refresh later"), - }) + Abort(w, http.StatusServiceUnavailable, t.Get("panel is maintaining, please refresh later")) return case app.StatusClosed: - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusForbidden) - render.JSON(chix.M{ - "msg": t.Get("panel is closed"), - }) + Abort(w, http.StatusServiceUnavailable, t.Get("panel is closed")) return case app.StatusFailed: - render := chix.NewRender(w) - defer render.Release() - render.Status(http.StatusInternalServerError) - render.JSON(chix.M{ - "msg": t.Get("panel run error, please check or contact support"), - }) + Abort(w, http.StatusInternalServerError, t.Get("panel run error, please check or contact support")) return default: next.ServeHTTP(w, r)