Skip to content

Commit 15f3848

Browse files
author
jordanqin
committed
update qcloud sdk to 5.9.29
1 parent 1dbba2d commit 15f3848

File tree

10 files changed

+310
-6
lines changed

10 files changed

+310
-6
lines changed

QCloudCosXml/cos-android-base/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ android {
66
minSdkVersion 15
77
targetSdkVersion 28
88

9-
versionCode 50926
10-
versionName '5.9.26'
9+
versionCode 50927
10+
versionName '5.9.27'
1111

1212
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
1313

QCloudCosXml/cos-android-base/src/main/java/com/tencent/cos/xml/BaseCosXml.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.tencent.cos.xml.model.CosXmlRequest;
2929
import com.tencent.cos.xml.model.object.BasePutObjectRequest;
3030
import com.tencent.cos.xml.model.object.BasePutObjectResult;
31+
import com.tencent.cos.xml.model.object.GetObjectBytesRequest;
3132
import com.tencent.cos.xml.model.object.GetObjectRequest;
3233
import com.tencent.cos.xml.model.object.GetObjectResult;
3334
import com.tencent.cos.xml.model.object.UploadPartRequest;
@@ -113,6 +114,22 @@ public interface BaseCosXml {
113114
*/
114115
byte[] getObject(String bucketName, String objectName) throws CosXmlClientException, CosXmlServiceException;
115116

117+
/**
118+
* <p>
119+
* 下载 COS 对象到字节数组的同步方法<br>
120+
* 和{@link #getObject(GetObjectRequest)}类似,只是返回结果形式不同
121+
* </p>
122+
* <p>
123+
* 注意:请不要通过本接口下载大文件,否则容易造成内存溢出。
124+
* </p>
125+
*
126+
* @param request 获取 COS 对象的请求 {@link GetObjectBytesRequest}
127+
* @return 对象的字节数据
128+
* @throws CosXmlClientException 客户端异常
129+
* @throws CosXmlServiceException 服务端异常
130+
*/
131+
byte[] getObject(GetObjectBytesRequest request) throws CosXmlClientException, CosXmlServiceException;
132+
116133
/**
117134
* <p>
118135
* 基础简单上传的同步方法.&nbsp;

QCloudCosXml/cos-android-base/src/main/java/com/tencent/cos/xml/CosXmlBaseService.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,18 @@ public byte[] getObject(String bucketName, String objectName) throws CosXmlClien
657657
return getObjectBytesResult != null ? getObjectBytesResult.data : new byte[0];
658658
}
659659

660+
/**
661+
* <p>
662+
* 将 COS 对象下载为字节数组
663+
* <p>
664+
* 详细介绍,请查看:{@link BaseCosXml#getObject(GetObjectBytesRequest)}
665+
*/
666+
@Override
667+
public byte[] getObject(GetObjectBytesRequest request) throws CosXmlClientException, CosXmlServiceException {
668+
GetObjectBytesResult getObjectBytesResult = execute(request, new GetObjectBytesResult());
669+
return getObjectBytesResult != null ? getObjectBytesResult.data : new byte[0];
670+
}
671+
660672
/**
661673
* <p>
662674
* 基础简单上传的同步方法.&nbsp;

QCloudCosXml/cos-android-base/src/main/java/com/tencent/cos/xml/model/object/GetObjectBytesRequest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,34 @@
2222

2323
package com.tencent.cos.xml.model.object;
2424

25+
import android.util.Log;
26+
2527
import com.tencent.cos.xml.BaseCosXml;
28+
import com.tencent.cos.xml.common.ClientErrorCode;
2629
import com.tencent.cos.xml.common.RequestMethod;
2730
import com.tencent.cos.xml.exception.CosXmlClientException;
2831
import com.tencent.qcloud.core.http.RequestBodySerializer;
2932

3033
import org.xmlpull.v1.XmlPullParserException;
3134

35+
import java.io.File;
3236
import java.io.IOException;
3337

3438
/**
3539
* 下载 COS 对象到字节数组的请求.
3640
* @see BaseCosXml#getObject(String, String)
3741
*/
3842
final public class GetObjectBytesRequest extends ObjectRequest {
43+
private boolean objectKeySimplifyCheck = true;
44+
45+
/**
46+
* 设置是否校验cosPath归并后是否符合规范,默认为true
47+
* @param objectKeySimplifyCheck 是否校验cosPath归并后是否符合规范
48+
*/
49+
public void setObjectKeySimplifyCheck(boolean objectKeySimplifyCheck) {
50+
this.objectKeySimplifyCheck = objectKeySimplifyCheck;
51+
}
52+
3953
public GetObjectBytesRequest(String bucket, String cosPath) {
4054
super(bucket, cosPath);
4155
}
@@ -49,4 +63,20 @@ public String getMethod() {
4963
protected RequestBodySerializer xmlBuilder() throws XmlPullParserException, IOException {
5064
return null;
5165
}
66+
67+
@Override
68+
public void checkParameters() throws CosXmlClientException {
69+
super.checkParameters();
70+
71+
if(objectKeySimplifyCheck) {
72+
String normalizedPath = cosPath;
73+
try {
74+
File file = new File("/" + cosPath);
75+
normalizedPath = file.getCanonicalPath();
76+
} catch (IOException e) {e.printStackTrace();}
77+
if ("/".equals(normalizedPath)) {
78+
throw new CosXmlClientException(ClientErrorCode.INVALID_ARGUMENT.getCode(), "The key in the getobject is illegal");
79+
}
80+
}
81+
}
5282
}

QCloudCosXml/cos-android-base/src/main/java/com/tencent/cos/xml/model/object/GetObjectRequest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626

2727
import com.tencent.cos.xml.BaseCosXml;
2828
import com.tencent.cos.xml.common.COSRequestHeaderKey;
29+
import com.tencent.cos.xml.common.ClientErrorCode;
2930
import com.tencent.cos.xml.common.Range;
3031
import com.tencent.cos.xml.common.RequestMethod;
32+
import com.tencent.cos.xml.exception.CosXmlClientException;
3133
import com.tencent.cos.xml.listener.CosXmlProgressListener;
3234
import com.tencent.cos.xml.listener.CosXmlResultListener;
3335
import com.tencent.qcloud.core.http.RequestBodySerializer;
@@ -61,6 +63,8 @@ public class GetObjectRequest extends ObjectRequest implements TransferRequest {
6163

6264
private Uri fileContentUri;
6365

66+
private boolean objectKeySimplifyCheck = true;
67+
6468
/**
6569
* GetObjectRequest 构造函数
6670
* @param bucket 存储桶名称(cos v5 的 bucket格式为:xxx-appid, 如 bucket-1250000000)
@@ -317,6 +321,18 @@ public String getSaveFileName() {
317321
return saveFileName;
318322
}
319323

324+
/**
325+
* 设置是否校验cosPath归并后是否符合规范,默认为true
326+
* @param objectKeySimplifyCheck 是否校验cosPath归并后是否符合规范
327+
*/
328+
public void setObjectKeySimplifyCheck(boolean objectKeySimplifyCheck) {
329+
this.objectKeySimplifyCheck = objectKeySimplifyCheck;
330+
}
331+
332+
public boolean isObjectKeySimplifyCheck() {
333+
return objectKeySimplifyCheck;
334+
}
335+
320336
public String getDownloadPath(){
321337
String path = null;
322338
if(savePath != null){
@@ -389,4 +405,20 @@ protected RequestBodySerializer xmlBuilder() throws XmlPullParserException, IOEx
389405
public void setTrafficLimit(long limit) {
390406
addHeader("x-cos-traffic-limit", String.valueOf(limit));
391407
}
408+
409+
@Override
410+
public void checkParameters() throws CosXmlClientException {
411+
super.checkParameters();
412+
413+
if(objectKeySimplifyCheck) {
414+
String normalizedPath = cosPath;
415+
try {
416+
File file = new File("/" + cosPath);
417+
normalizedPath = file.getCanonicalPath();
418+
} catch (IOException e) {e.printStackTrace();}
419+
if ("/".equals(normalizedPath)) {
420+
throw new CosXmlClientException(ClientErrorCode.INVALID_ARGUMENT.getCode(), "The key in the getobject is illegal");
421+
}
422+
}
423+
}
392424
}

QCloudCosXml/cos-android/src/androidTest/java/com/tencent/cos/xml/core/TestConst.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class TestConst {
1919
public static final String PERSIST_BUCKET_REGION = BuildConfig.PERSIST_BUCKET_REGION;
2020
public static final String PERSIST_BUCKET = BuildConfig.PERSIST_BUCKET;
2121
public static final String PERSIST_BUCKET_CDN_SIGN = BuildConfig.PERSIST_BUCKET_CDN_SIGN;
22+
public static final String PERSIST_BUCKET_ROOT_FILE_PATH = "do_not_remove";
2223
public static final String PERSIST_BUCKET_PIC_PATH = "do_not_remove/image.png";
2324
public static final String PERSIST_BUCKET_PIC_6M_PATH = "do_not_remove/6m.jpg";
2425
public static final String PERSIST_BUCKET_QR_PATH = "do_not_remove/qr.png";
@@ -103,5 +104,5 @@ public class TestConst {
103104
public static final String CALLBACK_SECRET_ID = BuildConfig.CALLBACK_SECRET_ID;
104105
public static final String CALLBACK_SECRET_KEY = BuildConfig.CALLBACK_SECRET_KEY;
105106
public static final String CALLBACK_PERSIST_BUCKET_REGION = "ap-shanghai";
106-
public static final String CALLBACK_PERSIST_BUCKET = "test-callback-1251668577";
107+
public static final String CALLBACK_PERSIST_BUCKET = "test-callback-1252246555";
107108
}

QCloudCosXml/cos-android/src/androidTest/java/com/tencent/cos/xml/transfer/DownloadTest.java

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.tencent.cos.xml.listener.CosXmlResultListener;
4141
import com.tencent.cos.xml.model.CosXmlRequest;
4242
import com.tencent.cos.xml.model.CosXmlResult;
43+
import com.tencent.cos.xml.model.object.GetObjectBytesRequest;
4344
import com.tencent.cos.xml.model.object.GetObjectRequest;
4445
import com.tencent.qcloud.core.http.HttpTaskMetrics;
4546
import com.tencent.qcloud.core.logger.QCloudLogger;
@@ -476,4 +477,195 @@ public void onFail(CosXmlRequest request, @Nullable CosXmlClientException client
476477
}
477478
Assert.assertTrue(true);
478479
}
480+
481+
@Test public void testDownloadPath() {
482+
testDownloadBtPath("/", true, true);
483+
testDownloadBtPath("///////", true, true);
484+
testDownloadBtPath("/abc/../", true, true);
485+
testDownloadBtPath("/./", true, true);
486+
testDownloadBtPath("///abc/.//def//../../", true, true);
487+
testDownloadBtPath("/././///abc/.//def//../../", true, true);
488+
testDownloadBtPath(TestConst.PERSIST_BUCKET_ROOT_FILE_PATH, false, true);
489+
testDownloadBtPath(TestConst.PERSIST_BUCKET_PIC_PATH, false, true);
490+
testDownloadBtPath("/"+TestConst.PERSIST_BUCKET_PIC_PATH, false, true);
491+
testDownloadBtPath("do_not_remove/", false, true);
492+
testDownloadBtPath("/do_not_remove/", false, true);
493+
494+
testDownloadBtPath("/", true, false);
495+
testDownloadBtPath("///////", true, false);
496+
testDownloadBtPath("/abc/../", true, false);
497+
testDownloadBtPath("/./", true, false);
498+
testDownloadBtPath("///abc/.//def//../../", true, false);
499+
testDownloadBtPath("/././///abc/.//def//../../", true, false);
500+
testDownloadBtPath(TestConst.PERSIST_BUCKET_ROOT_FILE_PATH, false, false);
501+
testDownloadBtPath(TestConst.PERSIST_BUCKET_PIC_PATH, false, false);
502+
testDownloadBtPath("/"+TestConst.PERSIST_BUCKET_PIC_PATH, false, false);
503+
testDownloadBtPath("do_not_remove/", false, false);
504+
testDownloadBtPath("/do_not_remove/", false, false);
505+
506+
// 为了覆盖getCanonicalPath()的IOException
507+
testDownloadBtPath("\u0000", true, true);
508+
509+
Assert.assertTrue(true);
510+
}
511+
512+
private void testDownloadBtPath(String cosPath, boolean isFail, boolean isObjectKeySimplifyCheck){
513+
try {
514+
TransferManager transferManager = ServiceFactory.INSTANCE.newDefaultTransferManager();
515+
516+
GetObjectRequest getObjectRequest = new GetObjectRequest(TestConst.PERSIST_BUCKET,
517+
cosPath,
518+
TestUtils.localParentPath(), "test");
519+
getObjectRequest.setObjectKeySimplifyCheck(isObjectKeySimplifyCheck);
520+
521+
COSXMLDownloadTask downloadTask = transferManager.download(TestUtils.getContext(),
522+
getObjectRequest);
523+
final TestLocker testLocker = new TestLocker();
524+
downloadTask.setCosXmlResultListener(new CosXmlResultListener() {
525+
@Override
526+
public void onSuccess(CosXmlRequest request, CosXmlResult result) {
527+
testLocker.release();
528+
}
529+
530+
@Override
531+
public void onFail(CosXmlRequest request, CosXmlClientException clientException, CosXmlServiceException serviceException) {
532+
String error = TestUtils.getCosExceptionMessage(clientException, serviceException);
533+
TestUtils.printError(error);
534+
if(serviceException != null){
535+
// 如果开启校验且应该校验失败 就不应该走到服务端,其他情况不关注后端错误
536+
if(isObjectKeySimplifyCheck && isFail){
537+
Assert.fail(error);
538+
}
539+
}
540+
if(clientException != null){
541+
if(isFail) {
542+
if (!"The key in the getobject is illegal".equals(clientException.getMessage())) {
543+
Assert.fail(clientException.getMessage());
544+
} else {
545+
if(!isObjectKeySimplifyCheck){
546+
Assert.fail(clientException.getMessage());
547+
}
548+
}
549+
} else {
550+
Assert.fail(clientException.getMessage());
551+
}
552+
}
553+
testLocker.release();
554+
}
555+
});
556+
testLocker.lock();
557+
} catch (Exception e){
558+
e.printStackTrace();
559+
}
560+
}
561+
562+
@Test public void testGetObjectPath() {
563+
getObjectByPath("/", true, true);
564+
getObjectByPath("///////", true, true);
565+
getObjectByPath("/abc/../", true, true);
566+
getObjectByPath("/./", true, true);
567+
getObjectByPath("///abc/.//def//../../", true, true);
568+
getObjectByPath("/././///abc/.//def//../../", true, true);
569+
getObjectByPath(TestConst.PERSIST_BUCKET_ROOT_FILE_PATH, false, true);
570+
getObjectByPath(TestConst.PERSIST_BUCKET_PIC_PATH, false, true);
571+
getObjectByPath("/"+TestConst.PERSIST_BUCKET_PIC_PATH, false, true);
572+
getObjectByPath("do_not_remove/", false, true);
573+
getObjectByPath("/do_not_remove/", false, true);
574+
575+
getObjectByPath("/", true, false);
576+
getObjectByPath("///////", true, false);
577+
getObjectByPath("/abc/../", true, false);
578+
getObjectByPath("/./", true, false);
579+
getObjectByPath("///abc/.//def//../../", true, false);
580+
getObjectByPath("/././///abc/.//def//../../", true, false);
581+
getObjectByPath(TestConst.PERSIST_BUCKET_ROOT_FILE_PATH, false, false);
582+
getObjectByPath(TestConst.PERSIST_BUCKET_PIC_PATH, false, false);
583+
getObjectByPath("/"+TestConst.PERSIST_BUCKET_PIC_PATH, false, false);
584+
getObjectByPath("do_not_remove/", false, false);
585+
getObjectByPath("/do_not_remove/", false, false);
586+
587+
Assert.assertTrue(true);
588+
}
589+
private void getObjectByPath(String cosPath, boolean isFail, boolean isObjectKeySimplifyCheck) {
590+
CosXmlSimpleService cosXmlSimpleService = ServiceFactory.INSTANCE.newDefaultService();
591+
GetObjectRequest getObjectRequest = new GetObjectRequest(TestConst.PERSIST_BUCKET,
592+
cosPath,
593+
TestUtils.localParentPath(), "test");
594+
getObjectRequest.setObjectKeySimplifyCheck(isObjectKeySimplifyCheck);
595+
try {
596+
cosXmlSimpleService.getObject(getObjectRequest);
597+
} catch (CosXmlClientException e) {
598+
TestUtils.printError(e.getMessage());
599+
if(isFail) {
600+
if (!"The key in the getobject is illegal".equals(e.getMessage())) {
601+
Assert.fail(e.getMessage());
602+
} else {
603+
if(!isObjectKeySimplifyCheck){
604+
Assert.fail(e.getMessage());
605+
}
606+
}
607+
} else {
608+
Assert.fail(e.getMessage());
609+
}
610+
} catch (CosXmlServiceException e) {
611+
// 如果开启校验且应该校验失败 就不应该走到服务端,其他情况不关注后端错误
612+
if(isObjectKeySimplifyCheck && isFail){
613+
Assert.fail(e.getMessage());
614+
}
615+
}
616+
}
617+
618+
@Test public void testGetObjectBytesPath() {
619+
getObjectBytesByPath("/", true, true);
620+
getObjectBytesByPath("///////", true, true);
621+
getObjectBytesByPath("/abc/../", true, true);
622+
getObjectBytesByPath("/./", true, true);
623+
getObjectBytesByPath("///abc/.//def//../../", true, true);
624+
getObjectBytesByPath("/././///abc/.//def//../../", true, true);
625+
getObjectBytesByPath(TestConst.PERSIST_BUCKET_ROOT_FILE_PATH, false, true);
626+
getObjectBytesByPath(TestConst.PERSIST_BUCKET_PIC_PATH, false, true);
627+
getObjectBytesByPath("/"+TestConst.PERSIST_BUCKET_PIC_PATH, false, true);
628+
getObjectBytesByPath("do_not_remove/", false, true);
629+
getObjectBytesByPath("/do_not_remove/", false, true);
630+
631+
getObjectBytesByPath("/", true, false);
632+
getObjectBytesByPath("///////", true, false);
633+
getObjectBytesByPath("/abc/../", true, false);
634+
getObjectBytesByPath("/./", true, false);
635+
getObjectBytesByPath("///abc/.//def//../../", true, false);
636+
getObjectBytesByPath("/././///abc/.//def//../../", true, false);
637+
getObjectBytesByPath(TestConst.PERSIST_BUCKET_ROOT_FILE_PATH, false, false);
638+
getObjectBytesByPath(TestConst.PERSIST_BUCKET_PIC_PATH, false, false);
639+
getObjectBytesByPath("/"+TestConst.PERSIST_BUCKET_PIC_PATH, false, false);
640+
getObjectBytesByPath("do_not_remove/", false, false);
641+
getObjectBytesByPath("/do_not_remove/", false, false);
642+
643+
Assert.assertTrue(true);
644+
}
645+
private void getObjectBytesByPath(String cosPath, boolean isFail, boolean isObjectKeySimplifyCheck) {
646+
CosXmlSimpleService cosXmlSimpleService = ServiceFactory.INSTANCE.newDefaultService();
647+
GetObjectBytesRequest getObjectBytesRequest = new GetObjectBytesRequest(TestConst.PERSIST_BUCKET, cosPath);
648+
getObjectBytesRequest.setObjectKeySimplifyCheck(isObjectKeySimplifyCheck);
649+
try {
650+
cosXmlSimpleService.getObject(getObjectBytesRequest);
651+
} catch (CosXmlClientException e) {
652+
TestUtils.printError(e.getMessage());
653+
if(isFail) {
654+
if (!"The key in the getobject is illegal".equals(e.getMessage())) {
655+
Assert.fail(e.getMessage());
656+
} else {
657+
if(!isObjectKeySimplifyCheck){
658+
Assert.fail(e.getMessage());
659+
}
660+
}
661+
} else {
662+
Assert.fail(e.getMessage());
663+
}
664+
} catch (CosXmlServiceException e) {
665+
// 如果开启校验且应该校验失败 就不应该走到服务端,其他情况不关注后端错误
666+
if(isObjectKeySimplifyCheck && isFail){
667+
Assert.fail(e.getMessage());
668+
}
669+
}
670+
}
479671
}

0 commit comments

Comments
 (0)