Files
OpenList/server/common/common.go
2026-05-26 13:03:29 +08:00

170 lines
3.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package common
import (
"context"
"fmt"
"html"
stdnet "net"
"net/http"
"strings"
"github.com/OpenListTeam/OpenList/v4/cmd/flags"
"github.com/OpenListTeam/OpenList/v4/internal/conf"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
)
func hidePrivacy(msg string) string {
for _, r := range conf.PrivacyReg {
msg = r.ReplaceAllStringFunc(msg, func(s string) string {
return strings.Repeat("*", len(s))
})
}
return msg
}
// ErrorResp is used to return error response
// @param l: if true, log error
func ErrorResp(c *gin.Context, err error, code int, l ...bool) {
ErrorWithDataResp(c, err, code, nil, l...)
//if len(l) > 0 && l[0] {
// if flags.Debug || flags.Dev {
// log.Errorf("%+v", err)
// } else {
// log.Errorf("%v", err)
// }
//}
//c.JSON(200, Resp[interface{}]{
// Code: code,
// Message: hidePrivacy(err.Error()),
// Data: nil,
//})
//c.Abort()
}
// ErrorPage is used to return error page HTML.
// It also returns standard HTTP status code.
// @param l: if true, log error
func ErrorPage(c *gin.Context, err error, code int, l ...bool) {
if len(l) > 0 && l[0] {
if flags.Debug || flags.Dev {
log.Errorf("%+v", err)
} else {
log.Errorf("%v", err)
}
}
codes := fmt.Sprintf("%d %s", code, http.StatusText(code))
html := fmt.Sprintf(`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="color-scheme" content="dark light" />
<meta name="robots" content="noindex" />
<title>%s</title>
</head>
<body>
<h1>%s</h1>
<hr>
<p>%s</p>
</body>
</html>`,
codes, codes, html.EscapeString(hidePrivacy(err.Error())))
c.Data(code, "text/html; charset=utf-8", []byte(html))
c.Abort()
}
func ErrorWithDataResp(c *gin.Context, err error, code int, data interface{}, l ...bool) {
if len(l) > 0 && l[0] {
if flags.Debug || flags.Dev {
log.Errorf("%+v", err)
} else {
log.Errorf("%v", err)
}
}
c.JSON(200, Resp[interface{}]{
Code: code,
Message: hidePrivacy(err.Error()),
Data: data,
})
c.Abort()
}
func ErrorStrResp(c *gin.Context, str string, code int, l ...bool) {
if len(l) != 0 && l[0] {
log.Error(str)
}
c.JSON(200, Resp[interface{}]{
Code: code,
Message: hidePrivacy(str),
Data: nil,
})
c.Abort()
}
func SuccessResp(c *gin.Context, data ...interface{}) {
SuccessWithMsgResp(c, "success", data...)
}
func SuccessWithMsgResp(c *gin.Context, msg string, data ...interface{}) {
var respData interface{}
if len(data) > 0 {
respData = data[0]
}
c.JSON(200, Resp[interface{}]{
Code: 200,
Message: msg,
Data: respData,
})
}
func Pluralize(count int, singular, plural string) string {
if count == 1 {
return singular
}
return plural
}
type requestContext struct {
context.Context
}
// GinAppendValues 向当前请求上下文追加键值,提供类似 gin.Context Set/Get 的可变语义。
// 同一请求内,已持有的上下文引用会同步看到后续更新。
func GinAppendValues(c *gin.Context, keyAndValue ...any) {
ctx := c.Request.Context()
if r, ok := ctx.(*requestContext); ok {
r.Context = ContentWithValues(r.Context, keyAndValue...)
return
}
c.Request = c.Request.WithContext(
&requestContext{ContentWithValues(ctx, keyAndValue...)},
)
}
func ContentWithValues(ctx context.Context, keyAndValue ...any) context.Context {
if len(keyAndValue) < 1 || len(keyAndValue)%2 != 0 {
panic("keyAndValue must be an even number of arguments (key, value, ...)")
}
for len(keyAndValue) > 0 {
ctx = context.WithValue(ctx, keyAndValue[0], keyAndValue[1])
keyAndValue = keyAndValue[2:]
}
return ctx
}
// StripHostPort 从 Host 头中去掉端口部分,返回纯域名。
// 支持 IPv4、IPv6[::1]:port及无端口的裸域名/IP。
func StripHostPort(host string) string {
h, _, err := stdnet.SplitHostPort(host)
if err != nil {
// 无端口,原样返回
return host
}
return h
}