背景:minio(高性能对象存储,源码是GOLANG。)中业务存储一般使用uuid作为文件名,非用户侧感知的文件名。这样通过getPresignedObjectUrl()方法获取的URL进行下载文件,下载的文件名是uuid文件名,用户体验非常不好,下面我们通过修改minio源码来解决这个问题。
一、编译打包、使用产物运行容器
安装go语言环境
yuwb@cattery minio-local % go version
go version go1.17.5 darwin/arm64
配置依赖下载代理
go env -w GOPROXY=https://goproxy.cn
下载minio指定tag源码
git clone --branch RELEASE.2022-08-02T23-59-16Z https://github.com/minio/minio.git
本地打包运行:
本机:
go build main.go
arm:
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o minio main.go
amd:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o minio main.go
将打包后的minio可执行文件移入docker-compose.yml同级目录。
docker-compose.yml
version: "3"
services:
s3:
image: minio/minio:RELEASE.2022-08-02T23-59-16Z
container_name: docsminio
hostname: minio
environment:
- "MINIO_ACCESS_KEY=minio"
- "MINIO_SECRET_KEY=minio123"
volumes:
- ./minio:/opt/bin/minio
command: server /data --console-address ":9001"
ports:
- "9000:9000"
- "9001:9001"
文件结构
启动容器
访问控制台:
http://localhost:9001
二、代码改造:
1.让minio支持filename参数
使其在下载时在responseheader中添加 "Content-disposition", "attachment; filename=测试文件.txt"。
api路由入口 getObjectHandler()
添加获取URL参数方法
//BillYu 获取URL的GET参数
func GetUrlArg(r *http.Request,name string)string{
var arg string
values := r.URL.Query()
arg=values.Get(name)
return arg
}
请求头中添加URL文件名参数
//BillYu 请求头中添加下载文件名参数
var filename string = GetUrlArg(r, "filename");
if(filename!=""){
w.Header().Set("Content-disposition", "attachment; filename="+filename);
}
查看setHeadGetRespHeaders方法,通用请求头处理
2、修改临时链校验逻辑,使临时链中的URL filename参数不参与签名计算
修改doesPresignedSignatureMatch方法,使其校验签名时排除filename参数。
三、实现效果:
对象存储中的文件名称 test.docx
使用生成链接下载: