diff --git a/pkg/chart/locator.go b/pkg/chart/locator.go
index 509876247f8aeeeec423f2022fc0ce306427289c..749a838741781c6d9297ebe4fb1aa12e7300b95f 100644
--- a/pkg/chart/locator.go
+++ b/pkg/chart/locator.go
@@ -34,6 +34,8 @@ var ErrRemote = errors.New("cannot use remote Locator as local")
 const (
 	SchemeHTTP  = "http"
 	SchemeHTTPS = "https"
+	SchemeGS    = "gs"
+	SchemeS3    = "s3"
 	SchemeHelm  = "helm"
 	SchemeFile  = "file"
 )
@@ -85,6 +87,7 @@ func Parse(path string) (*Locator, error) {
 		if len(parts) < 3 {
 			return nil, fmt.Errorf("both bucket and chart name are required in %s: %s", path, u.Path)
 		}
+
 		// Need to parse opaque data into bucket and chart.
 		return &Locator{
 			Scheme:   u.Scheme,
@@ -115,6 +118,26 @@ func Parse(path string) (*Locator, error) {
 			Version:  version,
 			original: path,
 		}, nil
+	case SchemeGS, SchemeS3:
+		// Long name
+		parts := strings.SplitN(u.Path, "/", 2)
+		if len(parts) < 2 {
+			return nil, fmt.Errorf("chart name is required in %s", path)
+		}
+
+		name, version, err := parseTarName(parts[1])
+		if err != nil {
+			return nil, err
+		}
+
+		return &Locator{
+			Scheme:   u.Scheme,
+			Host:     u.Scheme,
+			Bucket:   u.Host,
+			Name:     name,
+			Version:  version,
+			original: path,
+		}, nil
 	case SchemeFile:
 		return &Locator{
 			LocalRef: u.Path,
@@ -153,6 +176,7 @@ func (u *Locator) Short() (string, error) {
 	if u.IsLocal() {
 		return "", ErrLocal
 	}
+
 	fname := fmt.Sprintf("%s/%s/%s", u.Host, u.Bucket, u.Name)
 	return (&url.URL{
 		Scheme:   SchemeHelm,
@@ -171,18 +195,30 @@ func (u *Locator) Long(secure bool) (string, error) {
 		return "", ErrLocal
 	}
 
-	scheme := SchemeHTTPS
-	if !secure {
-		scheme = SchemeHTTP
+	scheme := u.Scheme
+	host := u.Host
+	switch scheme {
+	case SchemeGS, SchemeS3:
+		host = ""
+	case SchemeHTTP, SchemeHTTPS, SchemeHelm:
+		switch host {
+		case SchemeGS, SchemeS3:
+			scheme = host
+			host = ""
+		default:
+			scheme = SchemeHTTPS
+			if !secure {
+				scheme = SchemeHTTP
+			}
+		}
 	}
-	fname := fmt.Sprintf("%s/%s-%s.tgz", u.Bucket, u.Name, u.Version)
 
+	fname := fmt.Sprintf("%s/%s-%s.tgz", u.Bucket, u.Name, u.Version)
 	return (&url.URL{
 		Scheme: scheme,
-		Host:   u.Host,
+		Host:   host,
 		Path:   fname,
 	}).String(), nil
-
 }
 
 // parseTarName parses a long-form tarfile name.
diff --git a/pkg/chart/locator_test.go b/pkg/chart/locator_test.go
index 67bfcf7519cd48f94882b590a1125784b55a46da..dbafae114dc99da86693624c6c4dadebc0d52007 100644
--- a/pkg/chart/locator_test.go
+++ b/pkg/chart/locator_test.go
@@ -64,8 +64,12 @@ func TestShort(t *testing.T) {
 	tests := map[string]string{
 		"https://example.com/foo/bar-1.2.3.tgz": "helm:example.com/foo/bar#1.2.3",
 		"http://example.com/foo/bar-1.2.3.tgz":  "helm:example.com/foo/bar#1.2.3",
+		"gs://foo/bar-1.2.3.tgz":                "helm:gs/foo/bar#1.2.3",
+		"s3://foo/bar-1.2.3.tgz":                "helm:s3/foo/bar#1.2.3",
 		"helm:example.com/foo/bar#1.2.3":        "helm:example.com/foo/bar#1.2.3",
 		"helm:example.com/foo/bar#>1.2.3":       "helm:example.com/foo/bar#%3E1.2.3",
+		"helm:gs/foo/bar#1.2.3":                 "helm:gs/foo/bar#1.2.3",
+		"helm:s3/foo/bar#>1.2.3":                "helm:s3/foo/bar#%3E1.2.3",
 	}
 
 	for start, expect := range tests {
@@ -74,6 +78,9 @@ func TestShort(t *testing.T) {
 			t.Errorf("Failed to parse: %s", err)
 			continue
 		}
+
+		t.Logf("Parsed reference %s into locator %#v", start, u)
+
 		short, err := u.Short()
 		if err != nil {
 			t.Errorf("Failed to generate short: %s", err)
@@ -103,8 +110,12 @@ func TestLong(t *testing.T) {
 	tests := map[string]string{
 		"https://example.com/foo/bar-1.2.3.tgz": "https://example.com/foo/bar-1.2.3.tgz",
 		"http://example.com/foo/bar-1.2.3.tgz":  "https://example.com/foo/bar-1.2.3.tgz",
+		"gs://foo/bar-1.2.3.tgz":                "gs://foo/bar-1.2.3.tgz",
+		"s3://foo/bar-1.2.3.tgz":                "s3://foo/bar-1.2.3.tgz",
 		"helm:example.com/foo/bar#1.2.3":        "https://example.com/foo/bar-1.2.3.tgz",
 		"helm:example.com/foo/bar#>1.2.3":       "https://example.com/foo/bar-%3E1.2.3.tgz",
+		"helm:gs/foo/bar#1.2.3":                 "gs://foo/bar-1.2.3.tgz",
+		"helm:s3/foo/bar#>1.2.3":                "s3://foo/bar-%3E1.2.3.tgz",
 	}
 
 	for start, expect := range tests {
@@ -114,6 +125,9 @@ func TestLong(t *testing.T) {
 			t.Errorf("Failed to parse: %s", err)
 			continue
 		}
+
+		t.Logf("Parsed reference %s into locator %#v", start, u)
+
 		long, err := u.Long(true)
 		if err != nil {
 			t.Errorf("Failed to generate long: %s", err)