diff --git a/pom.xml b/pom.xml index fa8dc27..12a7202 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ dev-35.0.1 - dev-64.0.1 + dev-64.0.2 diff --git a/src/main/java/ninja/NinjaController.java b/src/main/java/ninja/NinjaController.java index 00c4280..7c44100 100644 --- a/src/main/java/ninja/NinjaController.java +++ b/src/main/java/ninja/NinjaController.java @@ -14,6 +14,7 @@ import io.netty.handler.codec.http.HttpResponseStatus; import sirius.kernel.commons.Hasher; import sirius.kernel.commons.PriorityCollector; +import sirius.kernel.commons.Strings; import sirius.kernel.di.std.Part; import sirius.kernel.di.std.Register; import sirius.kernel.health.Exceptions; @@ -170,12 +171,20 @@ public void bucket(WebContext webContext, String bucketName) { return; } + // we only accept known paths below /ui as return address + String address = webContext.getParameter("return"); + if (Strings.areEqual(address, "/ui") || Strings.areEqual(address, "/ui/") || Strings.areEqual(address, "ui")) { + address = "/ui"; + } else { + address = "/ui/" + bucket.getEncodedName(); + } + // handle /ui/[bucket]?make-public if (webContext.hasParameter("make-public")) { bucket.makePublic(); UserContext.message(Message.info().withTextMessage("ACLs successfully changed")); - webContext.respondWith().redirectTemporarily("/ui/" + bucket.getEncodedName()); + webContext.respondWith().redirectTemporarily(address); return; } @@ -184,7 +193,7 @@ public void bucket(WebContext webContext, String bucketName) { bucket.makePrivate(); UserContext.message(Message.info().withTextMessage("ACLs successfully changed")); - webContext.respondWith().redirectTemporarily("/ui/" + bucket.getEncodedName()); + webContext.respondWith().redirectTemporarily(address); return; } diff --git a/src/main/java/ninja/S3Dispatcher.java b/src/main/java/ninja/S3Dispatcher.java index de0b4a6..448a3be 100644 --- a/src/main/java/ninja/S3Dispatcher.java +++ b/src/main/java/ninja/S3Dispatcher.java @@ -87,7 +87,6 @@ public class S3Dispatcher implements WebDispatcher { private static final String HTTP_HEADER_NAME_ETAG = "ETag"; private static final String HTTP_HEADER_NAME_CONTENT_TYPE = "Content-Type"; - private static final String HTTP_HEADER_NAME_AMAZON_ACL = "x-amz-acl"; private static final String CONTENT_TYPE_XML = "application/xml"; private static final String RESPONSE_DISPLAY_NAME = "DisplayName"; private static final String RESPONSE_BUCKET = "Bucket"; @@ -475,7 +474,7 @@ private void bucket(WebContext webContext, String bucketName) { bucket.create(); // in order to allow creation of public buckets, we support a single canned access control list - String cannedAccessControlList = webContext.getHeader(HTTP_HEADER_NAME_AMAZON_ACL); + String cannedAccessControlList = webContext.getHeader("x-amz-acl"); if (Strings.areEqual(cannedAccessControlList, "public-read-write")) { bucket.makePublic(); } @@ -737,8 +736,7 @@ private Map parseUploadProperties(WebContext webContext) { Map properties = Maps.newTreeMap(); for (String name : webContext.getRequest().headers().names()) { String nameLower = name.toLowerCase(); - if (nameLower.startsWith("x-amz-meta-") || "content-md5".equals(nameLower) || "content-type".equals( - nameLower) || HTTP_HEADER_NAME_AMAZON_ACL.equals(nameLower)) { + if (nameLower.startsWith("x-amz-") || "content-md5".equals(nameLower) || "content-type".equals(nameLower)) { properties.put(name, webContext.getHeader(name)); } } @@ -872,8 +870,7 @@ private void startMultipartUpload(WebContext webContext, Bucket bucket, String i Map properties = Maps.newTreeMap(); for (String name : webContext.getRequest().headers().names()) { String nameLower = name.toLowerCase(); - if (nameLower.startsWith("x-amz-meta-") || "content-md5".equals(nameLower) || "content-type".equals( - nameLower) || HTTP_HEADER_NAME_AMAZON_ACL.equals(nameLower)) { + if (nameLower.startsWith("x-amz-") || "content-md5".equals(nameLower) || "content-type".equals(nameLower)) { properties.put(name, webContext.getHeader(name)); response.addHeader(name, webContext.getHeader(name)); } diff --git a/src/main/java/ninja/StoredObject.java b/src/main/java/ninja/StoredObject.java index 5e2d903..03ca640 100644 --- a/src/main/java/ninja/StoredObject.java +++ b/src/main/java/ninja/StoredObject.java @@ -22,6 +22,7 @@ import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.time.Instant; +import java.util.List; import java.util.Map; import java.util.Properties; @@ -181,11 +182,11 @@ public File getPropertiesFile() { /** * Returns all meta information stored along with the object. *

- * This is the Content-MD5, Content-Type and any x-amz-meta-* header. + * These are the Content-MD5, Content-Type and any x-amz-* headers. *

* Internally, a {@link Properties} file is loaded from disk and converted to a {@link Map}. * - * @return name value pairs representing all properties stored for this object, or an empty map if no properties + * @return name-value-pairs representing all properties stored for this object, or an empty map if no properties * could be read */ public Map getProperties() { @@ -203,6 +204,16 @@ public Map getProperties() { return map; } + /** + * Returns a sorted list of all property names. + * + * @return a list of property names + * @see #getProperties() + */ + public List getPropertyNames() { + return getProperties().keySet().stream().sorted(String::compareToIgnoreCase).toList(); + } + /** * Stores the given meta information for this object. *

diff --git a/src/main/resources/templates/bucket.html.pasta b/src/main/resources/templates/bucket.html.pasta index b8d85ed..5bc42d4 100644 --- a/src/main/resources/templates/bucket.html.pasta +++ b/src/main/resources/templates/bucket.html.pasta @@ -79,8 +79,47 @@

@obj.getLastModified()
- + + + + +
+ +

+ (No properties) +

+
+ + +

+ + @propertyName + +
+ + @propertyValue + +

+
+
+
+ + + + diff --git a/src/main/resources/templates/index.html.pasta b/src/main/resources/templates/index.html.pasta index a173129..c60a037 100644 --- a/src/main/resources/templates/index.html.pasta +++ b/src/main/resources/templates/index.html.pasta @@ -168,7 +168,19 @@ - + + + + + + + + +