优化 S3 协议自动配置跨域逻辑,改为不覆盖原有配置。且增加 GET 跨域,对于在线预览文本、视频场景提供跨域支持.

This commit is contained in:
zhaojun
2022-07-30 20:01:41 +08:00
parent d798750ee6
commit 67a84edd4d

View File

@@ -17,6 +17,7 @@ import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.amazonaws.services.s3.model.SetBucketCrossOriginConfigurationRequest;
import im.zhaojun.zfile.admin.exception.StorageSourceAutoConfigCorsException;
import im.zhaojun.zfile.admin.model.param.S3BaseParam;
import im.zhaojun.zfile.admin.service.SystemConfigService;
import im.zhaojun.zfile.common.constant.ZFileConstant;
import im.zhaojun.zfile.common.exception.file.operator.GetFileInfoException;
import im.zhaojun.zfile.common.util.StringUtils;
@@ -24,11 +25,14 @@ import im.zhaojun.zfile.home.model.enums.FileTypeEnum;
import im.zhaojun.zfile.home.model.result.FileItemResult;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
/**
@@ -36,15 +40,18 @@ import java.util.List;
*/
@Slf4j
public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends AbstractBaseFileService<P> {
protected AmazonS3 s3Client;
@Resource
private SystemConfigService systemConfigService;
@Override
public List<FileItemResult> fileList(String folderPath) {
return s3FileList(folderPath);
}
/**
* 默认 S3 获取对象下载链接的方法, 如果指定了域名, 则替换为自定义域名.
* @return S3 对象访问地址
@@ -53,33 +60,33 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
public String getDownloadUrl(String pathAndName) {
String bucketName = param.getBucketName();
String domain = param.getDomain();
String fullPath = StringUtils.concatTrimStartSlashes(param.getBasePath() + pathAndName);
// 如果不是私有空间, 且指定了加速域名, 则直接返回下载地址.
if (BooleanUtil.isFalse(param.isPrivate()) && StrUtil.isNotEmpty(domain)) {
return StringUtils.concat(domain, StringUtils.encodeAllIgnoreSlashes(fullPath));
}
Integer tokenTime = param.getTokenTime();
if (param.getTokenTime() == null || param.getTokenTime() < 1) {
tokenTime = 1800;
}
Date expirationDate = new Date(System.currentTimeMillis() + tokenTime * 1000);
GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, fullPath, HttpMethod.GET);
generatePresignedUrlRequest.setExpiration(expirationDate);
URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
String defaultUrl = url.toExternalForm();
if (StrUtil.isNotEmpty(domain)) {
defaultUrl = StringUtils.concat(domain, url.getFile());
}
return defaultUrl;
}
/**
* 获取 S3 指定目录下的对象列表
* @param path 路径
@@ -91,7 +98,7 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
String fullPath = StringUtils.trimStartSlashes(StringUtils.concat(param.getBasePath(), path, ZFileConstant.PATH_SEPARATOR));
List<FileItemResult> fileItemList = new ArrayList<>();
ObjectListing objectListing = s3Client.listObjects(new ListObjectsRequest(bucketName, fullPath, "", "/", 1000));
for (S3ObjectSummary s : objectListing.getObjectSummaries()) {
FileItemResult fileItemResult = new FileItemResult();
if (s.getKey().equals(fullPath)) {
@@ -102,13 +109,13 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
fileItemResult.setTime(s.getLastModified());
fileItemResult.setType(FileTypeEnum.FILE);
fileItemResult.setPath(path);
String fullPathAndName = StringUtils.concat(path, fileItemResult.getName());
fileItemResult.setUrl(getDownloadUrl(fullPathAndName));
fileItemList.add(fileItemResult);
}
for (String commonPrefix : objectListing.getCommonPrefixes()) {
FileItemResult fileItemResult = new FileItemResult();
fileItemResult.setName(commonPrefix.substring(fullPath.length(), commonPrefix.length() - 1));
@@ -116,24 +123,24 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
if (StrUtil.isEmpty(name) || StrUtil.equals(name, StringUtils.DELIMITER_STR)) {
continue;
}
fileItemResult.setType(FileTypeEnum.FOLDER);
fileItemResult.setPath(path);
fileItemList.add(fileItemResult);
}
return fileItemList;
}
@Override
public FileItemResult getFileItem(String pathAndName) {
try {
String fileName = FileUtil.getName(pathAndName);
String parentPath = StringUtils.getParentPath(pathAndName);
String trimStartPath = StringUtils.concatTrimStartSlashes(param.getBasePath(), pathAndName);
ObjectMetadata objectMetadata = s3Client.getObjectMetadata(param.getBucketName(), trimStartPath);
FileItemResult fileItemResult = new FileItemResult();
fileItemResult.setName(fileName);
fileItemResult.setSize(objectMetadata.getInstanceLength());
@@ -146,7 +153,7 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
throw new GetFileInfoException(storageId, pathAndName, e);
}
}
@Override
public boolean newFolder(String path, String name) {
String bucketName = param.getBucketName();
@@ -158,7 +165,7 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
PutObjectResult putObjectResult = s3Client.putObject(putObjectRequest);
return putObjectResult != null;
}
@Override
public boolean deleteFile(String path, String name) {
String bucketName = param.getBucketName();
@@ -172,7 +179,7 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
}
return false;
}
@Override
public boolean deleteFolder(String path, String name) {
String bucketName = param.getBucketName();
@@ -186,16 +193,16 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
}
return false;
}
@Override
public boolean renameFile(String path, String name, String newName) {
String bucketName = param.getBucketName();
String srcPath = StringUtils.concat(param.getBasePath(), path, name);
srcPath = StringUtils.trimStartSlashes(srcPath);
String distPath = StringUtils.concat(param.getBasePath(), path, newName);
distPath = StringUtils.trimStartSlashes(distPath);
try {
s3Client.copyObject(bucketName, srcPath, bucketName, distPath);
deleteFile(path, name);
@@ -203,41 +210,62 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
} catch (Exception e) {
log.error("存储源 {} 重命名文件 {} 至 {} 失败", storageId, srcPath, distPath, e);
}
return false;
}
@Override
public boolean renameFolder(String path, String name, String newName) {
throw new UnsupportedOperationException("不支持重命名文件夹");
}
@Override
public String getUploadUrl(String path, String name, Long size) {
String bucketName = param.getBucketName();
String uploadToPath = StringUtils.concat(param.getBasePath(), path, name);
uploadToPath = StringUtils.trimStartSlashes(uploadToPath);
GeneratePresignedUrlRequest req =
new GeneratePresignedUrlRequest(bucketName, uploadToPath, HttpMethod.PUT);
URL url = s3Client.generatePresignedUrl(req);
return url.toExternalForm();
}
protected void setUploadCors() {
if (param.isAutoConfigCors()) {
try {
BucketCrossOriginConfiguration bucketCrossOriginConfiguration = new BucketCrossOriginConfiguration();
ArrayList<CORSRule> rules = new ArrayList<>();
// 获取历史的 CORS 规则
BucketCrossOriginConfiguration bucketCrossOriginConfiguration = s3Client.getBucketCrossOriginConfiguration(param.getBucketName());
if (bucketCrossOriginConfiguration == null) {
bucketCrossOriginConfiguration = new BucketCrossOriginConfiguration();
}
List<CORSRule> corsRules = bucketCrossOriginConfiguration.getRules();
if (corsRules == null) {
corsRules = new ArrayList<>();
}
// 当前要添加的规则
List<String> allowOrigins = Arrays.asList("*", systemConfigService.getDomain(), systemConfigService.getFrontDomain());
// 从历史规则中查找是否已经存在, 如果存在则不添加.
boolean presentCorsRules = corsRules.stream().anyMatch(corsRule -> {
List<String> origins = corsRule.getAllowedOrigins();
return new HashSet<>(origins).containsAll(allowOrigins);
});
if (presentCorsRules) {
log.info("存储源 {} CORS 规则已经存在,不需要重复添加", storageId);
return;
}
CORSRule corsRule = new CORSRule();
corsRule.setAllowedMethods(CORSRule.AllowedMethods.PUT);
corsRule.setAllowedOrigins("*");
rules.add(corsRule);
bucketCrossOriginConfiguration.setRules(rules);
corsRule.setAllowedMethods(CORSRule.AllowedMethods.PUT, CORSRule.AllowedMethods.GET);
corsRule.setAllowedOrigins("*", systemConfigService.getDomain(), systemConfigService.getFrontDomain());
corsRules.add(corsRule);
bucketCrossOriginConfiguration.setRules(corsRules);
SetBucketCrossOriginConfigurationRequest setBucketCrossOriginConfigurationRequest =
new SetBucketCrossOriginConfigurationRequest(param.getBucketName(), bucketCrossOriginConfiguration);
s3Client.setBucketCrossOriginConfiguration(setBucketCrossOriginConfigurationRequest);
@@ -246,5 +274,5 @@ public abstract class AbstractS3BaseFileService<P extends S3BaseParam> extends A
}
}
}
}