Files
filestoragesystem/go/internal/utils/request.go
T
2026-08-23 00:48:10 +08:00

134 lines
2.5 KiB
Go

package utils
import (
"strings"
"github.com/gin-gonic/gin"
)
// ClientIP 获取客户端真实IP
func ClientIP(c *gin.Context) string {
// 优先取反向代理头
for _, header := range []string{"X-Real-IP", "X-Forwarded-For"} {
if v := c.GetHeader(header); v != "" {
ips := strings.Split(v, ",")
ip := strings.TrimSpace(ips[0])
if ip != "" {
return ip
}
}
}
return c.ClientIP()
}
// SanitizePath 清理虚拟路径,防止路径穿越
func SanitizePath(p string) string {
p = strings.ReplaceAll(p, "\\", "/")
parts := make([]string, 0, 8)
for _, seg := range strings.Split(p, "/") {
seg = strings.TrimSpace(seg)
if seg == "" || seg == "." {
continue
}
if seg == ".." {
if len(parts) > 0 {
parts = parts[:len(parts)-1]
}
continue
}
parts = append(parts, seg)
}
return strings.Join(parts, "/")
}
// IsValidPassword 检查密码强度:至少8位,包含字母和数字
func IsValidPassword(pwd string) bool {
if len(pwd) < 8 {
return false
}
hasLetter, hasDigit := false, false
for _, ch := range pwd {
switch {
case ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z':
hasLetter = true
case ch >= '0' && ch <= '9':
hasDigit = true
}
}
return hasLetter && hasDigit
}
// IsEmail 简单校验邮箱格式
func IsEmail(s string) bool {
at := strings.IndexByte(s, '@')
if at <= 0 || at == len(s)-1 {
return false
}
domain := s[at+1:]
return strings.Contains(domain, ".") && strings.IndexByte(domain, '.') != 0 && strings.IndexByte(domain, '.') != len(domain)-1
}
// HumanSize 将字节数转为可读大小
func HumanSize(n int64) string {
const unit = 1024
if n < unit {
return itoa(n) + " B"
}
div, exp := int64(unit), 0
for m := n / unit; m >= unit && exp < 4; m /= unit {
div *= unit
exp++
}
val := float64(n) / float64(div)
s := trimFloat(val)
units := []string{"KB", "MB", "GB", "TB", "PB"}
return s + " " + units[exp]
}
func itoa(n int64) string {
if n == 0 {
return "0"
}
neg := n < 0
if neg {
n = -n
}
var buf [20]byte
i := len(buf)
for n > 0 {
i--
buf[i] = byte('0' + n%10)
n /= 10
}
if neg {
i--
buf[i] = '-'
}
return string(buf[i:])
}
func trimFloat(f float64) string {
// 保留两位小数并去掉末尾多余的0
s := itoa(int64(f))
frac := f - float64(int64(f))
if frac < 0.005 {
return s
}
d1 := int64(frac * 10)
if d1 > 9 {
d1 = 9
}
frac = frac*10 - float64(d1)
d2 := int64(frac * 10)
if d2 > 9 {
d2 = 9
}
if d2 < 5 {
if d1 == 0 {
return s
}
return s + "." + itoa(d1)
}
return s + "." + itoa(d1) + itoa(d2)
}