kopia lustrzana https://github.com/gaul/s3proxy
URL encode blob names when client requests it
This allows support for characters which XML 1.0 cannot represent and improves compatibility with newer versions of the AWS CLI. Fixes #104.pull/102/merge
rodzic
23cff3a61d
commit
d8c73bc86d
|
@ -23,8 +23,10 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.PushbackInputStream;
|
import java.io.PushbackInputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
@ -140,6 +142,7 @@ final class S3ProxyHandler extends AbstractHandler {
|
||||||
"AWSAccessKeyId",
|
"AWSAccessKeyId",
|
||||||
"delete",
|
"delete",
|
||||||
"delimiter",
|
"delimiter",
|
||||||
|
"encoding-type",
|
||||||
"Expires",
|
"Expires",
|
||||||
"location",
|
"location",
|
||||||
"marker",
|
"marker",
|
||||||
|
@ -955,6 +958,7 @@ final class S3ProxyHandler extends AbstractHandler {
|
||||||
String blobStoreType = getBlobStoreType(blobStore);
|
String blobStoreType = getBlobStoreType(blobStore);
|
||||||
ListContainerOptions options = new ListContainerOptions();
|
ListContainerOptions options = new ListContainerOptions();
|
||||||
String delimiter = request.getParameter("delimiter");
|
String delimiter = request.getParameter("delimiter");
|
||||||
|
String encodingType = request.getParameter("encoding-type");
|
||||||
if (delimiter != null) {
|
if (delimiter != null) {
|
||||||
options.delimiter(delimiter);
|
options.delimiter(delimiter);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1002,7 +1006,8 @@ final class S3ProxyHandler extends AbstractHandler {
|
||||||
if (prefix == null) {
|
if (prefix == null) {
|
||||||
xml.writeEmptyElement("Prefix");
|
xml.writeEmptyElement("Prefix");
|
||||||
} else {
|
} else {
|
||||||
writeSimpleElement(xml, "Prefix", prefix);
|
writeSimpleElement(xml, "Prefix", encodeBlob(
|
||||||
|
request.getParameter("encoding-type"), prefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
writeSimpleElement(xml, "MaxKeys", String.valueOf(maxKeys));
|
writeSimpleElement(xml, "MaxKeys", String.valueOf(maxKeys));
|
||||||
|
@ -1010,17 +1015,24 @@ final class S3ProxyHandler extends AbstractHandler {
|
||||||
if (marker == null) {
|
if (marker == null) {
|
||||||
xml.writeEmptyElement("Marker");
|
xml.writeEmptyElement("Marker");
|
||||||
} else {
|
} else {
|
||||||
writeSimpleElement(xml, "Marker", marker);
|
writeSimpleElement(xml, "Marker", encodeBlob(
|
||||||
|
request.getParameter("encoding-type"), marker));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delimiter != null) {
|
if (delimiter != null) {
|
||||||
writeSimpleElement(xml, "Delimiter", delimiter);
|
writeSimpleElement(xml, "Delimiter", encodeBlob(
|
||||||
|
request.getParameter("encoding-type"), delimiter));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encodingType != null && encodingType.equals("url")) {
|
||||||
|
writeSimpleElement(xml, "Encoding-Type", encodingType);
|
||||||
}
|
}
|
||||||
|
|
||||||
String nextMarker = set.getNextMarker();
|
String nextMarker = set.getNextMarker();
|
||||||
if (nextMarker != null) {
|
if (nextMarker != null) {
|
||||||
writeSimpleElement(xml, "IsTruncated", "true");
|
writeSimpleElement(xml, "IsTruncated", "true");
|
||||||
writeSimpleElement(xml, "NextMarker", nextMarker);
|
writeSimpleElement(xml, "NextMarker", encodeBlob(
|
||||||
|
request.getParameter("encoding-type"), nextMarker));
|
||||||
if (BLOBSTORE_OPAQUE_MARKERS.contains(blobStoreType)) {
|
if (BLOBSTORE_OPAQUE_MARKERS.contains(blobStoreType)) {
|
||||||
lastKeyToMarker.put(Maps.immutableEntry(containerName,
|
lastKeyToMarker.put(Maps.immutableEntry(containerName,
|
||||||
Iterables.getLast(set).getName()), nextMarker);
|
Iterables.getLast(set).getName()), nextMarker);
|
||||||
|
@ -1649,6 +1661,8 @@ final class S3ProxyHandler extends AbstractHandler {
|
||||||
|
|
||||||
List<MultipartPart> parts = blobStore.listMultipartUpload(mpu);
|
List<MultipartPart> parts = blobStore.listMultipartUpload(mpu);
|
||||||
|
|
||||||
|
String encodingType = request.getParameter("encoding-type");
|
||||||
|
|
||||||
try (Writer writer = response.getWriter()) {
|
try (Writer writer = response.getWriter()) {
|
||||||
XMLStreamWriter xml = xmlOutputFactory.createXMLStreamWriter(
|
XMLStreamWriter xml = xmlOutputFactory.createXMLStreamWriter(
|
||||||
writer);
|
writer);
|
||||||
|
@ -1656,8 +1670,13 @@ final class S3ProxyHandler extends AbstractHandler {
|
||||||
xml.writeStartElement("ListPartsResult");
|
xml.writeStartElement("ListPartsResult");
|
||||||
xml.writeDefaultNamespace(AWS_XMLNS);
|
xml.writeDefaultNamespace(AWS_XMLNS);
|
||||||
|
|
||||||
|
if (encodingType != null && encodingType.equals("url")) {
|
||||||
|
writeSimpleElement(xml, "Encoding-Type", encodingType);
|
||||||
|
}
|
||||||
|
|
||||||
writeSimpleElement(xml, "Bucket", containerName);
|
writeSimpleElement(xml, "Bucket", containerName);
|
||||||
writeSimpleElement(xml, "Key", blobName);
|
writeSimpleElement(xml, "Key", encodeBlob(
|
||||||
|
request.getParameter("encoding-type"), blobName));
|
||||||
writeSimpleElement(xml, "UploadId", uploadId);
|
writeSimpleElement(xml, "UploadId", uploadId);
|
||||||
|
|
||||||
// TODO: bogus values
|
// TODO: bogus values
|
||||||
|
@ -2283,4 +2302,18 @@ final class S3ProxyHandler extends AbstractHandler {
|
||||||
private static boolean startsWithIgnoreCase(String string, String prefix) {
|
private static boolean startsWithIgnoreCase(String string, String prefix) {
|
||||||
return string.toLowerCase().startsWith(prefix.toLowerCase());
|
return string.toLowerCase().startsWith(prefix.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode blob name if client requests it. This allows for characters
|
||||||
|
// which XML 1.0 cannot represent.
|
||||||
|
private static String encodeBlob(String encodingType, String blobName) {
|
||||||
|
if (encodingType != null && encodingType.equals("url")) {
|
||||||
|
try {
|
||||||
|
return URLEncoder.encode(blobName, "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw Throwables.propagate(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return blobName;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue