From 9850a22adc13221685512ae3d374ec41db6ae56c Mon Sep 17 00:00:00 2001 From: Samuel Pelletier Date: Wed, 11 May 2022 16:06:17 -0400 Subject: [PATCH 1/3] Fix url encoding of path to use %20 instead of + for spaces as defined in the spec. Url encoding of form values should use + for spaces. --- .../com/amazon/s3/AWSAuthConnection.java | 16 ++++++++-------- .../amazon/s3/QueryStringAuthGenerator.java | 12 ++++++------ .../Sources/com/amazon/s3/Utils.java | 19 ++++++++++--------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/AWSAuthConnection.java b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/AWSAuthConnection.java index ebe03fbd3fd..09adb34f6e3 100644 --- a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/AWSAuthConnection.java +++ b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/AWSAuthConnection.java @@ -195,7 +195,7 @@ public Response put(String bucket, String key, S3Object object, Map headers) key = ""; HttpURLConnection request = makeRequest("PUT", bucket + pathSep - + Utils.urlencode(key), headers, object); + + Utils.urlencodePath(key), headers, object); request.setDoOutput(true); request.getOutputStream().write( @@ -230,7 +230,7 @@ public Response putStream(String bucket, String key, S3StreamObject object, if (key == null) key = ""; HttpURLConnection request = makeStreamRequest("PUT", bucket + pathSep - + Utils.urlencode(key), headers, object); + + Utils.urlencodePath(key), headers, object); request.setDoOutput(true); if (object.length != 0) { @@ -274,7 +274,7 @@ public GetResponse get(String bucket, String key, Map headers) key = ""; return new GetResponse(makeRequest("GET", bucket + pathSep - + Utils.urlencode(key), headers)); + + Utils.urlencodePath(key), headers)); } /** @@ -302,7 +302,7 @@ public GetStreamResponse getStream(String bucket, String key, Map headers) key = ""; return new GetStreamResponse(makeRequest("GET", bucket + pathSep - + Utils.urlencode(key), headers)); + + Utils.urlencodePath(key), headers)); } /** @@ -330,7 +330,7 @@ public GetResponse getTorrent(String bucket, String key, Map headers) key = ""; return new GetResponse(makeRequest("GET", bucket + pathSep - + Utils.urlencode(key) + "?torrent", headers)); + + Utils.urlencodePath(key) + "?torrent", headers)); } /** @@ -356,7 +356,7 @@ public Response delete(String bucket, String key, Map headers) if (key == null) key = ""; return new Response(makeRequest("DELETE", bucket + pathSep - + Utils.urlencode(key), headers)); + + Utils.urlencodePath(key), headers)); } /** @@ -400,7 +400,7 @@ public GetResponse getACL(String bucket, String key, Map headers) if (key == null) key = ""; return new GetResponse(makeRequest("GET", bucket + pathSep - + Utils.urlencode(key) + "?acl", headers)); + + Utils.urlencodePath(key) + "?acl", headers)); } /** @@ -449,7 +449,7 @@ public Response putACL(String bucket, String key, String aclXMLDoc, if (key == null) key = ""; HttpURLConnection request = makeRequest("PUT", bucket + pathSep - + Utils.urlencode(key) + "?acl", headers, object); + + Utils.urlencodePath(key) + "?acl", headers, object); request.setDoOutput(true); request.getOutputStream().write( diff --git a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/QueryStringAuthGenerator.java b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/QueryStringAuthGenerator.java index 79d4688263f..e3b9bec369c 100644 --- a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/QueryStringAuthGenerator.java +++ b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/QueryStringAuthGenerator.java @@ -97,17 +97,17 @@ public String put(String bucket, String key, S3Object object, Map headers) { metadata = object.metadata; } - return generateURL("PUT", bucket + "/" + Utils.urlencode(key), mergeMeta(headers, metadata)); + return generateURL("PUT", bucket + "/" + Utils.urlencodePath(key), mergeMeta(headers, metadata)); } public String get(String bucket, String key, Map headers) { - return generateURL("GET", bucket + "/" + Utils.urlencode(key), headers); + return generateURL("GET", bucket + "/" + Utils.urlencodePath(key), headers); } public String delete(String bucket, String key, Map headers) { - return generateURL("DELETE", bucket + "/" + Utils.urlencode(key), headers); + return generateURL("DELETE", bucket + "/" + Utils.urlencodePath(key), headers); } public String getBucketACL(String bucket, Map headers) { @@ -116,7 +116,7 @@ public String getBucketACL(String bucket, Map headers) { public String getACL(String bucket, String key, Map headers) { - return generateURL("GET", bucket + "/" + Utils.urlencode(key) + "?acl", headers); + return generateURL("GET", bucket + "/" + Utils.urlencodePath(key) + "?acl", headers); } public String putBucketACL(String bucket, String aclXMLDoc, Map headers) { @@ -125,7 +125,7 @@ public String putBucketACL(String bucket, String aclXMLDoc, Map headers) { public String putACL(String bucket, String key, String aclXMLDoc, Map headers) { - return generateURL("PUT", bucket + "/" + Utils.urlencode(key) + "?acl", headers); + return generateURL("PUT", bucket + "/" + Utils.urlencodePath(key) + "?acl", headers); } public String listAllMyBuckets(Map headers) @@ -141,7 +141,7 @@ public String makeBareURL(String bucket, String key) { buffer.append("http://"); } buffer.append(server).append(':').append(port).append('/').append(bucket); - buffer.append('/').append(Utils.urlencode(key)); + buffer.append('/').append(Utils.urlencodePath(key)); return buffer.toString(); } diff --git a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/Utils.java b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/Utils.java index 698d1d822df..aadc2856546 100644 --- a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/Utils.java +++ b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/Utils.java @@ -9,8 +9,8 @@ package com.amazon.s3; -import java.io.UnsupportedEncodingException; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Iterator; @@ -23,7 +23,6 @@ import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; -import org.apache.commons.lang3.CharEncoding; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; @@ -184,13 +183,15 @@ static String pathForListOptions(String bucket, String prefix, String marker, In return path.toString(); } - static String urlencode(String unencoded) { - try { - return URLEncoder.encode(unencoded, CharEncoding.UTF_8); - } catch (UnsupportedEncodingException e) { - // should never happen - throw new RuntimeException("Could not url encode to UTF-8", e); - } + public static String urlencode(String unencoded) { + String encoded = URLEncoder.encode(unencoded, StandardCharsets.UTF_8); + return encoded; + } + + public static String urlencodePath(String path) { + String encodedPath = URLEncoder.encode(path, StandardCharsets.UTF_8); + encodedPath = encodedPath.replace("+", "%20"); + return encodedPath; } static XMLReader createXMLReader() { From a368db15b60790219159b3d5288fde02538a0aae Mon Sep 17 00:00:00 2001 From: Samuel Pelletier Date: Wed, 11 May 2022 16:08:00 -0400 Subject: [PATCH 2/3] Add generics to remove warnings in S3 api classes. --- .../com/amazon/s3/AWSAuthConnection.java | 48 +++++++++---------- .../Sources/com/amazon/s3/GetResponse.java | 13 +++-- .../com/amazon/s3/GetStreamResponse.java | 13 +++-- .../amazon/s3/ListAllMyBucketsResponse.java | 8 ++-- .../com/amazon/s3/ListBucketResponse.java | 8 ++-- .../amazon/s3/QueryStringAuthGenerator.java | 39 +++++++-------- .../Sources/com/amazon/s3/S3Object.java | 5 +- .../Sources/com/amazon/s3/Utils.java | 17 +++---- .../com/silvasoftinc/s3/S3StreamObject.java | 5 +- 9 files changed, 73 insertions(+), 83 deletions(-) diff --git a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/AWSAuthConnection.java b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/AWSAuthConnection.java index 09adb34f6e3..a2696fc1d90 100644 --- a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/AWSAuthConnection.java +++ b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/AWSAuthConnection.java @@ -41,7 +41,6 @@ import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; @@ -120,7 +119,7 @@ public AWSAuthConnection(String awsAccessKeyId, String awsSecretAccessKey, * @throws MalformedURLException * @throws IOException */ - public Response createBucket(String bucket, Map headers) + public Response createBucket(String bucket, Map> headers) throws MalformedURLException, IOException { return new Response(makeRequest("PUT", bucket, headers)); } @@ -145,7 +144,7 @@ public Response createBucket(String bucket, Map headers) * @throws IOException */ public ListBucketResponse listBucket(String bucket, String prefix, - String marker, Integer maxKeys, Map headers) + String marker, Integer maxKeys, Map> headers) throws MalformedURLException, IOException { String path = Utils.pathForListOptions(bucket, prefix, marker, maxKeys); return new ListBucketResponse(makeRequest("GET", path, headers)); @@ -163,7 +162,7 @@ public ListBucketResponse listBucket(String bucket, String prefix, * @throws MalformedURLException * @throws IOException */ - public Response deleteBucket(String bucket, Map headers) + public Response deleteBucket(String bucket, Map> headers) throws MalformedURLException, IOException { return new Response(makeRequest("DELETE", bucket, headers)); } @@ -184,7 +183,7 @@ public Response deleteBucket(String bucket, Map headers) * @throws MalformedURLException * @throws IOException */ - public Response put(String bucket, String key, S3Object object, Map headers) + public Response put(String bucket, String key, S3Object object, Map> headers) throws MalformedURLException, IOException { boolean isEmptyKey = (key == null) || (key.length() == 0) @@ -221,7 +220,7 @@ public Response put(String bucket, String key, S3Object object, Map headers) * @throws IOException */ public Response putStream(String bucket, String key, S3StreamObject object, - Map headers) throws MalformedURLException, IOException { + Map> headers) throws MalformedURLException, IOException { boolean isEmptyKey = (key == null) || (key.length() == 0) || (key.trim().length() == 0); @@ -263,7 +262,7 @@ public Response putStream(String bucket, String key, S3StreamObject object, * @throws MalformedURLException * @throws IOException */ - public GetResponse get(String bucket, String key, Map headers) + public GetResponse get(String bucket, String key, Map> headers) throws MalformedURLException, IOException { boolean isEmptyKey = (key == null) || (key.length() == 0) @@ -291,7 +290,7 @@ public GetResponse get(String bucket, String key, Map headers) * @throws MalformedURLException * @throws IOException */ - public GetStreamResponse getStream(String bucket, String key, Map headers) + public GetStreamResponse getStream(String bucket, String key, Map> headers) throws MalformedURLException, IOException { boolean isEmptyKey = (key == null) || (key.length() == 0) @@ -319,7 +318,7 @@ public GetStreamResponse getStream(String bucket, String key, Map headers) * @throws MalformedURLException * @throws IOException */ - public GetResponse getTorrent(String bucket, String key, Map headers) + public GetResponse getTorrent(String bucket, String key, Map> headers) throws MalformedURLException, IOException { boolean isEmptyKey = (key == null) || (key.length() == 0) @@ -347,7 +346,7 @@ public GetResponse getTorrent(String bucket, String key, Map headers) * @throws MalformedURLException * @throws IOException */ - public Response delete(String bucket, String key, Map headers) + public Response delete(String bucket, String key, Map> headers) throws MalformedURLException, IOException { boolean isEmptyKey = (key == null) || (key.length() == 0) || (key.trim().length() == 0); @@ -371,7 +370,7 @@ public Response delete(String bucket, String key, Map headers) * @throws MalformedURLException * @throws IOException */ - public GetResponse getBucketACL(String bucket, Map headers) + public GetResponse getBucketACL(String bucket, Map> headers) throws MalformedURLException, IOException { return getACL(bucket, "", headers); } @@ -390,7 +389,7 @@ public GetResponse getBucketACL(String bucket, Map headers) * @throws MalformedURLException * @throws IOException */ - public GetResponse getACL(String bucket, String key, Map headers) + public GetResponse getACL(String bucket, String key, Map> headers) throws MalformedURLException, IOException { boolean isEmptyKey = (key == null) || (key.length() == 0) @@ -417,7 +416,7 @@ public GetResponse getACL(String bucket, String key, Map headers) * @throws MalformedURLException * @throws IOException */ - public Response putBucketACL(String bucket, String aclXMLDoc, Map headers) + public Response putBucketACL(String bucket, String aclXMLDoc, Map> headers) throws MalformedURLException, IOException { return putACL(bucket, "", aclXMLDoc, headers); } @@ -439,7 +438,7 @@ public Response putBucketACL(String bucket, String aclXMLDoc, Map headers) * @throws IOException */ public Response putACL(String bucket, String key, String aclXMLDoc, - Map headers) throws MalformedURLException, IOException { + Map> headers) throws MalformedURLException, IOException { S3Object object = new S3Object(aclXMLDoc.getBytes(), null); boolean isEmptyKey = (key == null) || (key.length() == 0) @@ -468,7 +467,7 @@ public Response putACL(String bucket, String key, String aclXMLDoc, * @throws MalformedURLException * @throws IOException */ - public ListAllMyBucketsResponse listAllMyBuckets(Map headers) + public ListAllMyBucketsResponse listAllMyBuckets(Map> headers) throws MalformedURLException, IOException { return new ListAllMyBucketsResponse(makeRequest("GET", "", headers)); } @@ -477,7 +476,7 @@ public ListAllMyBucketsResponse listAllMyBuckets(Map headers) * Make a new HttpURLConnection without passing an S3Object parameter. */ private HttpURLConnection makeRequest(String method, String resource, - Map headers) throws MalformedURLException, IOException { + Map> headers) throws MalformedURLException, IOException { return makeRequest(method, resource, headers, null); } @@ -495,7 +494,7 @@ private HttpURLConnection makeRequest(String method, String resource, * The S3Object that is to be written (can be null). */ private HttpURLConnection makeRequest(String method, String resource, - Map headers, S3Object object) throws MalformedURLException, + Map> headers, S3Object object) throws MalformedURLException, IOException { URL url = makeURL(resource); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); @@ -524,7 +523,7 @@ private HttpURLConnection makeRequest(String method, String resource, * The S3StreamObject that is to be written (can be null). */ private HttpURLConnection makeStreamRequest(String method, String resource, - Map headers, S3StreamObject object) throws MalformedURLException, + Map> headers, S3StreamObject object) throws MalformedURLException, IOException { URL url = makeURL(resource); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); @@ -548,7 +547,7 @@ private HttpURLConnection makeStreamRequest(String method, String resource, * A Map of String to List of Strings representing the http * headers to pass (can be null). */ - private void addHeaders(HttpURLConnection connection, Map headers) { + private void addHeaders(HttpURLConnection connection, Map> headers) { addHeaders(connection, headers, ""); } @@ -561,7 +560,7 @@ private void addHeaders(HttpURLConnection connection, Map headers) { * A Map of String to List of Strings representing the s3 * metadata for this resource. */ - private void addMetadataHeaders(HttpURLConnection connection, Map metadata) { + private void addMetadataHeaders(HttpURLConnection connection, Map> metadata) { addHeaders(connection, metadata, Utils.METADATA_PREFIX); } @@ -578,14 +577,11 @@ private void addMetadataHeaders(HttpURLConnection connection, Map metadata) { * The string to prepend to each key before adding it to the * connection. */ - private void addHeaders(HttpURLConnection connection, Map headers, + private void addHeaders(HttpURLConnection connection, Map> headers, String prefix) { if (headers != null) { - for (Iterator i = headers.keySet().iterator(); i.hasNext();) { - String key = (String) i.next(); - for (Iterator j = ((List) headers.get(key)).iterator(); j - .hasNext();) { - String value = (String) j.next(); + for (String key : headers.keySet()) { + for (String value :headers.get(key)) { connection.addRequestProperty(prefix + key, value); } } diff --git a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/GetResponse.java b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/GetResponse.java index 7cf836e1b30..0fab67b1cf2 100644 --- a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/GetResponse.java +++ b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/GetResponse.java @@ -13,7 +13,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; -import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -31,7 +31,7 @@ public class GetResponse extends Response { public GetResponse(HttpURLConnection connection) throws IOException { super(connection); if (connection.getResponseCode() < 400) { - Map metadata = extractMetadata(connection); + Map> metadata = extractMetadata(connection); byte[] body = slurpInputStream(connection.getInputStream()); object = new S3Object(body, metadata); } @@ -41,11 +41,10 @@ public GetResponse(HttpURLConnection connection) throws IOException { * Examines the response's header fields and returns a Map from String to * List of Strings representing the object's metadata. */ - private Map extractMetadata(HttpURLConnection connection) { - TreeMap metadata = new TreeMap(); - Map headers = connection.getHeaderFields(); - for (Iterator i = headers.keySet().iterator(); i.hasNext();) { - String key = (String) i.next(); + private Map> extractMetadata(HttpURLConnection connection) { + TreeMap> metadata = new TreeMap<>(); + Map> headers = connection.getHeaderFields(); + for (String key : headers.keySet()) { if (key == null) continue; metadata.put(key, headers.get(key)); diff --git a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/GetStreamResponse.java b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/GetStreamResponse.java index f19698cf29c..848919f5aa2 100644 --- a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/GetStreamResponse.java +++ b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/GetStreamResponse.java @@ -27,7 +27,7 @@ import java.io.IOException; import java.net.HttpURLConnection; -import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -47,7 +47,7 @@ public class GetStreamResponse extends Response { public GetStreamResponse(HttpURLConnection connection) throws IOException { super(connection); if (connection.getResponseCode() < 400) { - Map metadata = extractMetadata(connection); + Map> metadata = extractMetadata(connection); object = new S3StreamObject(connection.getInputStream(), metadata); } @@ -57,11 +57,10 @@ public GetStreamResponse(HttpURLConnection connection) throws IOException { * Examines the response's header fields and returns a Map from String to * List of Strings representing the object's metadata. */ - private Map extractMetadata(HttpURLConnection connection) { - TreeMap metadata = new TreeMap(); - Map headers = connection.getHeaderFields(); - for (Iterator i = headers.keySet().iterator(); i.hasNext();) { - String key = (String) i.next(); + private Map> extractMetadata(HttpURLConnection connection) { + TreeMap> metadata = new TreeMap<>(); + Map> headers = connection.getHeaderFields(); + for (String key : headers.keySet()) { if (key == null) continue; if (key.startsWith(Utils.METADATA_PREFIX)) { diff --git a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/ListAllMyBucketsResponse.java b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/ListAllMyBucketsResponse.java index 0fc8b13dac1..1cd1507b508 100644 --- a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/ListAllMyBucketsResponse.java +++ b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/ListAllMyBucketsResponse.java @@ -31,7 +31,7 @@ public class ListAllMyBucketsResponse extends Response { * A list of Bucket objects, one for each of this account's buckets. Will be null if * the request fails. */ - public List entries; + public List entries; public ListAllMyBucketsResponse(HttpURLConnection connection) throws IOException { super(connection); @@ -52,14 +52,14 @@ public ListAllMyBucketsResponse(HttpURLConnection connection) throws IOException static class ListAllMyBucketsHandler extends DefaultHandler { - private List entries = null; + private List entries = null; private Bucket currBucket = null; private StringBuffer currText = null; private SimpleDateFormat iso8601Parser = null; public ListAllMyBucketsHandler() { super(); - entries = new ArrayList(); + entries = new ArrayList<>(); iso8601Parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); iso8601Parser.setTimeZone(new SimpleTimeZone(0, "GMT")); currText = new StringBuffer(); @@ -103,7 +103,7 @@ public void characters(char ch[], int start, int length) { currText.append(ch, start, length); } - public List getEntries() { + public List getEntries() { return entries; } } diff --git a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/ListBucketResponse.java b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/ListBucketResponse.java index 5b549b3c981..721bee8d44f 100644 --- a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/ListBucketResponse.java +++ b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/ListBucketResponse.java @@ -32,7 +32,7 @@ public class ListBucketResponse extends Response { * A List of ListEntry objects representing the objects in the given bucket. This will * be null if the request fails. */ - public List entries = null; + public List entries = null; public ListBucketResponse(HttpURLConnection connection) throws IOException { super(connection); @@ -53,14 +53,14 @@ public ListBucketResponse(HttpURLConnection connection) throws IOException { class ListBucketHandler extends DefaultHandler { - private List entries = null; + private List entries = null; private ListEntry currEntry = null; private StringBuffer currText = null; private SimpleDateFormat iso8601Parser = null; public ListBucketHandler() { super(); - entries = new ArrayList(); + entries = new ArrayList<>(); iso8601Parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); iso8601Parser.setTimeZone(new SimpleTimeZone(0, "GMT")); currText = new StringBuffer(); @@ -116,7 +116,7 @@ public void characters(char ch[], int start, int length) { currText.append(ch, start, length); } - public List getEntries() { + public List getEntries() { return entries; } } diff --git a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/QueryStringAuthGenerator.java b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/QueryStringAuthGenerator.java index e3b9bec369c..d70c2997f2a 100644 --- a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/QueryStringAuthGenerator.java +++ b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/QueryStringAuthGenerator.java @@ -9,7 +9,6 @@ package com.amazon.s3; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -74,25 +73,25 @@ public void setExpiresIn(long millis) { expires = null; } - public String createBucket(String bucket, Map headers) + public String createBucket(String bucket, Map> headers) { return generateURL("PUT", bucket, headers); } public String listBucket(String bucket, String prefix, String marker, - Integer maxKeys, Map headers) + Integer maxKeys, Map> headers) { String path = Utils.pathForListOptions(bucket, prefix, marker, maxKeys); return generateURL("GET", path, headers); } - public String deleteBucket(String bucket, Map headers) + public String deleteBucket(String bucket, Map> headers) { return generateURL("DELETE", bucket, headers); } - public String put(String bucket, String key, S3Object object, Map headers) { - Map metadata = null; + public String put(String bucket, String key, S3Object object, Map> headers) { + Map> metadata = null; if (object != null) { metadata = object.metadata; } @@ -100,35 +99,35 @@ public String put(String bucket, String key, S3Object object, Map headers) { return generateURL("PUT", bucket + "/" + Utils.urlencodePath(key), mergeMeta(headers, metadata)); } - public String get(String bucket, String key, Map headers) + public String get(String bucket, String key, Map> headers) { return generateURL("GET", bucket + "/" + Utils.urlencodePath(key), headers); } - public String delete(String bucket, String key, Map headers) + public String delete(String bucket, String key, Map> headers) { return generateURL("DELETE", bucket + "/" + Utils.urlencodePath(key), headers); } - public String getBucketACL(String bucket, Map headers) { + public String getBucketACL(String bucket, Map> headers) { return getACL(bucket, "", headers); } - public String getACL(String bucket, String key, Map headers) + public String getACL(String bucket, String key, Map> headers) { return generateURL("GET", bucket + "/" + Utils.urlencodePath(key) + "?acl", headers); } - public String putBucketACL(String bucket, String aclXMLDoc, Map headers) { + public String putBucketACL(String bucket, String aclXMLDoc, Map> headers) { return putACL(bucket, "", aclXMLDoc, headers); } - public String putACL(String bucket, String key, String aclXMLDoc, Map headers) + public String putACL(String bucket, String key, String aclXMLDoc, Map> headers) { return generateURL("PUT", bucket + "/" + Utils.urlencodePath(key) + "?acl", headers); } - public String listAllMyBuckets(Map headers) + public String listAllMyBuckets(Map> headers) { return generateURL("GET", "", headers); } @@ -146,7 +145,7 @@ public String makeBareURL(String bucket, String key) { return buffer.toString(); } - private String generateURL(String method, String path, Map headers) { + private String generateURL(String method, String path, Map> headers) { long expires = 0L; if (expiresIn != null) { expires = System.currentTimeMillis() + expiresIn.longValue(); @@ -186,20 +185,18 @@ private String generateURL(String method, String path, Map headers) { return buffer.toString(); } - private Map mergeMeta(Map headers, Map metadata) { - Map merged = new TreeMap(); + private Map> mergeMeta(Map> headers, Map> metadata) { + Map> merged = new TreeMap>(); if (headers != null) { - for (Iterator i = headers.keySet().iterator(); i.hasNext(); ) { - String key = (String)i.next(); + for (String key : headers.keySet()) { merged.put(key, headers.get(key)); } } if (metadata != null) { - for (Iterator i = metadata.keySet().iterator(); i.hasNext(); ) { - String key = (String)i.next(); + for (String key : metadata.keySet()) { String metadataKey = Utils.METADATA_PREFIX + key; if (merged.containsKey(metadataKey)) { - ((List)merged.get(metadataKey)).addAll((List)metadata.get(key)); + merged.get(metadataKey).addAll(metadata.get(key)); } else { merged.put(metadataKey, metadata.get(key)); } diff --git a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/S3Object.java b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/S3Object.java index d43a3bca9f9..97294b345d1 100644 --- a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/S3Object.java +++ b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/S3Object.java @@ -9,6 +9,7 @@ package com.amazon.s3; +import java.util.List; import java.util.Map; /** @@ -21,9 +22,9 @@ public class S3Object { /** * A Map from String to List of Strings representing the object's metadata */ - public Map metadata; + public Map> metadata; - public S3Object(byte[] data, Map metadata) { + public S3Object(byte[] data, Map> metadata) { this.data = data; this.metadata = metadata; } diff --git a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/Utils.java b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/Utils.java index aadc2856546..f32ca3b3fdf 100644 --- a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/Utils.java +++ b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/Utils.java @@ -13,7 +13,6 @@ import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.SortedMap; @@ -41,7 +40,7 @@ public class Utils { */ private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1"; - static String makeCanonicalString(String method, String resource, Map headers) { + static String makeCanonicalString(String method, String resource, Map> headers) { return makeCanonicalString(method, resource, headers, null); } @@ -55,17 +54,16 @@ static String makeCanonicalString(String method, String resource, Map headers) { * @return canoncical string */ static String makeCanonicalString(String method, String resource, - Map headers, String expires) + Map> headers, String expires) { StringBuilder buf = new StringBuilder(); buf.append(method + "\n"); // Add all interesting headers to a list, then sort them. "Interesting" // is defined as Content-MD5, Content-Type, Date, and x-amz- - SortedMap interestingHeaders = new TreeMap(); + SortedMap interestingHeaders = new TreeMap(); if (headers != null) { - for (Iterator i = headers.keySet().iterator(); i.hasNext(); ) { - String key = (String)i.next(); + for (String key : headers.keySet()) { if (key == null) continue; String lk = key.toLowerCase(); @@ -73,7 +71,7 @@ static String makeCanonicalString(String method, String resource, if (lk.equals("content-type") || lk.equals("content-md5") || lk.equals("date") || lk.startsWith(AMAZON_HEADER_PREFIX)) { - List s = (List)headers.get(key); + List s = headers.get(key); interestingHeaders.put(lk, concatenateList(s)); } } @@ -99,8 +97,7 @@ static String makeCanonicalString(String method, String resource, } // Finally, add all the interesting headers (i.e.: all that startwith x-amz- ;-)) - for (Iterator i = interestingHeaders.keySet().iterator(); i.hasNext(); ) { - String key = (String)i.next(); + for (String key : interestingHeaders.keySet()) { if (key.startsWith(AMAZON_HEADER_PREFIX)) { buf.append(key).append(':').append(interestingHeaders.get(key)); } else { @@ -214,7 +211,7 @@ static XMLReader createXMLReader() { * @param values List of header values. * @return String of all headers, with commas. */ - private static String concatenateList(List values) { + private static String concatenateList(List values) { StringBuilder buf = new StringBuilder(); for (int i = 0, size = values.size(); i < size; ++ i) { buf.append(((String)values.get(i)).replaceAll("\n", "").trim()); diff --git a/Frameworks/BusinessLogic/ERAttachment/Sources/com/silvasoftinc/s3/S3StreamObject.java b/Frameworks/BusinessLogic/ERAttachment/Sources/com/silvasoftinc/s3/S3StreamObject.java index 85f16d5bd85..ec632f3cbe7 100644 --- a/Frameworks/BusinessLogic/ERAttachment/Sources/com/silvasoftinc/s3/S3StreamObject.java +++ b/Frameworks/BusinessLogic/ERAttachment/Sources/com/silvasoftinc/s3/S3StreamObject.java @@ -26,6 +26,7 @@ package com.silvasoftinc.s3; import java.io.InputStream; +import java.util.List; import java.util.Map; /** @@ -40,9 +41,9 @@ public class S3StreamObject { /** * A Map from String to List of Strings representing the object's metadata */ - public Map metadata; + public Map> metadata; - public S3StreamObject(InputStream stream, Map metadata) { + public S3StreamObject(InputStream stream, Map> metadata) { this.stream = stream; this.metadata = metadata; } From d64a8343927c59cb95989187569670d474be5b6b Mon Sep 17 00:00:00 2001 From: Samuel Pelletier Date: Wed, 11 May 2022 17:03:51 -0400 Subject: [PATCH 3/3] Oups, forget we build in Java 8, back to encoding name in String. --- .../ERAttachment/Sources/com/amazon/s3/Utils.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/Utils.java b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/Utils.java index f32ca3b3fdf..957c888f8ca 100644 --- a/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/Utils.java +++ b/Frameworks/BusinessLogic/ERAttachment/Sources/com/amazon/s3/Utils.java @@ -9,8 +9,8 @@ package com.amazon.s3; +import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.List; @@ -21,6 +21,7 @@ import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; +import org.apache.commons.codec.CharEncoding; import org.apache.commons.codec.binary.Base64; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; @@ -181,12 +182,16 @@ static String pathForListOptions(String bucket, String prefix, String marker, In } public static String urlencode(String unencoded) { - String encoded = URLEncoder.encode(unencoded, StandardCharsets.UTF_8); - return encoded; + try { + return URLEncoder.encode(unencoded, CharEncoding.UTF_8); + } catch (UnsupportedEncodingException e) { + // should never happen + throw new RuntimeException("Could not url encode to UTF-8", e); + } } public static String urlencodePath(String path) { - String encodedPath = URLEncoder.encode(path, StandardCharsets.UTF_8); + String encodedPath = urlencode(path); encodedPath = encodedPath.replace("+", "%20"); return encodedPath; }