Skip to content

Commit 4bcc9b0

Browse files
harshavardhanabalamurugana
authored andcommitted
api: Enhance presignedGetObject API to support request params. (#488)
This is needed in cases when certain types of responses are expected for a GET on presigned requests. Supports response header overrides for [ response-expires, response-content-type, response-cache-control, response-content-disposition ]
1 parent e84187b commit 4bcc9b0

File tree

2 files changed

+100
-6
lines changed

2 files changed

+100
-6
lines changed

api/src/main/java/io/minio/MinioClient.java

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,15 +1355,17 @@ public void getObject(String bucketName, String objectName, String fileName)
13551355

13561356

13571357
/**
1358-
* Returns an presigned URL to download the object in the bucket with given expiry time.
1358+
* Returns an presigned URL to download the object in the bucket with given expiry time with custom request params.
13591359
*
13601360
* </p><b>Example:</b><br>
1361-
* <pre>{@code String url = minioClient.presignedGetObject("my-bucketname", "my-objectname", 60 * 60 * 24);
1361+
* <pre>{@code String url = minioClient.presignedGetObject("my-bucketname", "my-objectname", 60 * 60 * 24, reqParams);
13621362
* System.out.println(url); }</pre>
13631363
*
13641364
* @param bucketName Bucket name.
13651365
* @param objectName Object name in the bucket.
13661366
* @param expires Expiration time in seconds of presigned URL.
1367+
* @param reqParams Override values for set of response headers. Currently supported request parameters are
1368+
* [response-expires, response-content-type, response-cache-control, response-content-disposition]
13671369
*
13681370
* @return string contains URL to download the object.
13691371
*
@@ -1373,7 +1375,8 @@ public void getObject(String bucketName, String objectName, String fileName)
13731375
* @throws NoSuchAlgorithmException upon requested algorithm was not found during signature calculation
13741376
* @throws InvalidExpiresRangeException upon input expires is out of range
13751377
*/
1376-
public String presignedGetObject(String bucketName, String objectName, Integer expires)
1378+
public String presignedGetObject(String bucketName, String objectName, Integer expires,
1379+
Map<String, String> reqParams)
13771380
throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException,
13781381
InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException,
13791382
InternalException, InvalidExpiresRangeException {
@@ -1386,11 +1389,37 @@ public String presignedGetObject(String bucketName, String objectName, Integer e
13861389
String region = BucketRegionCache.INSTANCE.region(bucketName);
13871390

13881391
Request request = createRequest(Method.GET, bucketName, objectName, region,
1389-
null, null, null, null, 0);
1392+
null, reqParams, null, null, 0);
13901393
HttpUrl url = Signer.presignV4(request, region, accessKey, secretKey, expires);
13911394
return url.toString();
13921395
}
13931396

1397+
/**
1398+
* Returns an presigned URL to download the object in the bucket with given expiry time.
1399+
*
1400+
* </p><b>Example:</b><br>
1401+
* <pre>{@code String url = minioClient.presignedGetObject("my-bucketname", "my-objectname", 60 * 60 * 24);
1402+
* System.out.println(url); }</pre>
1403+
*
1404+
* @param bucketName Bucket name.
1405+
* @param objectName Object name in the bucket.
1406+
* @param expires Expiration time in seconds of presigned URL.
1407+
*
1408+
* @return string contains URL to download the object.
1409+
*
1410+
* @throws InvalidBucketNameException upon an invalid bucket name
1411+
* @throws InvalidKeyException upon an invalid access key or secret key
1412+
* @throws IOException upon signature calculation failure
1413+
* @throws NoSuchAlgorithmException upon requested algorithm was not found during signature calculation
1414+
* @throws InvalidExpiresRangeException upon input expires is out of range
1415+
*/
1416+
public String presignedGetObject(String bucketName, String objectName, Integer expires)
1417+
throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException,
1418+
InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException,
1419+
InternalException, InvalidExpiresRangeException {
1420+
return presignedGetObject(bucketName, objectName, expires, null);
1421+
}
1422+
13941423

13951424
/**
13961425
* Returns an presigned URL to download the object in the bucket with default expiry time.
@@ -1413,7 +1442,7 @@ public String presignedGetObject(String bucketName, String objectName)
14131442
throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException,
14141443
InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException,
14151444
InternalException, InvalidExpiresRangeException {
1416-
return presignedGetObject(bucketName, objectName, DEFAULT_EXPIRY_TIME);
1445+
return presignedGetObject(bucketName, objectName, DEFAULT_EXPIRY_TIME, null);
14171446
}
14181447

14191448

functional/FunctionalTest.java

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public static void removeBucket_test() throws Exception {
141141
}
142142

143143
/**
144-
* Tear down test setup.
144+
* Tear down test setup.
145145
*/
146146
public static void setup() throws Exception {
147147
client.makeBucket(bucketName);
@@ -595,6 +595,70 @@ public static void presignedGetObject_test2() throws Exception {
595595
client.removeObject(bucketName, fileName);
596596
}
597597

598+
/**
599+
* public String presignedGetObject(String bucketName, String objectName, Integer expires, Map reqParams).
600+
*/
601+
public static void presignedGetObject_test3() throws Exception {
602+
System.out.println("Test: presignedGetObject(String bucketName, String objectName, Integer expires, "
603+
+ "Map<String, String> reqParams)");
604+
String fileName = createFile(3 * MB);
605+
client.putObject(bucketName, fileName, fileName);
606+
607+
Map<String, String> reqParams = new HashMap<>();
608+
reqParams.put("response-content-type", "application/json");
609+
610+
String urlString = client.presignedGetObject(bucketName, fileName, 3600, reqParams);
611+
Request.Builder requestBuilder = new Request.Builder();
612+
Request request = requestBuilder
613+
.url(HttpUrl.parse(urlString))
614+
.method("GET", null)
615+
.build();
616+
OkHttpClient transport = new OkHttpClient();
617+
Response response = transport.newCall(request).execute();
618+
619+
if (response != null) {
620+
if (response.isSuccessful()) {
621+
OutputStream os = Files.newOutputStream(Paths.get(fileName + ".downloaded"), StandardOpenOption.CREATE);
622+
ByteStreams.copy(response.body().byteStream(), os);
623+
if (!response.header("Content-Type").equals("application/json")) {
624+
throw new Exception("[FAILED] Test: presignedGetObject(String bucketName, String objectName,"
625+
+ " Integer expires, Map<String, String> reqParams)"
626+
+ ", Response: " + response);
627+
}
628+
response.body().close();
629+
os.close();
630+
} else {
631+
String errorXml = "";
632+
633+
// read entire body stream to string.
634+
Scanner scanner = new java.util.Scanner(response.body().charStream()).useDelimiter("\\A");
635+
if (scanner.hasNext()) {
636+
errorXml = scanner.next();
637+
}
638+
639+
throw new Exception("[FAILED] Test: presignedGetObject(String bucketName, String objectName,"
640+
+ " Integer expires, Map<String, String> reqParams)"
641+
+ ", Response: " + response
642+
+ ", Error: " + errorXml);
643+
}
644+
} else {
645+
throw new Exception("[FAILED] Test: presignedGetObject(String bucketName, String objectName,"
646+
+ " Integer expires, Map<String, String> reqParams)"
647+
+ ", Error: <No response from server>");
648+
}
649+
650+
if (!Arrays.equals(Files.readAllBytes(Paths.get(fileName)),
651+
Files.readAllBytes(Paths.get(fileName + ".downloaded")))) {
652+
throw new Exception("[FAILED] Test: presignedGetObject(String bucketName, String objectName,"
653+
+ " Integer expires, Map<String, String> reqParams)"
654+
+ ", Error: <Content differs>");
655+
}
656+
657+
Files.delete(Paths.get(fileName));
658+
Files.delete(Paths.get(fileName + ".downloaded"));
659+
client.removeObject(bucketName, fileName);
660+
}
661+
598662
/**
599663
* public String presignedPutObject(String bucketName, String objectName).
600664
*/
@@ -801,6 +865,7 @@ public static void main(String[] args) {
801865

802866
presignedGetObject_test1();
803867
presignedGetObject_test2();
868+
presignedGetObject_test3();
804869

805870
presignedPutObject_test1();
806871
presignedPutObject_test2();

0 commit comments

Comments
 (0)