kopia lustrzana https://github.com/gaul/s3proxy
rodzic
34db5cae9a
commit
452d8d366c
|
@ -22,6 +22,7 @@ import java.io.InputStream;
|
|||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
|
@ -51,7 +52,7 @@ public final class S3Proxy {
|
|||
|
||||
S3Proxy(BlobStore blobStore, URI endpoint, String identity,
|
||||
String credential, String keyStorePath, String keyStorePassword,
|
||||
boolean forceMultiPartUpload) {
|
||||
boolean forceMultiPartUpload, Optional<String> virtualHost) {
|
||||
Preconditions.checkNotNull(blobStore);
|
||||
Preconditions.checkNotNull(endpoint);
|
||||
// TODO: allow service paths?
|
||||
|
@ -75,7 +76,7 @@ public final class S3Proxy {
|
|||
connector.setPort(endpoint.getPort());
|
||||
server.addConnector(connector);
|
||||
server.setHandler(new S3ProxyHandler(blobStore, identity, credential,
|
||||
forceMultiPartUpload));
|
||||
forceMultiPartUpload, virtualHost));
|
||||
}
|
||||
|
||||
public void start() throws Exception {
|
||||
|
@ -158,6 +159,9 @@ public final class S3Proxy {
|
|||
|
||||
String forceMultiPartUpload = properties.getProperty(
|
||||
S3ProxyConstants.PROPERTY_FORCE_MULTI_PART_UPLOAD);
|
||||
Optional<String> virtualHost = Optional.fromNullable(
|
||||
properties.getProperty(
|
||||
S3ProxyConstants.PROPERTY_VIRTUAL_HOST));
|
||||
|
||||
ContextBuilder builder = ContextBuilder
|
||||
.newBuilder(provider)
|
||||
|
@ -171,7 +175,7 @@ public final class S3Proxy {
|
|||
S3Proxy s3Proxy = new S3Proxy(context.getBlobStore(), s3ProxyEndpoint,
|
||||
localIdentity, localCredential, keyStorePath,
|
||||
keyStorePassword,
|
||||
"true".equalsIgnoreCase(forceMultiPartUpload));
|
||||
"true".equalsIgnoreCase(forceMultiPartUpload), virtualHost);
|
||||
s3Proxy.start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,14 @@ public final class S3ProxyConstants {
|
|||
/** Force all proxy-server put objects to use multi-part upload. */
|
||||
public static final String PROPERTY_FORCE_MULTI_PART_UPLOAD =
|
||||
"s3proxy.force-multi-part-upload";
|
||||
/**
|
||||
* Configure servicing of virtual host buckets. Setting to localhost:8080
|
||||
* allows bucket-in-hostname requests, e.g., bucketname.localhost:8080.
|
||||
* This mode requires configuring DNS to forward all requests to the
|
||||
* S3Proxy host.
|
||||
*/
|
||||
public static final String PROPERTY_VIRTUAL_HOST =
|
||||
"s3proxy.virtual-host";
|
||||
|
||||
private S3ProxyConstants() {
|
||||
throw new AssertionError("Cannot instantiate utility constructor");
|
||||
|
|
|
@ -99,13 +99,15 @@ final class S3ProxyHandler extends AbstractHandler {
|
|||
private final String identity;
|
||||
private final String credential;
|
||||
private final boolean forceMultiPartUpload;
|
||||
private final Optional<String> virtualHost;
|
||||
|
||||
S3ProxyHandler(BlobStore blobStore, String identity, String credential,
|
||||
boolean forceMultiPartUpload) {
|
||||
boolean forceMultiPartUpload, Optional<String> virtualHost) {
|
||||
this.blobStore = Preconditions.checkNotNull(blobStore);
|
||||
this.identity = identity;
|
||||
this.credential = credential;
|
||||
this.forceMultiPartUpload = forceMultiPartUpload;
|
||||
this.virtualHost = Preconditions.checkNotNull(virtualHost);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -114,8 +116,17 @@ final class S3ProxyHandler extends AbstractHandler {
|
|||
throws IOException {
|
||||
String method = request.getMethod();
|
||||
String uri = request.getRequestURI();
|
||||
String[] path = uri.split("/", 3);
|
||||
logger.debug("request: {}", request);
|
||||
String hostHeader = request.getHeader(HttpHeaders.HOST);
|
||||
if (hostHeader != null && virtualHost.isPresent()) {
|
||||
String virtualHostSuffix = "." + virtualHost.get();
|
||||
if (hostHeader.endsWith(virtualHostSuffix)) {
|
||||
String bucket = hostHeader.substring(0,
|
||||
hostHeader.length() - virtualHostSuffix.length());
|
||||
uri = "/" + bucket + uri;
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasDateHeader = false;
|
||||
boolean hasXAmzDateHeader = false;
|
||||
for (String headerName : Collections.list(request.getHeaderNames())) {
|
||||
|
@ -167,7 +178,7 @@ final class S3ProxyHandler extends AbstractHandler {
|
|||
|
||||
if (identity != null) {
|
||||
String expectedSignature = createAuthorizationSignature(request,
|
||||
identity, credential);
|
||||
uri, identity, credential);
|
||||
String headerAuthorization = request.getHeader(
|
||||
HttpHeaders.AUTHORIZATION);
|
||||
String headerIdentity = null;
|
||||
|
@ -224,6 +235,7 @@ final class S3ProxyHandler extends AbstractHandler {
|
|||
}
|
||||
}
|
||||
|
||||
String[] path = uri.split("/", 3);
|
||||
switch (method) {
|
||||
case "DELETE":
|
||||
if (path.length <= 2 || path[2].isEmpty()) {
|
||||
|
@ -927,7 +939,8 @@ final class S3ProxyHandler extends AbstractHandler {
|
|||
* http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html
|
||||
*/
|
||||
private static String createAuthorizationSignature(
|
||||
HttpServletRequest request, String identity, String credential) {
|
||||
HttpServletRequest request, String uri, String identity,
|
||||
String credential) {
|
||||
// sort Amazon headers
|
||||
SortedSetMultimap<String, String> canonicalizedHeaders =
|
||||
TreeMultimap.create();
|
||||
|
@ -971,7 +984,7 @@ final class S3ProxyHandler extends AbstractHandler {
|
|||
builder.append(entry.getKey()).append(':')
|
||||
.append(entry.getValue()).append('\n');
|
||||
}
|
||||
builder.append(request.getRequestURI());
|
||||
builder.append(uri);
|
||||
if ("".equals(request.getParameter("acl"))) {
|
||||
builder.append("?acl");
|
||||
} else if ("".equals(request.getParameter("delete"))) {
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Random;
|
|||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
@ -88,6 +89,9 @@ public final class S3ProxyTest {
|
|||
S3ProxyConstants.PROPERTY_KEYSTORE_PASSWORD);
|
||||
String forceMultiPartUpload = s3ProxyProperties.getProperty(
|
||||
S3ProxyConstants.PROPERTY_FORCE_MULTI_PART_UPLOAD);
|
||||
Optional<String> virtualHost = Optional.fromNullable(
|
||||
s3ProxyProperties.getProperty(
|
||||
S3ProxyConstants.PROPERTY_VIRTUAL_HOST));
|
||||
|
||||
Properties properties = new Properties();
|
||||
ContextBuilder builder = ContextBuilder
|
||||
|
@ -116,7 +120,7 @@ public final class S3ProxyTest {
|
|||
s3Proxy = new S3Proxy(blobStore, s3Endpoint, s3Identity, s3Credential,
|
||||
Resources.getResource(keyStorePath).toString(),
|
||||
keyStorePassword,
|
||||
"true".equalsIgnoreCase(forceMultiPartUpload));
|
||||
"true".equalsIgnoreCase(forceMultiPartUpload), virtualHost);
|
||||
s3Proxy.start();
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue