Skip to content

Commit 13a5f2f

Browse files
author
jeffreykzli
committed
preflight
1 parent 0812f94 commit 13a5f2f

File tree

4 files changed

+74
-0
lines changed

4 files changed

+74
-0
lines changed

src/main/java/com/qcloud/cos/COSClient.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import java.util.Map;
4040
import java.util.Map.Entry;
4141
import java.util.Objects;
42+
import java.util.concurrent.ConcurrentHashMap;
4243

4344
import com.fasterxml.jackson.core.Version;
4445
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -165,6 +166,8 @@ public class COSClient implements COS {
165166

166167
private CosHttpClient cosHttpClient;
167168

169+
private ConcurrentHashMap<String, Long> preflightBuckets = new ConcurrentHashMap<>();
170+
168171
public COSClient(COSCredentials cred, ClientConfig clientConfig) {
169172
this(new COSStaticCredentialsProvider(cred), clientConfig);
170173
}
@@ -840,6 +843,17 @@ ObjectMetadata uploadObjectInternal(UploadMode uploadMode, UploadObjectRequest u
840843
rejectNull(bucketName,
841844
"The bucket name parameter must be specified when uploading an object");
842845
rejectNull(key, "The key parameter must be specified when uploading an object");
846+
847+
try {
848+
preflightObj(bucketName, key);
849+
} catch (CosServiceException cse) {
850+
log.warn("fail to do the preflight request due to the service exception, will not do the upload obj request", cse);
851+
throw cse;
852+
} catch (CosClientException cce) {
853+
log.warn("fail to do the preflight request due to the client exception, will not do the upload obj request", cce);
854+
throw cce;
855+
}
856+
843857
// If a file is specified for upload, we need to pull some additional
844858
// information from it to auto-configure a few options
845859
if (file == null) {
@@ -979,6 +993,22 @@ ObjectMetadata uploadObjectInternal(UploadMode uploadMode, UploadObjectRequest u
979993
CosDataSource.Utils.cleanupDataSource(uploadObjectRequest, file, isOrig, input, log);
980994
}
981995

996+
if (returnedMetadata.isNeedPreflight()) {
997+
Long currentTime = System.currentTimeMillis();
998+
if ((preflightBuckets.get(bucketName) == null) || ((currentTime - preflightBuckets.get(bucketName)) > clientConfig.getPreflightStatusUpdateInterval())) {
999+
String reqMsg = String.format("will update preflight status, bucket[%s]",bucketName);
1000+
log.info(reqMsg);
1001+
preflightBuckets.put(bucketName, currentTime);
1002+
}
1003+
} else {
1004+
Long currentTime = System.currentTimeMillis();
1005+
if ((preflightBuckets.get(bucketName) != null) && ((currentTime - preflightBuckets.get(bucketName)) > clientConfig.getPreflightStatusUpdateInterval())) {
1006+
String reqMsg = String.format("will remove bucket[%s] from preflight lists",bucketName);
1007+
log.info(reqMsg);
1008+
preflightBuckets.remove(bucketName);
1009+
}
1010+
}
1011+
9821012
String contentMd5 = metadata.getContentMD5();
9831013
if (md5DigestStream != null) {
9841014
contentMd5 = Base64.encodeAsString(md5DigestStream.getMd5Digest());
@@ -5475,5 +5505,22 @@ public BucketGetMetadataResult getBucketMetadata(String bucketName) throws CosCl
54755505

54765506
return result;
54775507
}
5508+
5509+
private void preflightObj(String bucketName, String key) throws CosClientException, CosServiceException {
5510+
rejectEmpty(bucketName,
5511+
"The bucket name parameter must be specified when doing preflight request");
5512+
rejectEmpty(key,
5513+
"The key parameter must be specified when doing preflight request");
5514+
if (clientConfig.isCheckPreflightStatus() && preflightBuckets.containsKey(bucketName)) {
5515+
String reqMsg = String.format("will do preflight request for put object[%s] to the bucket[%s]", key, bucketName);
5516+
log.debug(reqMsg);
5517+
CosServiceRequest serviceRequest = new CosServiceRequest();
5518+
CosHttpRequest<CosServiceRequest> request = createRequest(bucketName, key, serviceRequest, HttpMethodName.HEAD);
5519+
request.addParameter("preflight", null);
5520+
request.addHeader("x-cos-next-action", "PutObject");
5521+
5522+
invoke(request, voidCosResponseHandler);
5523+
}
5524+
}
54785525
}
54795526

src/main/java/com/qcloud/cos/ClientConfig.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ public class ClientConfig {
127127

128128
private boolean isRefreshEndpointAddr = false;
129129

130+
private boolean checkPreflightStatus = false;
131+
132+
private long preflightStatusUpdateInterval = 10 * 1000L;
133+
130134
// 不传入region 用于后续调用List Buckets(获取所有的bucket信息)
131135
public ClientConfig() {
132136
super();
@@ -451,4 +455,16 @@ public void turnOnRefreshEndpointAddrSwitch() {
451455
public boolean IsRefreshEndpointAddr() {
452456
return isRefreshEndpointAddr;
453457
}
458+
459+
public boolean isCheckPreflightStatus() {
460+
return checkPreflightStatus;
461+
}
462+
463+
public void setCheckPreflightStatus(boolean checkPreflightStatus) {
464+
this.checkPreflightStatus = checkPreflightStatus;
465+
}
466+
467+
public long getPreflightStatusUpdateInterval() {
468+
return preflightStatusUpdateInterval;
469+
}
454470
}

src/main/java/com/qcloud/cos/model/ObjectMetadata.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,4 +830,12 @@ public CIUploadResult getCiUploadResult() {
830830
public void setCiUploadResult(CIUploadResult ciUploadResult) {
831831
this.ciUploadResult = ciUploadResult;
832832
}
833+
834+
public boolean isNeedPreflight() {
835+
if (metadata.containsKey("x-cos-preflight")) {
836+
String preflightStatus = (String)metadata.get("x-cos-preflight");
837+
return preflightStatus.equalsIgnoreCase("true");
838+
}
839+
return false;
840+
}
833841
}

src/main/java/com/qcloud/cos/retry/PredefinedRetryPolicies.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ public <X extends CosServiceRequest> boolean shouldRetry(CosHttpRequest<X> reque
6060
Exception exception,
6161
int retryIndex) {
6262
if (RetryUtils.isRetryableServiceException(exception)) {
63+
if (request.getParameters().containsKey("preflight")) {
64+
return false;
65+
}
6366
return true;
6467
}
6568

0 commit comments

Comments
 (0)