daShangDao_centerBook/ip_log.go
2026-02-28 14:27:33 +08:00

80 lines
2.2 KiB
Go
Raw 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 main
import (
"fmt"
"github.com/gin-gonic/gin"
"os"
"path/filepath"
"runtime"
"strings"
"sync"
"time"
)
var (
ipLogFilePath string
ipLogMu sync.Mutex
)
// EnsureIPLogPathInitialized 初始化IP日志文件路径。
// 作用:根据运行系统设置默认存储位置,并确保目录存在,避免写入失败。
// 优先读取环境变量 IP_LOG_FILE例如/www/wwwroot/centerBook/ip.txt
// Windows 默认C:\Users\www\centerBook\ip.txtLinux 默认:/www/wwwroot/centerBook/ip.txt。
func EnsureIPLogPathInitialized() {
if ipLogFilePath != "" {
return
}
if env := os.Getenv("IP_LOG_FILE"); env != "" {
ipLogFilePath = env
} else {
if runtime.GOOS == "windows" {
ipLogFilePath = `C:\Users\www\centerBook\ip.txt`
} else {
ipLogFilePath = "/www/wwwroot/centerBook/ip.txt"
}
}
dir := filepath.Dir(ipLogFilePath)
_ = os.MkdirAll(dir, 0755)
}
// LogLargePerPage 记录超大 per_page 请求的IP信息到文本文件。
// 触发条件:当 per_page 被裁剪(原始值大于上限)时调用。
// 记录内容时间、IP、方法、原始per_page、裁剪后per_page、路径、UA。
func LogLargePerPage(c *gin.Context, originalPerPage, sanitizedPerPage int) {
EnsureIPLogPathInitialized()
line := fmt.Sprintf(
"%s | ip=%s | method=%s | per_page=%d->%d | path=%s | ua=%s\n",
time.Now().Format("2006-01-02 15:04:05"),
c.ClientIP(),
c.Request.Method,
originalPerPage,
sanitizedPerPage,
c.Request.RequestURI,
strings.ReplaceAll(c.GetHeader("User-Agent"), "\n", " "),
)
ipLogMu.Lock()
defer ipLogMu.Unlock()
f, err := os.OpenFile(ipLogFilePath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
// 静默失败,避免影响主流程
return
}
defer f.Close()
_, _ = f.WriteString(line)
}
// IPLogHandler 返回 ip.txt 的内容text/plain
// 用途:通过路由暴露 ip.txt便于反向代理将 https://book.center.buzhiyushu.cn/ip.txt 映射到此接口。
func IPLogHandler() gin.HandlerFunc {
return func(c *gin.Context) {
EnsureIPLogPathInitialized()
data, err := os.ReadFile(ipLogFilePath)
if err != nil {
c.String(200, "")
return
}
c.Header("Content-Type", "text/plain; charset=utf-8")
c.String(200, string(data))
}
}