Skip to content

ZeeLyn/UploadMiddleware

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

50 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

UploadMiddleware

文件上传中间件,支持分片断点上传,目前还在开发迭代中,可能有些地方会做调整,目前不建议使用到生成环境

Packages & Status

Packages NuGet
UploadMiddleware.Core NuGet package
UploadMiddleware.LocalStorage NuGet package
UploadMiddleware.AliyunOSS NuGet package

注册&配置

本地存储

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddUploadLocalStorage(options =>
    {
        options.RootDirectory = Configuration.GetSection("SaveRootDirectory").Value;
        options.AddAllowFileExtension(".mp4");
        options.AddUploadCompletedHandler<CustomUploadCompletedHandler>();
    });
}

分片上传,本地存储

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

    services.AddChunkedUploadLocalStorage(options =>
    {
        options.AddAllowFileExtension(".zip",".mp4");
        options.RootDirectory = Configuration.GetSection("SaveRootDirectory").Value;
        options.DeleteChunksOnMerged = true;
    });
}

上传阿里云OSS

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddUploadAliyunOSS(options =>
    {
        options.AccessId = Configuration.GetSection("OSS:AccessId").Value;
        options.AccessKeySecret = Configuration.GetSection("OSS:AccessKeySecret").Value;
        options.BucketName = Configuration.GetSection("OSS:BucketName").Value;
        options.Endpoint = Configuration.GetSection("OSS:Endpoint").Value;
        options.RootDirectory = Configuration.GetSection("OSS:RootDirectory").Value;
    });
}

启用中间件

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //配置上传路由
    app.UseUpload("/upload");
}

路由示例&说明(以下实例路由可在Configure方法里定义)

上传文件路由

路由 请求类型 ContentType
/upload POST multipart/form-data
请求参数 类型 位置 说明
file binary body 至少要上传一个文件
file-md5 string header 文件的MD5值,分片上传时必须
chunk int header 当前上的分片索引,从0开始,分片上传时必须

检查已经上传的分片数量

路由 请求类型 ContentType 说明
/upload?action=chunks POST application/x-www-form-urlencoded 此接口只适用于单线程,分片按顺序上传
请求参数 类型 位置 说明
file-md5 string header 文件的MD5值
返回值 类型 说明
errmsg string 具体的错误信息
chunks int 已经上传的分片数量,默认会是已经上传的分片数量减一,因为可能最后一个分片不完整

检查单个分片的完整性

路由 请求类型 ContentType
/upload?action=chunk POST application/x-www-form-urlencoded
请求参数 类型 位置 说明
chunk-md5 string header 分片的MD5值
file-md5 string header 文件的MD5值
chunk int header 分片索引,从0开始
返回值 类型 说明
errmsg string 具体的错误信息
data int 0或1,1表示分片完整

合并分片

路由 请求类型 ContentType
/upload?action=merge POST application/x-www-form-urlencoded
请求参数 类型 位置 说明
file-md5 string header 文件的MD5值
chunks int header 分片数量

可选配置

参数 类型 说明
RootDirectory string 文件保存的根目录
MultipartBodyLengthLimit long Multipart Body的上限,Kestrel服务下才起作用,IIS下请在web.config里配置
AllowFileExtension HashSet 允许上传的文件格式(以"."开头),默认有:.jpg,.jpeg,.png,.gif,可以自行添加和删除
BufferSize int 缓冲池大小(默认64KB),推荐不要超过64KB,超过后会写磁盘
ChunksRootDirectory string 存放分片的跟目录,不设置则默认使用RootDirectory
DeleteChunksOnMerged bool 当分片合并完成时,是否删除分片,(默认:True)
AccessId string OSS access key Id
AccessKeySecret string OSS key secret
Endpoint string OSS endpoint
BucketName string OSS bucket name
SecurityToken string STS security token
Metadata Dictionary 设置文件的元数据,每种文件格式可以单独配置,可使用以下占位符:$(form:name): 表单数据,name是具体的form表单key;$(query:name): query参数,name是具体的query参数key;$LocalFileName: 本地文件名;$SectionName: MultipartBody的name值;
AddUploadCompletedHandler method 添加自定义(文件/分片)上传完成返回结果组装Handler
AddUploadProcessor method 添加自定义上传处理器
AddFileValidator method 添加自定义文件格式验证器
AddSubdirectoryGenerator method 添加子目录生成器
AddFileNameGenerator method 添加文件名生成器
AddCheckChunksProcessor method 添加自定义分片数量检测器
AddCheckChunkProcessor method 添加自定义分片完整性检测器
AddMergeProcessor method 添加自定义分片合并器
AddMergeHandler method 添加分片合并完成返回结果组装Handler

关于分片上传

  • 分片上传会有两种情况,一种是前端多线程上传,一种是单线程上传。
  • 如果是多线程上传,上传分片的顺序可能是乱的,所以如果你需要支持断点续传的话,需要在上传前检查分片的完整性。
  • 单线程上传的话就简单一些,只要前端保证按顺序上传就可以,如果需要支持断点续传,只需要在上传前检查已经上传的分片数量,默认情况下返回的分片数量会是已经上传的分片数量减一,因为最后一个分片可能是不完整的,当然你也可以选择没个分片都验证完整性。
  • 前端推荐使用WebUploader

关于文件格式验证

  • 很多人上传文件只是单纯的验证文件的后缀名,这是不安全的。
  • UploadMiddleware默认的文件验证器,不止验证了后缀名,还会根据后缀名验证文件的签名,具体的文件签名可以去这两个地方查询:https://www.filesignatures.net/index.php?page=search , https://en.wikipedia.org/wiki/List_of_file_signatures
  • UploadMiddleware内置了常用(.jpg、.png、.gif、.bmp、.mp3、.mp4、.rar、.zip、.doc、.docx、.xls、.xlsx、.ppt、.pptx、.pdf)的文件签名,可通过FileSignature类查询和添加

关于权限控制

  • UploadMiddleware是中间件,中间件内不能加权限过滤器。
  • 解决办法是在项目里写一个跟中间件路由一致的空api,api不需要有任何逻辑,也不会被调用,并加上AuthorizeAttribtue即可解决授权问题。