2016-02-09 05:23:11 +01:00
|
|
|
package s3
|
|
|
|
|
|
|
|
import (
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
|
|
"github.com/aws/aws-sdk-go/aws/awsutil"
|
|
|
|
"github.com/aws/aws-sdk-go/aws/request"
|
|
|
|
)
|
|
|
|
|
|
|
|
var reDomain = regexp.MustCompile(`^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$`)
|
|
|
|
var reIPAddress = regexp.MustCompile(`^(\d+\.){3}\d+$`)
|
|
|
|
|
|
|
|
// dnsCompatibleBucketName returns true if the bucket name is DNS compatible.
|
|
|
|
// Buckets created outside of the classic region MUST be DNS compatible.
|
|
|
|
func dnsCompatibleBucketName(bucket string) bool {
|
|
|
|
return reDomain.MatchString(bucket) &&
|
|
|
|
!reIPAddress.MatchString(bucket) &&
|
|
|
|
!strings.Contains(bucket, "..")
|
|
|
|
}
|
|
|
|
|
2016-07-31 19:39:16 +02:00
|
|
|
// hostStyleBucketName returns true if the request should put the bucket in
|
|
|
|
// the host. This is false if S3ForcePathStyle is explicitly set or if the
|
|
|
|
// bucket is not DNS compatible.
|
|
|
|
func hostStyleBucketName(r *request.Request, bucket string) bool {
|
|
|
|
if aws.BoolValue(r.Config.S3ForcePathStyle) {
|
|
|
|
return false
|
2016-02-09 05:23:11 +01:00
|
|
|
}
|
|
|
|
|
2016-07-31 19:39:16 +02:00
|
|
|
// Bucket might be DNS compatible but dots in the hostname will fail
|
|
|
|
// certificate validation, so do not use host-style.
|
|
|
|
if r.HTTPRequest.URL.Scheme == "https" && strings.Contains(bucket, ".") {
|
|
|
|
return false
|
2016-02-09 05:23:11 +01:00
|
|
|
}
|
|
|
|
|
2016-07-31 19:39:16 +02:00
|
|
|
// GetBucketLocation should be able to be called from any region within
|
|
|
|
// a partition, and return the associated region of the bucket.
|
|
|
|
if r.Operation.Name == opGetBucketLocation {
|
|
|
|
return false
|
2016-02-09 05:23:11 +01:00
|
|
|
}
|
|
|
|
|
2016-07-31 19:39:16 +02:00
|
|
|
// Use host-style if the bucket is DNS compatible
|
|
|
|
return dnsCompatibleBucketName(bucket)
|
|
|
|
}
|
|
|
|
|
|
|
|
func updateHostWithBucket(r *request.Request) {
|
|
|
|
b, _ := awsutil.ValuesAtPath(r.Params, "Bucket")
|
|
|
|
if len(b) == 0 {
|
|
|
|
return
|
2016-02-09 05:23:11 +01:00
|
|
|
}
|
2016-07-22 02:27:25 +02:00
|
|
|
|
2016-07-31 19:39:16 +02:00
|
|
|
if bucket := b[0].(*string); aws.StringValue(bucket) != "" && hostStyleBucketName(r, *bucket) {
|
|
|
|
r.HTTPRequest.URL.Host = *bucket + "." + r.HTTPRequest.URL.Host
|
|
|
|
r.HTTPRequest.URL.Path = strings.Replace(r.HTTPRequest.URL.Path, "/{Bucket}", "", -1)
|
|
|
|
if r.HTTPRequest.URL.Path == "" {
|
|
|
|
r.HTTPRequest.URL.Path = "/"
|
|
|
|
}
|
|
|
|
}
|
2016-02-09 05:23:11 +01:00
|
|
|
}
|