feat: 添加可配置的文件上传大小限制

新增 MAX_FILE_SIZE_MB 环境变量统一控制文件上传大小,默认 50MB
This commit is contained in:
wizardchen
2025-12-30 11:08:05 +08:00
committed by lyingbug
parent 7c302bea1f
commit 6cf7cbcb9c
10 changed files with 93 additions and 17 deletions

View File

@@ -152,4 +152,9 @@ COS_ENABLE_OLD_DOMAIN=true
# NEO4J_USERNAME=neo4j
# Neo4j的密码
# NEO4J_PASSWORD=password
# NEO4J_PASSWORD=password
# ========== 文件上传大小限制 ==========
# 统一的文件大小限制MB默认为50MB
# 影响单文件上传、gRPC消息大小、Nginx请求体大小
# MAX_FILE_SIZE_MB=50

View File

@@ -118,6 +118,8 @@ services:
- MINIO_BUCKET_NAME=${MINIO_BUCKET_NAME:-}
- MINIO_USE_SSL=${MINIO_USE_SSL:-}
- WEB_PROXY=${WEB_PROXY:-}
# File size limit (in MB)
- MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-50}
healthcheck:
test: ["CMD", "grpc_health_probe", "-addr=:50051"]
interval: 30s

View File

@@ -5,6 +5,8 @@ services:
container_name: WeKnora-frontend
ports:
- "${FRONTEND_PORT:-80}:80"
environment:
- MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-50}
depends_on:
app:
condition: service_healthy
@@ -96,6 +98,8 @@ services:
- INIT_RERANK_MODEL_NAME=${INIT_RERANK_MODEL_NAME:-}
- INIT_RERANK_MODEL_BASE_URL=${INIT_RERANK_MODEL_BASE_URL:-}
- INIT_RERANK_MODEL_API_KEY=${INIT_RERANK_MODEL_API_KEY:-}
# File size limit (in MB)
- MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-50}
depends_on:
redis:
condition: service_started
@@ -137,6 +141,8 @@ services:
- MINIO_USE_SSL=${MINIO_USE_SSL:-}
- WEB_PROXY=${WEB_PROXY:-}
- MINERU_ENDPOINT=${MINERU_ENDPOINT:-}
# File size limit (in MB)
- MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-50}
healthcheck:
test: ["CMD", "grpc_health_probe", "-addr=:50051"]
interval: 30s

View File

@@ -4,6 +4,7 @@ import (
"fmt"
"log"
"os"
"strconv"
"time"
"github.com/Tencent/WeKnora/docreader/proto"
@@ -12,9 +13,16 @@ import (
"google.golang.org/grpc/resolver"
)
const (
maxMessageSize = 50 * 1024 * 1024 // 50MB
)
// getMaxMessageSize returns the maximum gRPC message size in bytes.
// Default is 50MB, can be configured via MAX_FILE_SIZE_MB environment variable.
func getMaxMessageSize() int {
if sizeStr := os.Getenv("MAX_FILE_SIZE_MB"); sizeStr != "" {
if size, err := strconv.Atoi(sizeStr); err == nil && size > 0 {
return size * 1024 * 1024
}
}
return 50 * 1024 * 1024 // default 50MB
}
// Logger is the default logger used by the client
var Logger = log.New(os.Stdout, "[DocReader] ", log.LstdFlags|log.Lmicroseconds)
@@ -40,13 +48,14 @@ type Client struct {
func NewClient(addr string) (*Client, error) {
Logger.Printf("INFO: Creating new DocReader client connecting to %s", addr)
// 设置消息大小限制
// 设置消息大小限制 (configurable via GRPC_MAX_MESSAGE_SIZE_MB)
maxMsgSize := getMaxMessageSize()
opts := []grpc.DialOption{
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy":"round_robin"}`),
grpc.WithDefaultCallOptions(
grpc.MaxCallRecvMsgSize(maxMessageSize),
grpc.MaxCallSendMsgSize(maxMessageSize),
grpc.MaxCallRecvMsgSize(maxMsgSize),
grpc.MaxCallSendMsgSize(maxMsgSize),
),
}
resolver.SetDefaultScheme("dns")

View File

@@ -57,8 +57,22 @@ logger.info("Initializing server logging")
# Initialize request ID logging
init_logging_request_id()
# Set max message size to 50MB
MAX_MESSAGE_LENGTH = 50 * 1024 * 1024
def get_max_message_length() -> int:
"""Get max gRPC message length from environment variable.
Default is 50MB, can be configured via MAX_FILE_SIZE_MB.
"""
try:
size_mb = int(os.environ.get("MAX_FILE_SIZE_MB", "50"))
if size_mb > 0:
return size_mb * 1024 * 1024
except ValueError:
pass
return 50 * 1024 * 1024 # default 50MB
# Set max message size (default 50MB, configurable via MAX_FILE_SIZE_MB)
MAX_MESSAGE_LENGTH = get_max_message_length()
parser = Parser()

View File

@@ -27,11 +27,14 @@ FROM nginx:stable-alpine as production-stage
# 复制构建产物到nginx服务目录
COPY --from=build-stage /app/dist /usr/share/nginx/html
# 复制nginx配置文件
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 复制nginx配置模板文件
COPY nginx.conf /etc/nginx/templates/default.conf.template
# 设置默认环境变量MB
ENV MAX_FILE_SIZE_MB=50
# 暴露端口
EXPOSE 80
# 启动nginx
CMD ["nginx", "-g", "daemon off;"]
# 启动时将 MAX_FILE_SIZE_MB 转换为带单位的 MAX_FILE_SIZE然后替换到 nginx 配置
CMD ["/bin/sh", "-c", "export MAX_FILE_SIZE=${MAX_FILE_SIZE_MB}M && envsubst '${MAX_FILE_SIZE}' < /etc/nginx/templates/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"]

View File

@@ -1,7 +1,8 @@
server {
listen 80;
server_name localhost;
client_max_body_size 50M;
# Default 50M, configured via MAX_FILE_SIZE_MB env var
client_max_body_size ${MAX_FILE_SIZE};
# 安全头配置
add_header X-Frame-Options "SAMEORIGIN" always;

View File

@@ -1823,10 +1823,11 @@ func (h *InitializationHandler) TestMultimodalFunction(c *gin.Context) {
return
}
// 验证文件大小 (10MB)
if header.Size > 10*1024*1024 {
// 验证文件大小 (default 50MB, configurable via MAX_FILE_SIZE_MB)
maxSize := utils.GetMaxFileSize()
if header.Size > maxSize {
logger.Error(ctx, "File size too large")
c.Error(errors.NewBadRequestError("图片文件大小不能超过10MB"))
c.Error(errors.NewBadRequestError(fmt.Sprintf("图片文件大小不能超过%dMB", utils.GetMaxFileSizeMB())))
return
}
logger.Infof(ctx, "Processing image: %s", utils.SanitizeForLog(header.Filename))

View File

@@ -118,6 +118,14 @@ func (h *KnowledgeHandler) CreateKnowledgeFromFile(c *gin.Context) {
return
}
// Validate file size (configurable via MAX_FILE_SIZE_MB)
maxSize := secutils.GetMaxFileSize()
if file.Size > maxSize {
logger.Error(ctx, "File size too large")
c.Error(errors.NewBadRequestError(fmt.Sprintf("文件大小不能超过%dMB", secutils.GetMaxFileSizeMB())))
return
}
// Get custom filename if provided (for folder uploads with path)
customFileName := c.PostForm("fileName")
customFileName = secutils.SanitizeForLog(customFileName)

View File

@@ -0,0 +1,27 @@
package utils
import (
"os"
"strconv"
)
// GetMaxFileSize returns the maximum file upload size in bytes.
// Default is 50MB, can be configured via MAX_FILE_SIZE_MB environment variable.
func GetMaxFileSize() int64 {
if sizeStr := os.Getenv("MAX_FILE_SIZE_MB"); sizeStr != "" {
if size, err := strconv.ParseInt(sizeStr, 10, 64); err == nil && size > 0 {
return size * 1024 * 1024
}
}
return 50 * 1024 * 1024 // default 50MB
}
// GetMaxFileSizeMB returns the maximum file upload size in MB.
func GetMaxFileSizeMB() int64 {
if sizeStr := os.Getenv("MAX_FILE_SIZE_MB"); sizeStr != "" {
if size, err := strconv.ParseInt(sizeStr, 10, 64); err == nil && size > 0 {
return size
}
}
return 50 // default 50MB
}