- 新增 /uploads/thumb/{key}?w=:首访从存储端读一次原图,标准库盒均值缩放后
落盘 data/.thumbnail_cache(按内容哈希命名,天然失效);失败写 .failed 冷却
一小时,非图片/超大一律 302 回原图,前端无感。原图路由改用 ServeContent,
补上视频拖动进度条所需的 Range 支持
- 前端 thumbURL/thumbifyHtml 接入两套 UI 的时间线配图、长文封面与短文正文,
并补 loading=lazy;详情页与灯箱仍用原图。/api/site 改为
{settings, uploads_public_base},让前端识别哪些直链属于自家存储
- 后台登录的滑动窗口限速器抽成 internal/ratelimit 共享包(调用面不变),
新增:读者登录失败按 IP 20 次/10 分钟、评论写入按读者 5 条/分钟
(站主豁免,且只计成功写入)
34 lines
843 B
Go
34 lines
843 B
Go
package admin
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"oneblog/internal/ratelimit"
|
|
)
|
|
|
|
// loginLimiter 限制每个来源 IP 的登录失败次数(滑动窗口),
|
|
// 防止默认/弱口令被在线暴力破解。成功登录后计数清零。
|
|
// 实现挪到了 internal/ratelimit(读者登录/评论写入共用),这里保留
|
|
// 原有调用面与常量。
|
|
type loginLimiter = ratelimit.Window
|
|
|
|
const (
|
|
maxLoginFails = 10
|
|
loginWindow = 10 * time.Minute
|
|
)
|
|
|
|
func newLoginLimiter() *loginLimiter {
|
|
return ratelimit.New(maxLoginFails, loginWindow)
|
|
}
|
|
|
|
func sourceKey(r *http.Request) string { return ratelimit.SourceKey(r) }
|
|
|
|
// isTLS 判断最终用户看到的是不是 HTTPS(含反代 X-Forwarded-Proto)。
|
|
func isTLS(r *http.Request) bool {
|
|
if r.TLS != nil {
|
|
return true
|
|
}
|
|
return r.Header.Get("X-Forwarded-Proto") == "https"
|
|
}
|