diff --git a/pom.xml b/pom.xml
index ee12a15..c7ecbb8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,8 +16,8 @@
http://s3ninja.net
- dev-34.6.0
- dev-62.5.2
+ dev-34.8.0
+ dev-63.0.1
diff --git a/src/test/java/BaseAWSSpec.groovy b/src/test/java/BaseAWSSpec.groovy
index a0a5533..ab51fa8 100644
--- a/src/test/java/BaseAWSSpec.groovy
+++ b/src/test/java/BaseAWSSpec.groovy
@@ -8,6 +8,7 @@
import com.amazonaws.HttpMethod
import com.amazonaws.services.s3.AmazonS3Client
+import com.amazonaws.services.s3.Headers
import com.amazonaws.services.s3.model.AmazonS3Exception
import com.amazonaws.services.s3.model.DeleteObjectsRequest
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest
@@ -15,11 +16,11 @@ import com.amazonaws.services.s3.model.ListObjectsV2Request
import com.amazonaws.services.s3.model.ObjectMetadata
import com.amazonaws.services.s3.model.ResponseHeaderOverrides
import com.amazonaws.services.s3.transfer.TransferManagerBuilder
-import com.google.common.base.Charsets
import com.google.common.io.ByteStreams
import com.google.common.io.Files
import sirius.kernel.BaseSpecification
+import java.nio.charset.StandardCharsets
import java.time.Instant
import java.time.temporal.ChronoUnit
@@ -31,6 +32,28 @@ abstract class BaseAWSSpec extends BaseSpecification {
abstract AmazonS3Client getClient()
+ private void createPubliclyAccessibleBucket(String bucketName) {
+ def client = getClient()
+ client.createBucket(bucketName)
+
+ // we make the bucket now public via our own endpoint; note that this is not proper S3 code
+ // where you would use ACLs that we do not support in S3 Ninja
+ def url = new URL("http://localhost:9999/ui/" + bucketName + "/?make-public")
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection()
+ connection.getResponseCode() == 200
+ connection.disconnect();
+ }
+
+ private void putObjectWithContent(String bucketName, String key, String content) {
+ def client = getClient()
+ def data = content.getBytes(StandardCharsets.UTF_8)
+
+ def metadata = new ObjectMetadata()
+ metadata.setHeader(Headers.CONTENT_LENGTH, new Long(data.length))
+
+ client.putObject(bucketName, key, new ByteArrayInputStream(data), metadata)
+ }
+
def "HEAD of non-existing bucket as expected"() {
given:
def bucketName = "does-not-exist"
@@ -101,7 +124,7 @@ abstract class BaseAWSSpec extends BaseSpecification {
File file = File.createTempFile("test", "")
file.delete()
for (int i = 0; i < 10000; i++) {
- Files.append("This is a test.", file, Charsets.UTF_8)
+ Files.append("This is a test.", file, StandardCharsets.UTF_8)
}
and:
def tm = TransferManagerBuilder.standard().withS3Client(client).build()
@@ -111,7 +134,7 @@ abstract class BaseAWSSpec extends BaseSpecification {
download.deleteOnExit()
tm.download(bucketName, key, download).waitForCompletion()
then:
- Files.toString(file, Charsets.UTF_8) == Files.toString(download, Charsets.UTF_8)
+ Files.toString(file, StandardCharsets.UTF_8) == Files.toString(download, StandardCharsets.UTF_8)
and:
client.deleteObject(bucketName, key)
}
@@ -126,19 +149,15 @@ abstract class BaseAWSSpec extends BaseSpecification {
client.createBucket(bucketName)
}
and:
- client.putObject(
- bucketName,
- key,
- new ByteArrayInputStream("Test".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
+ putObjectWithContent(bucketName, key, "Test")
def content = new String(
ByteStreams.toByteArray(client.getObject(bucketName, key).getObjectContent()),
- Charsets.UTF_8)
+ StandardCharsets.UTF_8)
and:
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, key)
URLConnection c = new URL(getClient().generatePresignedUrl(request).toString()).openConnection()
and:
- String downloadedData = new String(ByteStreams.toByteArray(c.getInputStream()), Charsets.UTF_8)
+ String downloadedData = new String(ByteStreams.toByteArray(c.getInputStream()), StandardCharsets.UTF_8)
then:
content == "Test"
and:
@@ -159,16 +178,8 @@ abstract class BaseAWSSpec extends BaseSpecification {
}
client.createBucket(bucketName)
and:
- client.putObject(
- bucketName,
- key1,
- new ByteArrayInputStream("Eins".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
- client.putObject(
- bucketName,
- key2,
- new ByteArrayInputStream("Zwei".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
+ putObjectWithContent(bucketName, key1, "Eins")
+ putObjectWithContent(bucketName, key2, "Zwei")
then:
def listing = client.listObjects(bucketName)
def summaries = listing.getObjectSummaries()
@@ -191,21 +202,9 @@ abstract class BaseAWSSpec extends BaseSpecification {
}
client.createBucket(bucketName)
and:
- client.putObject(
- bucketName,
- key1,
- new ByteArrayInputStream("Eins".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
- client.putObject(
- bucketName,
- key2,
- new ByteArrayInputStream("Zwei".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
- client.putObject(
- bucketName,
- key3,
- new ByteArrayInputStream("Drei".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
+ putObjectWithContent(bucketName, key1, "Eins")
+ putObjectWithContent(bucketName, key2, "Zwei")
+ putObjectWithContent(bucketName, key3, "Drei")
then:
def listing = client.listObjects(bucketName, DEFAULT_KEY + '/')
def summaries = listing.getObjectSummaries()
@@ -224,11 +223,7 @@ abstract class BaseAWSSpec extends BaseSpecification {
client.createBucket(bucketName)
}
and:
- client.putObject(
- bucketName,
- key,
- new ByteArrayInputStream("Test".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
+ putObjectWithContent(bucketName, key, "Test")
client.deleteBucket(bucketName)
client.getObject(bucketName, key)
then:
@@ -247,7 +242,7 @@ abstract class BaseAWSSpec extends BaseSpecification {
withMultipartUploadThreshold(1).
withMinimumUploadPartSize(1).build()
def meta = new ObjectMetadata()
- def message = "Test".getBytes(Charsets.UTF_8)
+ def message = "Test".getBytes(StandardCharsets.UTF_8)
and:
if (!client.doesBucketExist(bucketName)) {
client.createBucket(bucketName)
@@ -259,7 +254,7 @@ abstract class BaseAWSSpec extends BaseSpecification {
upload.waitForUploadResult()
def content = new String(
ByteStreams.toByteArray(client.getObject(bucketName, key).getObjectContent()),
- Charsets.UTF_8)
+ StandardCharsets.UTF_8)
def userdata = client.getObjectMetadata(bucketName, key).getUserMetaDataOf("userdata")
then:
content == "Test"
@@ -279,7 +274,7 @@ abstract class BaseAWSSpec extends BaseSpecification {
withMultipartUploadThreshold(1).
withMinimumUploadPartSize(1).build()
def meta = new ObjectMetadata()
- def message = "Test".getBytes(Charsets.UTF_8)
+ def message = "Test".getBytes(StandardCharsets.UTF_8)
and:
if (!client.doesBucketExist(bucketName)) {
client.createBucket(bucketName)
@@ -322,7 +317,7 @@ abstract class BaseAWSSpec extends BaseSpecification {
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, key)
URLConnection c = new URL(getClient().generatePresignedUrl(request).toString()).openConnection()
and:
- String downloadedData = new String(ByteStreams.toByteArray(c.getInputStream()), Charsets.UTF_8)
+ String downloadedData = new String(ByteStreams.toByteArray(c.getInputStream()), StandardCharsets.UTF_8)
then:
downloadedData == content
and:
@@ -340,14 +335,10 @@ abstract class BaseAWSSpec extends BaseSpecification {
client.createBucket(bucketName)
}
and:
- client.putObject(
- bucketName,
- key,
- new ByteArrayInputStream("Test".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
+ putObjectWithContent(bucketName, key, "Test")
def content = new String(
ByteStreams.toByteArray(client.getObject(bucketName, key).getObjectContent()),
- Charsets.UTF_8)
+ StandardCharsets.UTF_8)
and:
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, key)
.withExpiration(Date.from(Instant.now().plus(1, ChronoUnit.HOURS)))
@@ -356,7 +347,7 @@ abstract class BaseAWSSpec extends BaseSpecification {
.withContentDisposition("inline; filename=\"hello.txt\""))
URLConnection c = new URL(getClient().generatePresignedUrl(request).toString()).openConnection()
and:
- String downloadedData = new String(ByteStreams.toByteArray(c.getInputStream()), Charsets.UTF_8)
+ String downloadedData = new String(ByteStreams.toByteArray(c.getInputStream()), StandardCharsets.UTF_8)
then:
content == "Test"
and:
@@ -374,21 +365,9 @@ abstract class BaseAWSSpec extends BaseSpecification {
def key3 = DEFAULT_KEY + "/Drei"
def client = getClient()
when:
- client.putObject(
- bucketName,
- key1,
- new ByteArrayInputStream("Eins".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
- client.putObject(
- bucketName,
- key2,
- new ByteArrayInputStream("Zwei".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
- client.putObject(
- bucketName,
- key3,
- new ByteArrayInputStream("Drei".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
+ putObjectWithContent(bucketName, key1, "Eins")
+ putObjectWithContent(bucketName, key2, "Zwei")
+ putObjectWithContent(bucketName, key3, "Drei")
def result = client.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(key1, key2))
then:
result.getDeletedObjects().size() == 2
@@ -411,21 +390,9 @@ abstract class BaseAWSSpec extends BaseSpecification {
def key3 = DEFAULT_KEY + "/Drei"
def client = getClient()
when:
- client.putObject(
- bucketName,
- key1,
- new ByteArrayInputStream("Eins".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
- client.putObject(
- bucketName,
- key2,
- new ByteArrayInputStream("Zwei".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
- client.putObject(
- bucketName,
- key3,
- new ByteArrayInputStream("Drei".getBytes(Charsets.UTF_8)),
- new ObjectMetadata())
+ putObjectWithContent(bucketName, key1, "Eins")
+ putObjectWithContent(bucketName, key2, "Zwei")
+ putObjectWithContent(bucketName, key3, "Drei")
def result = client.listObjectsV2(new ListObjectsV2Request().withBucketName(bucketName).withPrefix(key1))
then:
result.getKeyCount() == 2
@@ -437,4 +404,26 @@ abstract class BaseAWSSpec extends BaseSpecification {
client.deleteObject(bucketName, key2)
client.deleteObject(bucketName, key3)
}
+
+ // reported in https://github.com/scireum/s3ninja/issues/209
+ def "HEAD reports content length correctly"() {
+ given:
+ def bucketName = "public-bucket"
+ def key = "simple_test"
+ def content = "I am pointless text content"
+ def client = getClient()
+ when:
+ createPubliclyAccessibleBucket(bucketName)
+ putObjectWithContent(bucketName, key, content)
+ then:
+ def url = new URL("http://localhost:9999/" + bucketName + "/" + key)
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection()
+ connection.setRequestMethod("HEAD")
+ connection.getResponseCode() == 200
+ connection.getContentLengthLong() == content.getBytes(StandardCharsets.UTF_8).length
+ connection.disconnect()
+ and:
+ client.deleteObject(bucketName, key)
+ client.deleteBucket(bucketName)
+ }
}