diff --git a/src/main/java/im/zhaojun/zfile/home/service/base/AbstractS3BaseFileService.java b/src/main/java/im/zhaojun/zfile/home/service/base/AbstractS3BaseFileService.java index fa820fd..e3e43e9 100644 --- a/src/main/java/im/zhaojun/zfile/home/service/base/AbstractS3BaseFileService.java +++ b/src/main/java/im/zhaojun/zfile/home/service/base/AbstractS3BaseFileService.java @@ -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

extends AbstractBaseFileService

{ - + protected AmazonS3 s3Client; - + + @Resource + private SystemConfigService systemConfigService; + @Override public List fileList(String folderPath) { return s3FileList(folderPath); } - - + + /** * 默认 S3 获取对象下载链接的方法, 如果指定了域名, 则替换为自定义域名. * @return S3 对象访问地址 @@ -53,33 +60,33 @@ public abstract class AbstractS3BaseFileService

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

extends A String fullPath = StringUtils.trimStartSlashes(StringUtils.concat(param.getBasePath(), path, ZFileConstant.PATH_SEPARATOR)); List 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

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

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

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

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

extends A } return false; } - + @Override public boolean deleteFolder(String path, String name) { String bucketName = param.getBucketName(); @@ -186,16 +193,16 @@ public abstract class AbstractS3BaseFileService

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

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 rules = new ArrayList<>(); - + // 获取历史的 CORS 规则 + BucketCrossOriginConfiguration bucketCrossOriginConfiguration = s3Client.getBucketCrossOriginConfiguration(param.getBucketName()); + if (bucketCrossOriginConfiguration == null) { + bucketCrossOriginConfiguration = new BucketCrossOriginConfiguration(); + } + List corsRules = bucketCrossOriginConfiguration.getRules(); + if (corsRules == null) { + corsRules = new ArrayList<>(); + } + + + // 当前要添加的规则 + List allowOrigins = Arrays.asList("*", systemConfigService.getDomain(), systemConfigService.getFrontDomain()); + + // 从历史规则中查找是否已经存在, 如果存在则不添加. + boolean presentCorsRules = corsRules.stream().anyMatch(corsRule -> { + List 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

extends A } } } - + } \ No newline at end of file