From a2714fb9f7ffb84d850d01a2f9acd1cb27c58fdb Mon Sep 17 00:00:00 2001 From: 秋辞未寒 <545073804@qq.com> Date: 星期五, 17 一月 2025 15:55:17 +0800 Subject: [PATCH] update 优化 OSS私有桶的临时URL获取方法 --- ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java | 511 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 378 insertions(+), 133 deletions(-) diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java index 992e3d4..59c599b 100644 --- a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java +++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java @@ -2,73 +2,116 @@ import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.IdUtil; -import com.amazonaws.ClientConfiguration; -import com.amazonaws.HttpMethod; -import com.amazonaws.Protocol; -import com.amazonaws.auth.AWSCredentials; -import com.amazonaws.auth.AWSCredentialsProvider; -import com.amazonaws.auth.AWSStaticCredentialsProvider; -import com.amazonaws.auth.BasicAWSCredentials; -import com.amazonaws.client.builder.AwsClientBuilder; -import com.amazonaws.services.s3.AmazonS3; -import com.amazonaws.services.s3.AmazonS3Client; -import com.amazonaws.services.s3.AmazonS3ClientBuilder; -import com.amazonaws.services.s3.model.*; +import org.dromara.common.core.constant.Constants; import org.dromara.common.core.utils.DateUtils; import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.core.utils.file.FileUtils; import org.dromara.common.oss.constant.OssConstant; import org.dromara.common.oss.entity.UploadResult; import org.dromara.common.oss.enumd.AccessPolicyType; -import org.dromara.common.oss.enumd.PolicyType; import org.dromara.common.oss.exception.OssException; import org.dromara.common.oss.properties.OssProperties; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.core.ResponseInputStream; +import software.amazon.awssdk.core.async.AsyncResponseTransformer; +import software.amazon.awssdk.core.async.BlockingInputStreamAsyncRequestBody; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.S3AsyncClient; +import software.amazon.awssdk.services.s3.S3Configuration; +import software.amazon.awssdk.services.s3.crt.S3CrtHttpConfiguration; +import software.amazon.awssdk.services.s3.model.GetObjectResponse; +import software.amazon.awssdk.services.s3.presigner.S3Presigner; +import software.amazon.awssdk.transfer.s3.S3TransferManager; +import software.amazon.awssdk.transfer.s3.model.*; +import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener; -import java.io.ByteArrayInputStream; -import java.io.InputStream; +import java.io.*; +import java.net.URI; import java.net.URL; -import java.util.Date; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; /** * S3 瀛樺偍鍗忚 鎵�鏈夊吋瀹筍3鍗忚鐨勪簯鍘傚晢鍧囨敮鎸� * 闃块噷浜� 鑵捐浜� 涓冪墰浜� minio * - * @author Lion Li + * @author AprilWind */ public class OssClient { + /** + * 鏈嶅姟鍟� + */ private final String configKey; + /** + * 閰嶇疆灞炴�� + */ private final OssProperties properties; - private final AmazonS3 client; + /** + * Amazon S3 寮傛瀹㈡埛绔� + */ + private final S3AsyncClient client; + /** + * 鐢ㄤ簬绠$悊 S3 鏁版嵁浼犺緭鐨勯珮绾у伐鍏� + */ + private final S3TransferManager transferManager; + + /** + * AWS S3 棰勭鍚� URL 鐨勭敓鎴愬櫒 + */ + private final S3Presigner presigner; + + /** + * 鏋勯�犳柟娉� + * + * @param configKey 閰嶇疆閿� + * @param ossProperties Oss閰嶇疆灞炴�� + */ public OssClient(String configKey, OssProperties ossProperties) { this.configKey = configKey; this.properties = ossProperties; try { - AwsClientBuilder.EndpointConfiguration endpointConfig = - new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion()); + // 鍒涘缓 AWS 璁よ瘉淇℃伅 + StaticCredentialsProvider credentialsProvider = StaticCredentialsProvider.create( + AwsBasicCredentials.create(properties.getAccessKey(), properties.getSecretKey())); - AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey()); - AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials); - ClientConfiguration clientConfig = new ClientConfiguration(); - if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) { - clientConfig.setProtocol(Protocol.HTTPS); - } else { - clientConfig.setProtocol(Protocol.HTTP); - } - AmazonS3ClientBuilder build = AmazonS3Client.builder() - .withEndpointConfiguration(endpointConfig) - .withClientConfiguration(clientConfig) - .withCredentials(credentialsProvider) - .disableChunkedEncoding(); - if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)) { - // minio 浣跨敤https闄愬埗浣跨敤鍩熷悕璁块棶 闇�瑕佹閰嶇疆 绔欑偣濉煙鍚� - build.enablePathStyleAccess(); - } - this.client = build.build(); + // MinIO 浣跨敤 HTTPS 闄愬埗浣跨敤鍩熷悕璁块棶锛岀珯鐐瑰~鍩熷悕銆傞渶瑕佸惎鐢ㄨ矾寰勬牱寮忚闂� + boolean isStyle = !StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE); - createBucket(); + // 鍒涘缓AWS鍩轰簬 CRT 鐨� S3 瀹㈡埛绔� + this.client = S3AsyncClient.crtBuilder() + .credentialsProvider(credentialsProvider) + .endpointOverride(URI.create(getEndpoint())) + .region(of()) + .targetThroughputInGbps(20.0) + .minimumPartSizeInBytes(10 * 1025 * 1024L) + .checksumValidationEnabled(false) + .forcePathStyle(isStyle) + .httpConfiguration(S3CrtHttpConfiguration.builder() + .connectionTimeout(Duration.ofSeconds(60)) // 璁剧疆杩炴帴瓒呮椂 + .build()) + .build(); + + //AWS鍩轰簬 CRT 鐨� S3 AsyncClient 瀹炰緥鐢ㄤ綔 S3 浼犺緭绠$悊鍣ㄧ殑搴曞眰瀹㈡埛绔� + this.transferManager = S3TransferManager.builder().s3Client(this.client).build(); + + // 鍒涘缓 S3 閰嶇疆瀵硅薄 + S3Configuration config = S3Configuration.builder().chunkedEncodingEnabled(false) + .pathStyleAccessEnabled(isStyle).build(); + + // 鍒涘缓 棰勭鍚� URL 鐨勭敓鎴愬櫒 瀹炰緥锛岀敤浜庣敓鎴� S3 棰勭鍚� URL + this.presigner = S3Presigner.builder() + .region(of()) + .credentialsProvider(credentialsProvider) + .endpointOverride(URI.create(getDomain())) + .serviceConfiguration(config) + .build(); + } catch (Exception e) { if (e instanceof OssException) { throw e; @@ -77,125 +120,355 @@ } } - public void createBucket() { + /** + * 涓婁紶鏂囦欢鍒� Amazon S3锛屽苟杩斿洖涓婁紶缁撴灉 + * + * @param filePath 鏈湴鏂囦欢璺緞 + * @param key 鍦� Amazon S3 涓殑瀵硅薄閿� + * @param md5Digest 鏈湴鏂囦欢鐨� MD5 鍝堝笇鍊硷紙鍙�夛級 + * @param contentType 鏂囦欢鍐呭绫诲瀷 + * @return UploadResult 鍖呭惈涓婁紶鍚庣殑鏂囦欢淇℃伅 + * @throws OssException 濡傛灉涓婁紶澶辫触锛屾姏鍑鸿嚜瀹氫箟寮傚父 + */ + public UploadResult upload(Path filePath, String key, String md5Digest, String contentType) { try { - String bucketName = properties.getBucketName(); - if (client.doesBucketExistV2(bucketName)) { - return; - } - CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); - AccessPolicyType accessPolicy = getAccessPolicy(); - createBucketRequest.setCannedAcl(accessPolicy.getAcl()); - client.createBucket(createBucketRequest); - client.setBucketPolicy(bucketName, getPolicy(bucketName, accessPolicy.getPolicyType())); + // 鏋勫缓涓婁紶璇锋眰瀵硅薄 + FileUpload fileUpload = transferManager.uploadFile( + x -> x.putObjectRequest( + y -> y.bucket(properties.getBucketName()) + .key(key) + .contentMD5(StringUtils.isNotEmpty(md5Digest) ? md5Digest : null) + .contentType(contentType) + // 鐢ㄤ簬璁剧疆瀵硅薄鐨勮闂帶鍒跺垪琛紙ACL锛夈�備笉鍚屼簯鍘傚晢瀵笰CL鐨勬敮鎸佸拰瀹炵幇鏂瑰紡鏈夋墍涓嶅悓锛� + // 鍥犳鏍规嵁鍏蜂綋鐨勪簯鏈嶅姟鎻愪緵鍟嗭紝浣犲彲鑳介渶瑕佽繘琛屼笉鍚岀殑閰嶇疆锛堣嚜琛屽紑鍚紝闃块噷浜戞湁acl鏉冮檺閰嶇疆锛岃吘璁簯娌℃湁acl鏉冮檺閰嶇疆锛� + //.acl(getAccessPolicy().getObjectCannedACL()) + .build()) + .addTransferListener(LoggingTransferListener.create()) + .source(filePath).build()); + + // 绛夊緟涓婁紶瀹屾垚骞惰幏鍙栦笂浼犵粨鏋� + CompletedFileUpload uploadResult = fileUpload.completionFuture().join(); + String eTag = uploadResult.response().eTag(); + + // 鎻愬彇涓婁紶缁撴灉涓殑 ETag锛屽苟鏋勫缓涓�涓嚜瀹氫箟鐨� UploadResult 瀵硅薄 + return UploadResult.builder().url(getUrl() + StringUtils.SLASH + key).filename(key).eTag(eTag).build(); } catch (Exception e) { - throw new OssException("鍒涘缓Bucket澶辫触, 璇锋牳瀵归厤缃俊鎭�:[" + e.getMessage() + "]"); + // 鎹曡幏寮傚父骞舵姏鍑鸿嚜瀹氫箟寮傚父 + throw new OssException("涓婁紶鏂囦欢澶辫触锛岃妫�鏌ラ厤缃俊鎭�:[" + e.getMessage() + "]"); + } finally { + // 鏃犺涓婁紶鏄惁鎴愬姛锛屾渶缁堥兘浼氬垹闄や复鏃舵枃浠� + FileUtils.del(filePath); } } - public UploadResult upload(byte[] data, String path, String contentType) { - return upload(new ByteArrayInputStream(data), path, contentType); - } - - public UploadResult upload(InputStream inputStream, String path, String contentType) { + /** + * 涓婁紶 InputStream 鍒� Amazon S3 + * + * @param inputStream 瑕佷笂浼犵殑杈撳叆娴� + * @param key 鍦� Amazon S3 涓殑瀵硅薄閿� + * @param length 杈撳叆娴佺殑闀垮害 + * @param contentType 鏂囦欢鍐呭绫诲瀷 + * @return UploadResult 鍖呭惈涓婁紶鍚庣殑鏂囦欢淇℃伅 + * @throws OssException 濡傛灉涓婁紶澶辫触锛屾姏鍑鸿嚜瀹氫箟寮傚父 + */ + public UploadResult upload(InputStream inputStream, String key, Long length, String contentType) { + // 濡傛灉杈撳叆娴佷笉鏄� ByteArrayInputStream锛屽垯灏嗗叾璇诲彇涓哄瓧鑺傛暟缁勫啀鍒涘缓 ByteArrayInputStream if (!(inputStream instanceof ByteArrayInputStream)) { inputStream = new ByteArrayInputStream(IoUtil.readBytes(inputStream)); } try { - ObjectMetadata metadata = new ObjectMetadata(); - metadata.setContentType(contentType); - metadata.setContentLength(inputStream.available()); - PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata); - // 璁剧疆涓婁紶瀵硅薄鐨� Acl 涓哄叕鍏辫 - putObjectRequest.setCannedAcl(getAccessPolicy().getAcl()); - client.putObject(putObjectRequest); + // 鍒涘缓寮傛璇锋眰浣擄紙length濡傛灉涓虹┖浼氭姤閿欙級 + BlockingInputStreamAsyncRequestBody body = BlockingInputStreamAsyncRequestBody.builder() + .contentLength(length) + .subscribeTimeout(Duration.ofSeconds(30)) + .build(); + + // 浣跨敤 transferManager 杩涜涓婁紶 + Upload upload = transferManager.upload( + x -> x.requestBody(body) + .putObjectRequest( + y -> y.bucket(properties.getBucketName()) + .key(key) + .contentType(contentType) + // 鐢ㄤ簬璁剧疆瀵硅薄鐨勮闂帶鍒跺垪琛紙ACL锛夈�備笉鍚屼簯鍘傚晢瀵笰CL鐨勬敮鎸佸拰瀹炵幇鏂瑰紡鏈夋墍涓嶅悓锛� + // 鍥犳鏍规嵁鍏蜂綋鐨勪簯鏈嶅姟鎻愪緵鍟嗭紝浣犲彲鑳介渶瑕佽繘琛屼笉鍚岀殑閰嶇疆锛堣嚜琛屽紑鍚紝闃块噷浜戞湁acl鏉冮檺閰嶇疆锛岃吘璁簯娌℃湁acl鏉冮檺閰嶇疆锛� + //.acl(getAccessPolicy().getObjectCannedACL()) + .build()) + .build()); + + // 灏嗚緭鍏ユ祦鍐欏叆璇锋眰浣� + body.writeInputStream(inputStream); + + // 绛夊緟鏂囦欢涓婁紶鎿嶄綔瀹屾垚 + CompletedUpload uploadResult = upload.completionFuture().join(); + String eTag = uploadResult.response().eTag(); + + // 鎻愬彇涓婁紶缁撴灉涓殑 ETag锛屽苟鏋勫缓涓�涓嚜瀹氫箟鐨� UploadResult 瀵硅薄 + return UploadResult.builder().url(getUrl() + StringUtils.SLASH + key).filename(key).eTag(eTag).build(); } catch (Exception e) { throw new OssException("涓婁紶鏂囦欢澶辫触锛岃妫�鏌ラ厤缃俊鎭�:[" + e.getMessage() + "]"); } - return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build(); } - public void delete(String path) { - path = path.replace(getUrl() + "/", ""); + /** + * 涓嬭浇鏂囦欢浠� Amazon S3 鍒颁复鏃剁洰褰� + * + * @param path 鏂囦欢鍦� Amazon S3 涓殑瀵硅薄閿� + * @return 涓嬭浇鍚庣殑鏂囦欢鍦ㄦ湰鍦扮殑涓存椂璺緞 + * @throws OssException 濡傛灉涓嬭浇澶辫触锛屾姏鍑鸿嚜瀹氫箟寮傚父 + */ + public Path fileDownload(String path) { + // 鏋勫缓涓存椂鏂囦欢 + Path tempFilePath = FileUtils.createTempFile().toPath(); + // 浣跨敤 S3TransferManager 涓嬭浇鏂囦欢 + FileDownload downloadFile = transferManager.downloadFile( + x -> x.getObjectRequest( + y -> y.bucket(properties.getBucketName()) + .key(removeBaseUrl(path)) + .build()) + .addTransferListener(LoggingTransferListener.create()) + .destination(tempFilePath) + .build()); + // 绛夊緟鏂囦欢涓嬭浇鎿嶄綔瀹屾垚 + downloadFile.completionFuture().join(); + return tempFilePath; + } + + /** + * 涓嬭浇鏂囦欢浠� Amazon S3 鍒� 杈撳嚭娴� + * + * @param key 鏂囦欢鍦� Amazon S3 涓殑瀵硅薄閿� + * @param out 杈撳嚭娴� + * @return 杈撳嚭娴佷腑鍐欏叆鐨勫瓧鑺傛暟锛堥暱搴︼級 + * @throws OssException 濡傛灉涓嬭浇澶辫触锛屾姏鍑鸿嚜瀹氫箟寮傚父 + */ + public long download(String key, OutputStream out) { try { - client.deleteObject(properties.getBucketName(), path); + // 鏋勫缓涓嬭浇璇锋眰 + DownloadRequest<ResponseInputStream<GetObjectResponse>> downloadRequest = DownloadRequest.builder() + // 鏂囦欢瀵硅薄 + .getObjectRequest(y -> y.bucket(properties.getBucketName()) + .key(key) + .build()) + .addTransferListener(LoggingTransferListener.create()) + // 浣跨敤璁㈤槄杞崲鍣� + .responseTransformer(AsyncResponseTransformer.toBlockingInputStream()) + .build(); + // 浣跨敤 S3TransferManager 涓嬭浇鏂囦欢 + Download<ResponseInputStream<GetObjectResponse>> responseFuture = transferManager.download(downloadRequest); + // 杈撳嚭鍒版祦涓� + try (ResponseInputStream<GetObjectResponse> responseStream = responseFuture.completionFuture().join().result()) { // auto-closeable stream + return responseStream.transferTo(out); // 闃诲璋冪敤绾跨▼ blocks the calling thread + } + } catch (Exception e) { + throw new OssException("鏂囦欢涓嬭浇澶辫触锛岄敊璇俊鎭�:[" + e.getMessage() + "]"); + } + } + + /** + * 鍒犻櫎浜戝瓨鍌ㄦ湇鍔′腑鎸囧畾璺緞涓嬫枃浠� + * + * @param path 鎸囧畾璺緞 + */ + public void delete(String path) { + try { + client.deleteObject( + x -> x.bucket(properties.getBucketName()) + .key(removeBaseUrl(path)) + .build()); } catch (Exception e) { throw new OssException("鍒犻櫎鏂囦欢澶辫触锛岃妫�鏌ラ厤缃俊鎭�:[" + e.getMessage() + "]"); } } - public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) { - return upload(data, getPath(properties.getPrefix(), suffix), contentType); - } - - public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) { - return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType); + /** + * 鑾峰彇绉佹湁URL閾炬帴 + * + * @param objectKey 瀵硅薄KEY + * @param expiredTime 閾炬帴鎺堟潈鍒版湡鏃堕棿 + */ + public String getPrivateUrl(String objectKey, Duration expiredTime) { + // 浣跨敤 AWS S3 棰勭鍚� URL 鐨勭敓鎴愬櫒 鑾峰彇瀵硅薄鐨勯绛惧悕 URL + URL url = presigner.presignGetObject( + x -> x.signatureDuration(expiredTime) + .getObjectRequest( + y -> y.bucket(properties.getBucketName()) + .key(objectKey) + .build()) + .build()) + .url(); + return url.toString(); } /** - * 鑾峰彇鏂囦欢鍏冩暟鎹� + * 涓婁紶 byte[] 鏁版嵁鍒� Amazon S3锛屼娇鐢ㄦ寚瀹氱殑鍚庣紑鏋勯�犲璞¢敭銆� + * + * @param data 瑕佷笂浼犵殑 byte[] 鏁版嵁 + * @param suffix 瀵硅薄閿殑鍚庣紑 + * @return UploadResult 鍖呭惈涓婁紶鍚庣殑鏂囦欢淇℃伅 + * @throws OssException 濡傛灉涓婁紶澶辫触锛屾姏鍑鸿嚜瀹氫箟寮傚父 + */ + public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) { + return upload(new ByteArrayInputStream(data), getPath(properties.getPrefix(), suffix), Long.valueOf(data.length), contentType); + } + + /** + * 涓婁紶 InputStream 鍒� Amazon S3锛屼娇鐢ㄦ寚瀹氱殑鍚庣紑鏋勯�犲璞¢敭銆� + * + * @param inputStream 瑕佷笂浼犵殑杈撳叆娴� + * @param suffix 瀵硅薄閿殑鍚庣紑 + * @param length 杈撳叆娴佺殑闀垮害 + * @return UploadResult 鍖呭惈涓婁紶鍚庣殑鏂囦欢淇℃伅 + * @throws OssException 濡傛灉涓婁紶澶辫触锛屾姏鍑鸿嚜瀹氫箟寮傚父 + */ + public UploadResult uploadSuffix(InputStream inputStream, String suffix, Long length, String contentType) { + return upload(inputStream, getPath(properties.getPrefix(), suffix), length, contentType); + } + + /** + * 涓婁紶鏂囦欢鍒� Amazon S3锛屼娇鐢ㄦ寚瀹氱殑鍚庣紑鏋勯�犲璞¢敭 + * + * @param file 瑕佷笂浼犵殑鏂囦欢 + * @param suffix 瀵硅薄閿殑鍚庣紑 + * @return UploadResult 鍖呭惈涓婁紶鍚庣殑鏂囦欢淇℃伅 + * @throws OssException 濡傛灉涓婁紶澶辫触锛屾姏鍑鸿嚜瀹氫箟寮傚父 + */ + public UploadResult uploadSuffix(File file, String suffix) { + return upload(file.toPath(), getPath(properties.getPrefix(), suffix), null, FileUtils.getMimeType(suffix)); + } + + /** + * 鑾峰彇鏂囦欢杈撳叆娴� * * @param path 瀹屾暣鏂囦欢璺緞 + * @return 杈撳叆娴� */ - public ObjectMetadata getObjectMetadata(String path) { - path = path.replace(getUrl() + "/", ""); - S3Object object = client.getObject(properties.getBucketName(), path); - return object.getObjectMetadata(); + public InputStream getObjectContent(String path) throws IOException { + // 涓嬭浇鏂囦欢鍒颁复鏃剁洰褰� + Path tempFilePath = fileDownload(path); + // 鍒涘缓杈撳叆娴� + InputStream inputStream = Files.newInputStream(tempFilePath); + // 鍒犻櫎涓存椂鏂囦欢 + FileUtils.del(tempFilePath); + // 杩斿洖瀵硅薄鍐呭鐨勮緭鍏ユ祦 + return inputStream; } - public InputStream getObjectContent(String path) { - path = path.replace(getUrl() + "/", ""); - S3Object object = client.getObject(properties.getBucketName(), path); - return object.getObjectContent(); + /** + * 鑾峰彇 S3 瀹㈡埛绔殑缁堢鐐� URL + * + * @return 缁堢鐐� URL + */ + public String getEndpoint() { + // 鏍规嵁閰嶇疆鏂囦欢涓殑鏄惁浣跨敤 HTTPS锛岃缃崗璁ご閮� + String header = getIsHttps(); + // 鎷兼帴鍗忚澶撮儴鍜岀粓绔偣锛屽緱鍒板畬鏁寸殑缁堢鐐� URL + return header + properties.getEndpoint(); } + /** + * 鑾峰彇 S3 瀹㈡埛绔殑缁堢鐐� URL锛堣嚜瀹氫箟鍩熷悕锛� + * + * @return 缁堢鐐� URL + */ + public String getDomain() { + // 浠庨厤缃腑鑾峰彇鍩熷悕銆佺粓绔偣銆佹槸鍚︿娇鐢� HTTPS 绛変俊鎭� + String domain = properties.getDomain(); + String endpoint = properties.getEndpoint(); + String header = getIsHttps(); + + // 濡傛灉鏄簯鏈嶅姟鍟嗭紝鐩存帴杩斿洖鍩熷悕鎴栫粓绔偣 + if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) { + return StringUtils.isNotEmpty(domain) ? header + domain : header + endpoint; + } + + // 濡傛灉鏄� MinIO锛屽鐞嗗煙鍚嶅苟杩斿洖 + if (StringUtils.isNotEmpty(domain)) { + return domain.startsWith(Constants.HTTPS) || domain.startsWith(Constants.HTTP) ? domain : header + domain; + } + + // 杩斿洖缁堢鐐� + return header + endpoint; + } + + /** + * 鏍规嵁浼犲叆鐨� region 鍙傛暟杩斿洖鐩稿簲鐨� AWS 鍖哄煙 + * 濡傛灉 region 鍙傛暟闈炵┖锛屼娇鐢� Region.of 鏂规硶鍒涘缓骞惰繑鍥炲搴旂殑 AWS 鍖哄煙瀵硅薄 + * 濡傛灉 region 鍙傛暟涓虹┖锛岃繑鍥炰竴涓粯璁ょ殑 AWS 鍖哄煙锛堜緥濡傦紝us-east-1锛夛紝浣滀负骞挎硾鏀寔鐨勫尯鍩� + * + * @return 瀵瑰簲鐨� AWS 鍖哄煙瀵硅薄锛屾垨鑰呴粯璁ょ殑骞挎硾鏀寔鐨勫尯鍩燂紙us-east-1锛� + */ + public Region of() { + //AWS 鍖哄煙瀛楃涓� + String region = properties.getRegion(); + // 濡傛灉 region 鍙傛暟闈炵┖锛屼娇鐢� Region.of 鏂规硶鍒涘缓瀵瑰簲鐨� AWS 鍖哄煙瀵硅薄锛屽惁鍒欒繑鍥為粯璁ゅ尯鍩� + return StringUtils.isNotEmpty(region) ? Region.of(region) : Region.US_EAST_1; + } + + /** + * 鑾峰彇浜戝瓨鍌ㄦ湇鍔$殑URL + * + * @return 鏂囦欢璺緞 + */ public String getUrl() { String domain = properties.getDomain(); String endpoint = properties.getEndpoint(); - String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://"; + String header = getIsHttps(); // 浜戞湇鍔″晢鐩存帴杩斿洖 if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) { - if (StringUtils.isNotBlank(domain)) { - return header + domain; - } - return header + properties.getBucketName() + "." + endpoint; + return header + (StringUtils.isNotEmpty(domain) ? domain : properties.getBucketName() + "." + endpoint); } - // minio 鍗曠嫭澶勭悊 - if (StringUtils.isNotBlank(domain)) { - return header + domain + "/" + properties.getBucketName(); + // MinIO 鍗曠嫭澶勭悊 + if (StringUtils.isNotEmpty(domain)) { + // 濡傛灉 domain 浠� "https://" 鎴� "http://" 寮�澶� + return (domain.startsWith(Constants.HTTPS) || domain.startsWith(Constants.HTTP)) ? + domain + StringUtils.SLASH + properties.getBucketName() : header + domain + StringUtils.SLASH + properties.getBucketName(); } - return header + endpoint + "/" + properties.getBucketName(); + return header + endpoint + StringUtils.SLASH + properties.getBucketName(); } + /** + * 鐢熸垚涓�涓鍚堢壒瀹氳鍒欑殑銆佸敮涓�鐨勬枃浠惰矾寰勩�傞�氳繃浣跨敤鏃ユ湡銆乁UID銆佸墠缂�鍜屽悗缂�绛夊厓绱犵殑缁勫悎锛岀‘淇濅簡鏂囦欢璺緞鐨勭嫭涓�鏃犱簩鎬� + * + * @param prefix 鍓嶇紑 + * @param suffix 鍚庣紑 + * @return 鏂囦欢璺緞 + */ public String getPath(String prefix, String suffix) { // 鐢熸垚uuid String uuid = IdUtil.fastSimpleUUID(); - // 鏂囦欢璺緞 - String path = DateUtils.datePath() + "/" + uuid; - if (StringUtils.isNotBlank(prefix)) { - path = prefix + "/" + path; - } + // 鐢熸垚鏃ユ湡璺緞 + String datePath = DateUtils.datePath(); + // 鎷兼帴璺緞 + String path = StringUtils.isNotEmpty(prefix) ? + prefix + StringUtils.SLASH + datePath + StringUtils.SLASH + uuid : datePath + StringUtils.SLASH + uuid; return path + suffix; } + /** + * 绉婚櫎璺緞涓殑鍩虹URL閮ㄥ垎锛屽緱鍒扮浉瀵硅矾寰� + * + * @param path 瀹屾暣鐨勮矾寰勶紝鍖呮嫭鍩虹URL鍜岀浉瀵硅矾寰� + * @return 鍘婚櫎鍩虹URL鍚庣殑鐩稿璺緞 + */ + public String removeBaseUrl(String path) { + return path.replace(getUrl() + StringUtils.SLASH, ""); + } + /** + * 鏈嶅姟鍟� + */ public String getConfigKey() { return configKey; } /** - * 鑾峰彇绉佹湁URL閾炬帴 + * 鑾峰彇鏄惁浣跨敤 HTTPS 鐨勯厤缃紝骞惰繑鍥炵浉搴旂殑鍗忚澶撮儴銆� * - * @param objectKey 瀵硅薄KEY - * @param second 鎺堟潈鏃堕棿 + * @return 鍗忚澶撮儴锛屾牴鎹槸鍚︿娇鐢� HTTPS 杩斿洖 "https://" 鎴� "http://" */ - public String getPrivateUrl(String objectKey, Integer second) { - GeneratePresignedUrlRequest generatePresignedUrlRequest = - new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey) - .withMethod(HttpMethod.GET) - .withExpiration(new Date(System.currentTimeMillis() + 1000L * second)); - URL url = client.generatePresignedUrl(generatePresignedUrlRequest); - return url.toString(); + public String getIsHttps() { + return OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? Constants.HTTPS : Constants.HTTP; } /** @@ -212,34 +485,6 @@ */ public AccessPolicyType getAccessPolicy() { return AccessPolicyType.getByType(properties.getAccessPolicy()); - } - - private static String getPolicy(String bucketName, PolicyType policyType) { - StringBuilder builder = new StringBuilder(); - builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n"); - builder.append(switch (policyType) { - case WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n"; - case READ_WRITE -> "\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n"; - default -> "\"s3:GetBucketLocation\"\n"; - }); - builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); - builder.append(bucketName); - builder.append("\"\n},\n"); - if (policyType == PolicyType.READ) { - builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); - builder.append(bucketName); - builder.append("\"\n},\n"); - } - builder.append("{\n\"Action\": "); - builder.append(switch (policyType) { - case WRITE -> "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n"; - case READ_WRITE -> "[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n"; - default -> "\"s3:GetObject\",\n"; - }); - builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); - builder.append(bucketName); - builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n"); - return builder.toString(); } } -- Gitblit v1.9.3