1
0
mirror of https://github.com/minio/mc.git synced 2025-11-13 12:22:45 +03:00
Files
mc/pkg/s3/client.go
Harshavardhana d1550045b3 Donut command
2015-03-22 20:03:39 -07:00

154 lines
4.2 KiB
Go

// Original license //
// ---------------- //
/*
Copyright 2011 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// All other modifications and improvements //
// ---------------------------------------- //
/*
* Minimalist Object Storage, (C) 2015 Minio, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Package s3 implements a generic Amazon S3 client
package s3
import (
"fmt"
"io"
"net"
"net/http"
"net/url"
"regexp"
"strings"
"encoding/xml"
"github.com/minio-io/mc/pkg/client"
)
// Total max object list
const (
MaxKeys = 1000
)
type listBucketResults struct {
Contents []*client.Item
IsTruncated bool
MaxKeys int
Name string // bucket name
Marker string
Delimiter string
Prefix string
CommonPrefixes []*client.Prefix
}
type s3Client struct {
*client.Meta
}
// GetNewClient returns an initialized s3Client structure.
func GetNewClient(auth *client.Auth, u *url.URL, transport http.RoundTripper) client.Client {
return &s3Client{&client.Meta{
Auth: auth,
Transport: GetNewTraceTransport(s3Verify{}, transport),
URL: u,
}}
}
// bucketURL returns the URL prefix of the bucket, with trailing slash
func (c *s3Client) bucketURL(bucket string) string {
var url string
if IsValidBucket(bucket) && !strings.Contains(bucket, ".") {
// if localhost use PathStyle
if strings.Contains(c.URL.Host, "localhost") || strings.Contains(c.URL.Host, "127.0.0.1") {
return fmt.Sprintf("%s://%s/%s", c.URL.Scheme, c.URL.Host, bucket)
}
// Verify if its ip address, use PathStyle
host, _, _ := net.SplitHostPort(c.URL.Host)
if net.ParseIP(host) != nil {
return fmt.Sprintf("%s://%s/%s", c.URL.Scheme, c.URL.Host, bucket)
}
// For DNS hostname or amazonaws.com use subdomain style
url = fmt.Sprintf("%s://%s.%s/", c.URL.Scheme, bucket, c.URL.Host)
}
return url
}
func (c *s3Client) keyURL(bucket, key string) string {
url := c.bucketURL(bucket)
if strings.Contains(c.URL.Host, "localhost") || strings.Contains(c.URL.Host, "127.0.0.1") {
return url + "/" + key
}
host, _, _ := net.SplitHostPort(c.URL.Host)
if net.ParseIP(host) != nil {
return url + "/" + key
}
return url + key
}
func newReq(url string) *http.Request {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
panic(fmt.Sprintf("s3 client; invalid URL: %v", err))
}
req.Header.Set("User-Agent", "Minio s3Client")
return req
}
func parseListAllMyBuckets(r io.Reader) ([]*client.Bucket, error) {
type allMyBuckets struct {
Buckets struct {
Bucket []*client.Bucket
}
}
var res allMyBuckets
if err := xml.NewDecoder(r).Decode(&res); err != nil {
return nil, err
}
return res.Buckets.Bucket, nil
}
// IsValidBucket reports whether bucket is a valid bucket name, per Amazon's naming restrictions.
// See http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html
func IsValidBucket(bucket string) bool {
if len(bucket) < 3 || len(bucket) > 63 {
return false
}
if bucket[0] == '.' || bucket[len(bucket)-1] == '.' {
return false
}
if match, _ := regexp.MatchString("\\.\\.", bucket); match == true {
return false
}
// We don't support buckets with '.' in them
match, _ := regexp.MatchString("^[a-zA-Z][a-zA-Z0-9\\-]+[a-zA-Z0-9]$", bucket)
return match
}