fix(backend): harden write registrar boundaries
This commit is contained in:
@@ -2,6 +2,7 @@ package files
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
@@ -26,12 +27,20 @@ type SourceDTO struct {
|
||||
|
||||
// Handler 负责 multipart 边界,文件名清理和本地路径构造始终委托给 Service。
|
||||
type Handler struct {
|
||||
service *Service
|
||||
service *Service
|
||||
maxUploadBytes int64
|
||||
}
|
||||
|
||||
// DefaultMaxUploadBytes 是未显式配置时的请求体上限,覆盖完整 multipart 内容。
|
||||
const DefaultMaxUploadBytes int64 = 32 << 20
|
||||
|
||||
// NewHandler 创建文件资料 HTTP registrar。
|
||||
func NewHandler(service *Service) *Handler {
|
||||
return &Handler{service: service}
|
||||
func NewHandler(service *Service, limits ...int64) *Handler {
|
||||
limit := DefaultMaxUploadBytes
|
||||
if len(limits) > 0 && limits[0] > 0 {
|
||||
limit = limits[0]
|
||||
}
|
||||
return &Handler{service: service, maxUploadBytes: limit}
|
||||
}
|
||||
|
||||
// Register 将文件资料上传接口注册到上层提供的 /api/v1 路由组。
|
||||
@@ -55,8 +64,15 @@ func (h *Handler) upload(c *gin.Context) {
|
||||
writeSourceError(c, err)
|
||||
return
|
||||
}
|
||||
// MaxBytesReader 必须在任何 multipart 解析前安装,限制字段、边界和文件内容的总请求量。
|
||||
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, h.maxUploadBytes)
|
||||
fileHeader, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
var maxBytesError *http.MaxBytesError
|
||||
if errors.As(err, &maxBytesError) {
|
||||
httpx.Error(c, http.StatusRequestEntityTooLarge, "payload_too_large", "上传内容超过大小限制")
|
||||
return
|
||||
}
|
||||
httpx.Error(c, http.StatusBadRequest, "invalid_request", "请选择要上传的文件")
|
||||
return
|
||||
}
|
||||
@@ -75,6 +91,10 @@ func (h *Handler) upload(c *gin.Context) {
|
||||
}
|
||||
source, err := h.service.CreateSource(userID, project, c.PostForm("title"), stored)
|
||||
if err != nil {
|
||||
if cleanupErr := h.service.Remove(stored); cleanupErr != nil {
|
||||
// 清理错误仅写服务端日志,响应继续使用稳定中文错误,不暴露 storage root。
|
||||
log.Printf("source file cleanup failed: %v", cleanupErr)
|
||||
}
|
||||
writeSourceError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user