kopia lustrzana https://github.com/gaul/s3proxy
rodzic
35b37c34a9
commit
7b937c1571
2
pom.xml
2
pom.xml
|
@ -235,7 +235,7 @@
|
|||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<jclouds.version>1.9.0</jclouds.version>
|
||||
<jclouds.version>1.9.1-SNAPSHOT</jclouds.version>
|
||||
</properties>
|
||||
|
||||
<prerequisites>
|
||||
|
|
|
@ -83,6 +83,7 @@ import org.jclouds.blobstore.domain.BlobMetadata;
|
|||
import org.jclouds.blobstore.domain.ContainerAccess;
|
||||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
import org.jclouds.blobstore.options.CopyOptions;
|
||||
import org.jclouds.blobstore.options.CreateContainerOptions;
|
||||
import org.jclouds.blobstore.options.GetOptions;
|
||||
import org.jclouds.blobstore.options.ListContainerOptions;
|
||||
|
@ -91,6 +92,7 @@ import org.jclouds.domain.Location;
|
|||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
import org.jclouds.io.ContentMetadataBuilder;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.util.Throwables2;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -1093,58 +1095,65 @@ final class S3ProxyHandler extends AbstractHandler {
|
|||
throw new S3Exception(S3ErrorCode.INVALID_REQUEST);
|
||||
}
|
||||
|
||||
Blob blob = blobStore.getBlob(sourceContainerName, sourceBlobName);
|
||||
if (blob == null) {
|
||||
throw new S3Exception(S3ErrorCode.NO_SUCH_KEY);
|
||||
CopyOptions.Builder options = CopyOptions.builder();
|
||||
if (replaceMetadata) {
|
||||
ContentMetadataBuilder contentMetadata =
|
||||
ContentMetadataBuilder.create();
|
||||
ImmutableMap.Builder<String, String> userMetadata =
|
||||
ImmutableMap.builder();
|
||||
for (String headerName : Collections.list(
|
||||
request.getHeaderNames())) {
|
||||
String headerValue = Strings.nullToEmpty(request.getHeader(
|
||||
headerName));
|
||||
if (headerName.equalsIgnoreCase(
|
||||
HttpHeaders.CONTENT_DISPOSITION)) {
|
||||
contentMetadata.contentDisposition(headerValue);
|
||||
} else if (headerName.equalsIgnoreCase(
|
||||
HttpHeaders.CONTENT_ENCODING)) {
|
||||
contentMetadata.contentEncoding(headerValue);
|
||||
} else if (headerName.equalsIgnoreCase(
|
||||
HttpHeaders.CONTENT_LANGUAGE)) {
|
||||
contentMetadata.contentLanguage(headerValue);
|
||||
} else if (headerName.equalsIgnoreCase(
|
||||
HttpHeaders.CONTENT_TYPE)) {
|
||||
contentMetadata.contentType(headerValue);
|
||||
} else if (headerName.toLowerCase().startsWith(
|
||||
USER_METADATA_PREFIX)) {
|
||||
userMetadata.put(
|
||||
headerName.substring(USER_METADATA_PREFIX.length()),
|
||||
headerValue);
|
||||
}
|
||||
// TODO: Expires
|
||||
}
|
||||
options.contentMetadata(contentMetadata.build());
|
||||
options.userMetadata(userMetadata.build());
|
||||
}
|
||||
|
||||
try (InputStream is = blob.getPayload().openStream()) {
|
||||
ContentMetadata metadata = blob.getMetadata().getContentMetadata();
|
||||
long contentLength = metadata.getContentLength();
|
||||
BlobBuilder.PayloadBlobBuilder builder = blobStore
|
||||
.blobBuilder(destBlobName)
|
||||
.payload(is)
|
||||
.contentLength(contentLength);
|
||||
if (replaceMetadata) {
|
||||
addContentMetdataFromHttpRequest(builder, request);
|
||||
} else {
|
||||
builder.contentDisposition(metadata.getContentDisposition())
|
||||
.contentEncoding(metadata.getContentEncoding())
|
||||
.contentLanguage(metadata.getContentLanguage())
|
||||
.contentType(metadata.getContentType())
|
||||
.userMetadata(blob.getMetadata().getUserMetadata());
|
||||
}
|
||||
String eTag = blobStore.copyBlob(
|
||||
sourceContainerName, sourceBlobName,
|
||||
destContainerName, destBlobName, options.build());
|
||||
BlobMetadata blobMetadata = blobStore.blobMetadata(destContainerName,
|
||||
destBlobName);
|
||||
try (Writer writer = response.getWriter()) {
|
||||
XMLStreamWriter xml = xmlOutputFactory.createXMLStreamWriter(
|
||||
writer);
|
||||
xml.writeStartDocument();
|
||||
xml.writeStartElement("CopyObjectResult");
|
||||
xml.writeDefaultNamespace(AWS_XMLNS);
|
||||
|
||||
PutOptions options = new PutOptions();
|
||||
String blobStoreType = getBlobStoreType(blobStore);
|
||||
if (blobStoreType.equals("azureblob") &&
|
||||
contentLength > 64 * 1024 * 1024) {
|
||||
options.multipart(true);
|
||||
}
|
||||
String eTag = blobStore.putBlob(destContainerName,
|
||||
builder.build(), options);
|
||||
Date lastModified = blob.getMetadata().getLastModified();
|
||||
try (Writer writer = response.getWriter()) {
|
||||
XMLStreamWriter xml = xmlOutputFactory.createXMLStreamWriter(
|
||||
writer);
|
||||
xml.writeStartDocument();
|
||||
xml.writeStartElement("CopyObjectResult");
|
||||
xml.writeDefaultNamespace(AWS_XMLNS);
|
||||
xml.writeStartElement("LastModified");
|
||||
xml.writeCharacters(blobStore.getContext().utils().date()
|
||||
.iso8601DateFormat(blobMetadata.getLastModified()));
|
||||
xml.writeEndElement();
|
||||
|
||||
xml.writeStartElement("LastModified");
|
||||
xml.writeCharacters(blobStore.getContext().utils().date()
|
||||
.iso8601DateFormat(lastModified));
|
||||
xml.writeEndElement();
|
||||
xml.writeStartElement("ETag");
|
||||
xml.writeCharacters("\"" + eTag + "\"");
|
||||
xml.writeEndElement();
|
||||
|
||||
xml.writeStartElement("ETag");
|
||||
xml.writeCharacters("\"" + eTag + "\"");
|
||||
xml.writeEndElement();
|
||||
|
||||
xml.writeEndElement();
|
||||
xml.flush();
|
||||
} catch (XMLStreamException xse) {
|
||||
throw new IOException(xse);
|
||||
}
|
||||
xml.writeEndElement();
|
||||
xml.flush();
|
||||
} catch (XMLStreamException xse) {
|
||||
throw new IOException(xse);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
|
||||
|
@ -27,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.io.ByteSource;
|
||||
import com.google.common.io.Resources;
|
||||
|
@ -44,10 +47,13 @@ import org.jclouds.blobstore.domain.Blob;
|
|||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
import org.jclouds.blobstore.options.CopyOptions;
|
||||
import org.jclouds.blobstore.options.ListContainerOptions;
|
||||
import org.jclouds.blobstore.options.PutOptions;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
import org.jclouds.io.ContentMetadataBuilder;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.payloads.ByteSourcePayload;
|
||||
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
|
||||
|
@ -388,6 +394,114 @@ public final class S3ProxyTest {
|
|||
new PutOptions().multipart(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyObjectPreserveMetadata() throws Exception {
|
||||
String fromName = "from-name";
|
||||
String toName = "to-name";
|
||||
ByteSource byteSource = ByteSource.wrap(new byte[42]);
|
||||
String contentDisposition = "attachment; filename=old.jpg";
|
||||
String contentEncoding = "gzip";
|
||||
String contentLanguage = "en";
|
||||
String contentType = "audio/ogg";
|
||||
Date expires = new Date(1000);
|
||||
Map<String, String> userMetadata = ImmutableMap.of(
|
||||
"key1", "value1",
|
||||
"key2", "value2");
|
||||
Blob fromBlob = s3BlobStore.blobBuilder(fromName)
|
||||
.payload(byteSource)
|
||||
.contentLength(byteSource.size())
|
||||
.contentDisposition(contentDisposition)
|
||||
.contentEncoding(contentEncoding)
|
||||
.contentLanguage(contentLanguage)
|
||||
.contentType(contentType)
|
||||
.expires(expires)
|
||||
.userMetadata(userMetadata)
|
||||
.build();
|
||||
s3BlobStore.putBlob(containerName, fromBlob);
|
||||
|
||||
s3BlobStore.copyBlob(containerName, fromName, containerName, toName,
|
||||
CopyOptions.NONE);
|
||||
|
||||
Blob toBlob = s3BlobStore.getBlob(containerName, toName);
|
||||
try (InputStream actual = toBlob.getPayload().openStream();
|
||||
InputStream expected = byteSource.openStream()) {
|
||||
assertThat(actual).hasContentEqualTo(expected);
|
||||
}
|
||||
ContentMetadata contentMetadata =
|
||||
toBlob.getMetadata().getContentMetadata();
|
||||
assertThat(contentMetadata.getContentDisposition()).isEqualTo(
|
||||
contentDisposition);
|
||||
assertThat(contentMetadata.getContentEncoding()).isEqualTo(
|
||||
contentEncoding);
|
||||
assertThat(contentMetadata.getContentLanguage()).isEqualTo(
|
||||
contentLanguage);
|
||||
assertThat(contentMetadata.getContentType()).isEqualTo(
|
||||
contentType);
|
||||
// TODO: expires
|
||||
assertThat(toBlob.getMetadata().getUserMetadata()).isEqualTo(
|
||||
userMetadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyObjectReplaceMetadata() throws Exception {
|
||||
String fromName = "from-name";
|
||||
String toName = "to-name";
|
||||
ByteSource byteSource = ByteSource.wrap(new byte[42]);
|
||||
Blob fromBlob = s3BlobStore.blobBuilder(fromName)
|
||||
.payload(byteSource)
|
||||
.contentLength(byteSource.size())
|
||||
.contentDisposition("attachment; filename=old.jpg")
|
||||
.contentEncoding("compress")
|
||||
.contentLanguage("en")
|
||||
.contentType("audio/ogg")
|
||||
.expires(new Date(1000))
|
||||
.userMetadata(ImmutableMap.of(
|
||||
"key1", "value1",
|
||||
"key2", "value2"))
|
||||
.build();
|
||||
s3BlobStore.putBlob(containerName, fromBlob);
|
||||
|
||||
String contentDisposition = "attachment; filename=new.jpg";
|
||||
String contentEncoding = "gzip";
|
||||
String contentLanguage = "fr";
|
||||
String contentType = "audio/mp4";
|
||||
Date expires = new Date(2000);
|
||||
ContentMetadata contentMetadata = ContentMetadataBuilder.create()
|
||||
.contentDisposition(contentDisposition)
|
||||
.contentEncoding(contentEncoding)
|
||||
.contentLanguage(contentLanguage)
|
||||
.contentType(contentType)
|
||||
.expires(expires)
|
||||
.build();
|
||||
Map<String, String> userMetadata = ImmutableMap.of(
|
||||
"key3", "value3",
|
||||
"key4", "value4");
|
||||
s3BlobStore.copyBlob(containerName, fromName, containerName, toName,
|
||||
CopyOptions.builder()
|
||||
.contentMetadata(contentMetadata)
|
||||
.userMetadata(userMetadata)
|
||||
.build());
|
||||
|
||||
Blob toBlob = s3BlobStore.getBlob(containerName, toName);
|
||||
try (InputStream actual = toBlob.getPayload().openStream();
|
||||
InputStream expected = byteSource.openStream()) {
|
||||
assertThat(actual).hasContentEqualTo(expected);
|
||||
}
|
||||
ContentMetadata toContentMetadata =
|
||||
toBlob.getMetadata().getContentMetadata();
|
||||
assertThat(toContentMetadata.getContentDisposition()).isEqualTo(
|
||||
contentDisposition);
|
||||
assertThat(toContentMetadata.getContentEncoding()).isEqualTo(
|
||||
contentEncoding);
|
||||
assertThat(toContentMetadata.getContentLanguage()).isEqualTo(
|
||||
contentLanguage);
|
||||
assertThat(toContentMetadata.getContentType()).isEqualTo(
|
||||
contentType);
|
||||
// TODO: expires
|
||||
assertThat(toBlob.getMetadata().getUserMetadata()).isEqualTo(
|
||||
userMetadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnknownParameter() throws Exception {
|
||||
S3Client s3Client = s3Context.unwrapApi(S3Client.class);
|
||||
|
|
Ładowanie…
Reference in New Issue