Skip to content

Commit 711b2aa

Browse files
api: Regression contentType set by user was never set properly. (#511)
The reason is because contentType is overriden by this operation even if the contentType is set through header. ``` public MediaType contentType() { if (contentType != null && !contentType.isEmpty()) { return MediaType.parse(contentType); } else { return MediaType.parse("application/octet-stream"); } } ```
1 parent e409e73 commit 711b2aa

File tree

2 files changed

+93
-26
lines changed

2 files changed

+93
-26
lines changed

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

Lines changed: 75 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -664,11 +664,16 @@ private Request createRequest(Method method, String bucketName, String objectNam
664664
requestBody = new RequestBody() {
665665
@Override
666666
public MediaType contentType() {
667+
MediaType mediaType = null;
668+
667669
if (contentType != null) {
668-
return MediaType.parse(contentType);
669-
} else {
670-
return MediaType.parse("application/octet-stream");
670+
mediaType = MediaType.parse(contentType);
671671
}
672+
if (mediaType == null) {
673+
mediaType = MediaType.parse("application/octet-stream");
674+
}
675+
676+
return mediaType;
672677
}
673678

674679
@Override
@@ -782,10 +787,15 @@ public void writeTo(BufferedSink sink) throws IOException {
782787
*/
783788
private HttpResponse execute(Method method, String region, String bucketName, String objectName,
784789
Map<String,String> headerMap, Map<String,String> queryParamMap,
785-
String contentType, Object body, int length)
790+
Object body, int length)
786791
throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException,
787792
InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException,
788793
InternalException {
794+
String contentType = null;
795+
if (headerMap != null) {
796+
contentType = headerMap.get("Content-Type");
797+
}
798+
789799
Request request = createRequest(method, bucketName, objectName, region,
790800
headerMap, queryParamMap,
791801
contentType, body, length);
@@ -919,7 +929,7 @@ private void updateRegionCache(String bucketName)
919929
queryParamMap.put("location", null);
920930

921931
HttpResponse response = execute(Method.GET, US_EAST_1, bucketName, null,
922-
null, queryParamMap, null, null, 0);
932+
null, queryParamMap, null, 0);
923933

924934
// existing XmlEntity does not work, so fallback to regular parsing.
925935
XmlPullParser xpp = xmlPullParserFactory.newPullParser();
@@ -983,7 +993,7 @@ private HttpResponse executeGet(String bucketName, String objectName, Map<String
983993
updateRegionCache(bucketName);
984994
return execute(Method.GET, BucketRegionCache.INSTANCE.region(bucketName),
985995
bucketName, objectName, headerMap, queryParamMap,
986-
null, null, 0);
996+
null, 0);
987997
}
988998

989999

@@ -1000,7 +1010,7 @@ private HttpResponse executeHead(String bucketName, String objectName)
10001010
updateRegionCache(bucketName);
10011011
HttpResponse response = execute(Method.HEAD, BucketRegionCache.INSTANCE.region(bucketName),
10021012
bucketName, objectName, null,
1003-
null, null, null, 0);
1013+
null, null, 0);
10041014
response.body().close();
10051015
return response;
10061016
}
@@ -1020,7 +1030,7 @@ private HttpResponse executeDelete(String bucketName, String objectName, Map<Str
10201030
updateRegionCache(bucketName);
10211031
HttpResponse response = execute(Method.DELETE, BucketRegionCache.INSTANCE.region(bucketName),
10221032
bucketName, objectName, null,
1023-
queryParamMap, null, null, 0);
1033+
queryParamMap, null, 0);
10241034
response.body().close();
10251035
return response;
10261036
}
@@ -1043,7 +1053,7 @@ private HttpResponse executePost(String bucketName, String objectName, Map<Strin
10431053
updateRegionCache(bucketName);
10441054
return execute(Method.POST, BucketRegionCache.INSTANCE.region(bucketName),
10451055
bucketName, objectName, headerMap, queryParamMap,
1046-
null, data, 0);
1056+
data, 0);
10471057
}
10481058

10491059

@@ -1065,7 +1075,7 @@ private HttpResponse executePut(String bucketName, String objectName, Map<String
10651075
InternalException {
10661076
HttpResponse response = execute(Method.PUT, region, bucketName, objectName,
10671077
headerMap, queryParamMap,
1068-
"", data, length);
1078+
data, length);
10691079
response.body().close();
10701080
return response;
10711081
}
@@ -1926,8 +1936,6 @@ public void makeBucket(String bucketName, String region)
19261936
throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException,
19271937
InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException,
19281938
InternalException {
1929-
Map<String,String> headerMap = new HashMap<>();
1930-
19311939
String configString;
19321940
if (region == null || US_EAST_1.equals(region)) {
19331941
// for 'us-east-1', location constraint is not required. for more info
@@ -1938,7 +1946,7 @@ public void makeBucket(String bucketName, String region)
19381946
configString = config.toString();
19391947
}
19401948

1941-
executePut(bucketName, null, headerMap, null, US_EAST_1, configString, 0);
1949+
executePut(bucketName, null, null, null, US_EAST_1, configString, 0);
19421950
}
19431951

19441952

@@ -1989,6 +1997,7 @@ public void removeBucket(String bucketName)
19891997
* @param bucketName Bucket name.
19901998
* @param objectName Object name to create in the bucket.
19911999
* @param fileName File name to upload.
2000+
* @param contentType File content type of the object, user supplied.
19922001
*
19932002
* @throws InvalidBucketNameException upon invalid bucket name is given
19942003
* @throws NoResponseException upon no response from server
@@ -1997,7 +2006,7 @@ public void removeBucket(String bucketName)
19972006
* @throws ErrorResponseException upon unsuccessful execution
19982007
* @throws InternalException upon internal library error
19992008
*/
2000-
public void putObject(String bucketName, String objectName, String fileName)
2009+
public void putObject(String bucketName, String objectName, String fileName, String contentType)
20012010
throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException,
20022011
InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException,
20032012
InternalException,
@@ -2011,7 +2020,10 @@ public void putObject(String bucketName, String objectName, String fileName)
20112020
throw new InvalidArgumentException("'" + fileName + "': not a regular file");
20122021
}
20132022

2014-
String contentType = Files.probeContentType(filePath);
2023+
if (contentType == null) {
2024+
contentType = Files.probeContentType(filePath);
2025+
}
2026+
20152027
long size = Files.size(filePath);
20162028

20172029
RandomAccessFile file = new RandomAccessFile(filePath.toFile(), "r");
@@ -2022,6 +2034,40 @@ public void putObject(String bucketName, String objectName, String fileName)
20222034
}
20232035
}
20242036

2037+
/**
2038+
* Uploads given file as object in given bucket.
2039+
* <p>
2040+
* If the object is larger than 5MB, the client will automatically use a multipart session.
2041+
* </p>
2042+
* <p>
2043+
* If the session fails, the user may attempt to re-upload the object by attempting to create
2044+
* the exact same object again. The client will examine all parts of any current upload session
2045+
* and attempt to reuse the session automatically. If a mismatch is discovered, the upload will fail
2046+
* before uploading any more data. Otherwise, it will resume uploading where the session left off.
2047+
* </p>
2048+
* <p>
2049+
* If the multipart session fails, the user is responsible for resuming or removing the session.
2050+
* </p>
2051+
*
2052+
* @param bucketName Bucket name.
2053+
* @param objectName Object name to create in the bucket.
2054+
* @param fileName File name to upload.
2055+
*
2056+
* @throws InvalidBucketNameException upon invalid bucket name is given
2057+
* @throws NoResponseException upon no response from server
2058+
* @throws IOException upon connection error
2059+
* @throws XmlPullParserException upon parsing response xml
2060+
* @throws ErrorResponseException upon unsuccessful execution
2061+
* @throws InternalException upon internal library error
2062+
*/
2063+
public void putObject(String bucketName, String objectName, String fileName)
2064+
throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException,
2065+
InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException,
2066+
InternalException,
2067+
InvalidArgumentException, InsufficientDataException {
2068+
putObject(bucketName, objectName, fileName, null);
2069+
}
2070+
20252071

20262072
/**
20272073
* Uploads data from given stream as object to given bucket.
@@ -2103,20 +2149,21 @@ private String putObject(String bucketName, String objectName, int length,
21032149
throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException,
21042150
InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException,
21052151
InternalException {
2152+
Map<String,String> headerMap = new HashMap<>();
2153+
if (contentType != null && !contentType.isEmpty()) {
2154+
headerMap.put("Content-Type", contentType);
2155+
} else {
2156+
headerMap.put("Content-Type", "application/octet-stream");
2157+
}
2158+
21062159
Map<String,String> queryParamMap = null;
21072160
if (partNumber > 0 && uploadId != null && !"".equals(uploadId)) {
21082161
queryParamMap = new HashMap<>();
21092162
queryParamMap.put("partNumber", Integer.toString(partNumber));
21102163
queryParamMap.put(UPLOAD_ID, uploadId);
21112164
}
2112-
Map<String,String> headerMap = new HashMap<>();
2113-
if (contentType != null) {
2114-
headerMap.put("Content-Type", contentType);
2115-
} else {
2116-
headerMap.put("Content-Type", "application/octet-stream");
2117-
}
2118-
HttpResponse response = executePut(bucketName, objectName, headerMap,
2119-
queryParamMap, data, length);
2165+
2166+
HttpResponse response = executePut(bucketName, objectName, headerMap, queryParamMap, data, length);
21202167
return response.header().etag();
21212168
}
21222169

@@ -2252,13 +2299,15 @@ private void setBucketPolicy(String bucketName, BucketPolicy policy)
22522299
throws InvalidBucketNameException, InvalidObjectPrefixException, NoSuchAlgorithmException,
22532300
InsufficientDataException, IOException, InvalidKeyException, NoResponseException,
22542301
XmlPullParserException, ErrorResponseException, InternalException {
2302+
Map<String,String> headerMap = new HashMap<>();
2303+
headerMap.put("Content-Type", "application/json");
2304+
22552305
Map<String,String> queryParamMap = new HashMap<>();
22562306
queryParamMap.put("policy", "");
22572307

22582308
String policyJson = policy.getJson();
22592309

2260-
HttpResponse response = executePut(bucketName, "", null, queryParamMap, policyJson, policyJson.length());
2261-
response.body().close();
2310+
executePut(bucketName, null, headerMap, queryParamMap, policyJson, policyJson.length());
22622311
}
22632312

22642313

@@ -2565,7 +2614,7 @@ private String initMultipartUpload(String bucketName, String objectName, String
25652614
InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException,
25662615
InternalException {
25672616
Map<String,String> headerMap = new HashMap<>();
2568-
if (contentType != null) {
2617+
if (contentType != null && !contentType.isEmpty()) {
25692618
headerMap.put("Content-Type", contentType);
25702619
} else {
25712620
headerMap.put("Content-Type", "application/octet-stream");

functional/FunctionalTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,23 @@ public static void putObject_test4() throws Exception {
214214
client.removeObject(bucketName, fileName);
215215
}
216216

217+
/**
218+
* Test: multipart: putObject(String bucketName, String objectName, String fileName, String contentType).
219+
*/
220+
public static void putObject_test5() throws Exception {
221+
System.out.println("Test: multipart: putObject(String bucketName, String objectName, String fileName,"
222+
+ " String contentType)");
223+
String fileName = createFile(13 * MB);
224+
client.putObject(bucketName, fileName, fileName, customContenType);
225+
Files.delete(Paths.get(fileName));
226+
ObjectStat objectStat = client.statObject(bucketName, fileName);
227+
if (!customContenType.equals(objectStat.contentType())) {
228+
throw new Exception("[FAILED] Test: putObject(String bucketName, String objectName, String fileName,"
229+
+ " String contentType)");
230+
}
231+
client.removeObject(bucketName, fileName);
232+
}
233+
217234
/**
218235
* Test: statObject(String bucketName, String objectName).
219236
*/
@@ -858,6 +875,7 @@ public static void main(String[] args) {
858875
putObject_test2();
859876
putObject_test3();
860877
putObject_test4();
878+
putObject_test5();
861879

862880
statObject_test();
863881

0 commit comments

Comments
 (0)