Deep copy Blob in LocalBlobStore.getBlob
ByteSourcePayload.openStream is not thread safe and lack of
synchronization can throw ArrayIndexOutOfBoundsExceptions. Instead
deep copy the underlying Payload. Fixes gaul/s3proxy#303.
diff --git a/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java b/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java
index 76a66b4..ca1b1c8 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java
@@ -162,7 +162,22 @@
@Override
public Blob getBlob(final String containerName, final String blobName) {
Map<String, Blob> map = containerToBlobs.get(containerName);
- return map == null ? null : map.get(blobName);
+ if (map == null) {
+ return null;
+ }
+ Blob blob = map.get(blobName);
+ if (blob == null) {
+ return null;
+ }
+
+ // Deep copy Blob to make sure ByteSourcePayload does not share Closer.
+ Payload payload = blob.getPayload();
+ MutableContentMetadata md = payload.getContentMetadata();
+ Blob newBlob = blobFactory.create(BlobStoreUtils.copy(blob.getMetadata()));
+ Payload newPayload = Payloads.newPayload(payload.getRawContent());
+ newBlob.setPayload(payload);
+ HttpUtils.copy(md, newPayload.getContentMetadata());
+ return newBlob;
}
@Override