com.eucalyptus.cloudformation.template.url.S3Helper.java Source code

Java tutorial

Introduction

Here is the source code for com.eucalyptus.cloudformation.template.url.S3Helper.java

Source

/*************************************************************************
 * Copyright 2009-2014 Eucalyptus Systems, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses/.
 *
 * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta
 * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need
 * additional information or have any questions.
 ************************************************************************/
package com.eucalyptus.cloudformation.template.url;

import com.eucalyptus.cloudformation.ValidationErrorException;
import com.google.common.net.InetAddresses;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.StringTokenizer;

/**
 * Created by ethomas on 9/21/14.
 */
public class S3Helper {

    public static BucketAndKey getBucketAndKeyFromUrl(URL url, String[] validServicePaths,
            String[] validHostBucketSuffixes, String[] validDomains) throws ValidationErrorException {
        if (url.getHost() == null || url.getPath() == null) {
            throw new ValidationErrorException("Invalid S3 " + url);
        }
        // We may not get every form of possible URLs right at this point, but we will allow 3 types
        // 1) http://<ip address>/<service_path>/bucket/key  (No address checks will be done)
        // 2) Valid external domain, including something with ".objectstorage" or ".walrus".  In this case bucket name is first, and key is path
        // 3) Valid external domain, must start with objectstorage or walrus.  In this case bucket name is part of the path
        // 4) Valid external domain, with no objectstorage or walrus.  In this case there must be a service path, and /bucket/key will be assumed to be there.
        if (InetAddresses.isInetAddress(url.getHost())) {
            // must end in valid service path...
            for (String validServicePath : validServicePaths) {
                if (url.getPath().startsWith(validServicePath)) {
                    return getBucketAndKeyFromPath(url.getPath().substring(validServicePath.length()), url);
                }
            }
            throw new ValidationErrorException(
                    "Invalid S3 url" + url + ", contains IP address but no OSG service path");
        }

        for (String validDomain : validDomains) {
            // DNS case insensitive
            String hostLower = url.getHost().toLowerCase();
            String validDomainLower = validDomain.toLowerCase();
            if (hostLower.endsWith(validDomainLower)) {
                // check bucket style...
                for (String validHostBucketSuffix : validHostBucketSuffixes) {
                    String validHostNameBucketNameSuffixLower = validHostBucketSuffix.toLowerCase();
                    if (hostLower.contains("." + validHostNameBucketNameSuffixLower)) {
                        String bucket = hostLower.substring(0,
                                hostLower.indexOf("." + validHostNameBucketNameSuffixLower));
                        return getBucketAndKeyFromPath(bucket + "/" + url.getPath(), url);
                    }
                }
                // check beginnings
                for (String validHostBucketSuffix : validHostBucketSuffixes) {
                    String validHostNameBucketNameSuffixLower = validHostBucketSuffix.toLowerCase();
                    if (hostLower.startsWith(validHostNameBucketNameSuffixLower + ".")) {
                        return getBucketAndKeyFromPath(url.getPath(), url);
                    }
                }
                // check service path
                for (String validServicePath : validServicePaths) {
                    if (url.getPath().startsWith(validServicePath)) {
                        return getBucketAndKeyFromPath(url.getPath().substring(validServicePath.length()), url);
                    }
                }
            }
        }
        throw new ValidationErrorException("Invalid S3 url " + url + ", does not match any known S3 domains");
    }

    private static BucketAndKey getBucketAndKeyFromPath(String path, URL url) throws ValidationErrorException {
        try {
            StringTokenizer stok = new StringTokenizer(path, "/");
            String bucket = URLDecoder.decode(stok.nextToken());
            String delimiter = "";
            StringBuilder keyBuilder = new StringBuilder();
            do {
                keyBuilder.append(delimiter).append(URLDecoder.decode(stok.nextToken()));
                delimiter = "/";
            } while (stok.hasMoreTokens()); // must have at least one token for key, otherwise not valid
            return new BucketAndKey(bucket, keyBuilder.toString());

        } catch (Exception ex) {
            throw new ValidationErrorException("S3 URL " + url + " parses to invalid bucket/key pairs.");
        }
    }

    public static class BucketAndKey {
        String bucket;
        String key;

        BucketAndKey(String bucket, String key) {
            this.bucket = bucket;
            this.key = key;
        }

        public String getBucket() {
            return bucket;
        }

        public String getKey() {
            return key;
        }

        @Override
        public String toString() {
            return "BucketAndKey{" + "bucket='" + bucket + '\'' + ", key='" + key + '\'' + '}';
        }
    }

    //  public static void main(String[] args) throws MalformedURLException, ValidationErrorException {
    //    String[] validDomains = new String[]{"h-14.autoqa.qa1.eucalyptus-systems.com"};
    //    String[] validServicePaths = new String[]{"/services/objectstorage","/services/walrus"};
    //    String[] validHostNameBucketNameSuffixes = new String[]{"walrus","objectstorage"};
    //    System.out.println(getBucketAndKeyFromUrl(new URL("http://10.0.0.10/services/objectstorage/path/to/my/key/a+b"), validServicePaths, validHostNameBucketNameSuffixes, validDomains));
    //    System.out.println(getBucketAndKeyFromUrl(new URL("http://10.0.0.10/services/walrus/path/to/my/key/a+b"), validServicePaths, validHostNameBucketNameSuffixes, validDomains));
    //    System.out.println(getBucketAndKeyFromUrl(new URL("http://boots.objectstorage.h-14.autoqa.qa1.eucalyptus-systems.com/key"), validServicePaths, validHostNameBucketNameSuffixes, validDomains));
    //    System.out.println(getBucketAndKeyFromUrl(new URL("http://boots.walrus.h-14.autoqa.qa1.eucalyptus-systems.com/key"), validServicePaths, validHostNameBucketNameSuffixes, validDomains));
    //    System.out.println(getBucketAndKeyFromUrl(new URL("http://walrus.h-14.autoqa.qa1.eucalyptus-systems.com/boots/key"), validServicePaths, validHostNameBucketNameSuffixes, validDomains));
    //    System.out.println(getBucketAndKeyFromUrl(new URL("http://walrus.h-14.autoqa.qa1.eucalyptus-systems.com/boots/key"), validServicePaths, validHostNameBucketNameSuffixes, validDomains));
    //    System.out.println(getBucketAndKeyFromUrl(new URL("http://walrus.h-15.autoqa.qa1.eucalyptus-systems.com/boots/key"), validServicePaths, validHostNameBucketNameSuffixes, validDomains));
    //  }
}