You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在MinIO预签名URL分片上传中设置文件大小限制?

MinIO预签名URL分片上传的大小限制方案

针对你不想让应用接收文件、仅用预签名URL完成上传,同时要限制文件大小的需求,给你几个可行的落地方案:

1. 用MinIO桶策略直接限制单分片大小

MinIO支持通过桶策略的content-length-range条件,直接限制上传的分片大小,这是最直接的方式,不用修改应用代码,由MinIO直接拦截不符合大小的分片上传请求。

比如给目标桶添加这样的策略(针对分片上传的PutObject操作):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::your-bucket/*",
      "Condition": {
        "ContentLengthRange": [5242880, 104857600] // 限制分片大小在5MB到100MB之间(最后一片可更小,MinIO会自动兼容)
      }
    }
  ]
}

用户用预签名URL上传分片时,若大小超出范围,MinIO会直接返回403错误,无需应用介入。

2. 初始化分片时提前校验总文件大小

修改你的StartMultiPartDto,让客户端传入文件总大小,在应用初始化分片时先判断是否超过允许的最大值,直接拦截不符合要求的请求:

首先更新Dto:

public class StartMultiPartDto
{
    public string FileName { get; set; }
    public long TotalFileSize { get; set; } // 新增总大小字段
}

然后修改StartMultiPart接口:

[HttpPost("start-multipart")]
public async Task<IActionResult> StartMultiPart([FromBody] StartMultiPartDto request)
{
    // 假设允许的最大文件大小为10GB
    var maxAllowedSize = 10L * 1024 * 1024 * 1024;
    if (request.TotalFileSize > maxAllowedSize)
    {
        return BadRequest("文件大小超过限制");
    }

    var key = Guid.NewGuid().ToString();
    var uploadId = await _objectStorageService.StartMultiPart(key, request.FileName);

    return Ok(new { key, uploadId });
}

注意:客户端可能伪造总大小,需要后续步骤兜底校验。

3. 完成分片时校验实际总大小

在调用CompleteMultiPart时,先通过MinIO的API获取所有已上传分片的大小总和,对比限制值,不符合就终止上传:

修改CompleteMultiPart接口:

[HttpPost("{key}/complete-multipart")]
public async Task<IActionResult> CompleteMultiPart([FromRoute] string key, [FromBody] CompleteMultiPartDto request)
{
    var maxAllowedSize = 10L * 1024 * 1024 * 1024;
    // 获取所有已上传的分片信息
    var parts = await _objectStorageService.ListParts(key, request.UploadId);
    var totalSize = parts.Sum(p => p.Size);

    if (totalSize > maxAllowedSize)
    {
        // 超过大小,终止分片上传
        await _objectStorageService.AbortMultiPart(key, request.UploadId);
        return BadRequest("实际文件大小超过限制");
    }

    await _objectStorageService.CompleteMultiPart(key, request.UploadId, request.Parts);
    return Ok();
}

对应的ObjectStorageService里需要实现ListParts方法,调用MinIO的ListPartsAsync接口即可。

4. 用MinIO事件通知做兜底校验

配置MinIO在对象上传完成后发送事件到你的应用,应用收到事件后检查对象大小,超过限制就删除该对象:

比如配置MinIO的事件通知,当s3:ObjectCreated:*事件触发时,发送到你的应用某个端点(该端点仅接收事件通知,不接收文件),然后在应用里处理:

[HttpPost("minio-event")]
public async Task<IActionResult> HandleMinioEvent([FromBody] MinioEventNotification notification)
{
    var maxAllowedSize = 10L * 1024 * 1024 * 1024;
    foreach (var record in notification.Records)
    {
        var objectSize = long.Parse(record.S3.Object.Size);
        if (objectSize > maxAllowedSize)
        {
            // 删除超出限制的对象
            await _objectStorageService.DeleteObject(record.S3.Bucket.Name, record.S3.Object.Key);
            // 可记录日志或通知用户
        }
    }
    return Ok();
}

这个方案作为最后一道防线,防止前面的校验被绕过。


你的现有代码可基于上面的方案调整,另外你的项目是video uploader,可根据视频上传场景调整大小限制的数值。

内容的提问来源于stack exchange,提问作者Luiz Kohler

火山引擎 最新活动