Skip to content

Commit

Permalink
service/s3: Add support for accelerate with dualstack (#887)
Browse files Browse the repository at this point in the history
Adds support for using S3 accelerate with Dualstack IPv4 with IPv6. To
enable Dualstack with accelerate set the `Config.UseDualstack` and
`Config.S3UseAccelerate`.

```go
sess := session.New()
svc := s3.New(sess, &aws.Config{
	S3UseAccelerate: aws.Bool(true),
	UseDualStack:    aws.Bool(true),
})

result, err := svc.GetObject(&s3.GetObjectInput{
	Bucket: aws.String("my_bucket"),
	Key:    aws.String("my_key"),
})

// Request made to:
// https://my_bucket.s3-accelerate.dualstack.amazonaws.com/my_key
```
  • Loading branch information
jasdel committed Oct 13, 2016
1 parent afb8bf5 commit 7cfb296
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 11 deletions.
3 changes: 0 additions & 3 deletions aws/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,6 @@ type Config struct {
// accelerate enabled. If the bucket is not enabled for accelerate an error
// will be returned. The bucket name must be DNS compatible to also work
// with accelerate.
//
// Not compatible with UseDualStack requests will fail if both flags are
// specified.
S3UseAccelerate *bool

// Set this to `true` to disable the EC2Metadata client from overriding the
Expand Down
29 changes: 21 additions & 8 deletions service/s3/host_style_bucket.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package s3

import (
"bytes"
"fmt"
"net/url"
"regexp"
Expand Down Expand Up @@ -37,14 +38,6 @@ var accelerateOpBlacklist = operationBlacklist{
func updateEndpointForS3Config(r *request.Request) {
forceHostStyle := aws.BoolValue(r.Config.S3ForcePathStyle)
accelerate := aws.BoolValue(r.Config.S3UseAccelerate)
useDualStack := aws.BoolValue(r.Config.UseDualStack)

if useDualStack && accelerate {
r.Error = awserr.New("InvalidParameterException",
fmt.Sprintf("configuration aws.Config.UseDualStack is not compatible with aws.Config.Accelerate"),
nil)
return
}

if accelerate && accelerateOpBlacklist.Continue(r) {
if forceHostStyle {
Expand Down Expand Up @@ -75,6 +68,10 @@ func updateEndpointForHostStyle(r *request.Request) {
moveBucketToHost(r.HTTPRequest.URL, bucket)
}

var (
accelElem = []byte("s3-accelerate.dualstack.")
)

func updateEndpointForAccelerate(r *request.Request) {
bucket, ok := bucketNameFromReqParams(r.Params)
if !ok {
Expand All @@ -93,6 +90,22 @@ func updateEndpointForAccelerate(r *request.Request) {

// Change endpoint from s3(-[a-z0-1-])?.amazonaws.com to s3-accelerate.amazonaws.com
r.HTTPRequest.URL.Host = replaceHostRegion(r.HTTPRequest.URL.Host, "accelerate")

if aws.BoolValue(r.Config.UseDualStack) {
host := []byte(r.HTTPRequest.URL.Host)

// Strip region from hostname
if idx := bytes.Index(host, accelElem); idx >= 0 {
start := idx + len(accelElem)
if end := bytes.IndexByte(host[start:], '.'); end >= 0 {
end += start + 1
copy(host[start:], host[end:])
host = host[:len(host)-(end-start)]
r.HTTPRequest.URL.Host = string(host)
}
}
}

moveBucketToHost(r.HTTPRequest.URL, bucket)
}

Expand Down
14 changes: 14 additions & 0 deletions service/s3/host_style_bucket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ var (
{"a.b.c", "http://a.b.c.s3-accelerate.amazonaws.com/", ""},
{"a$b$c", "http://s3-mock-region.amazonaws.com/%7BBucket%7D", "InvalidParameterException"},
}

accelerateDualstack = []s3BucketTest{
{"abc", "https://abc.s3-accelerate.dualstack.amazonaws.com/", ""},
{"a.b.c", "https://s3.dualstack.mock-region.amazonaws.com/%7BBucket%7D", "InvalidParameterException"},
{"a$b$c", "https://s3.dualstack.mock-region.amazonaws.com/%7BBucket%7D", "InvalidParameterException"},
}
)

func runTests(t *testing.T, svc *s3.S3, tests []s3BucketTest) {
Expand All @@ -74,6 +80,14 @@ func TestAccelerateNoSSLBucketBuild(t *testing.T) {
runTests(t, s, accelerateNoSSLTests)
}

func TestAccelerateDualstackBucketBuild(t *testing.T) {
s := s3.New(unit.Session, &aws.Config{
S3UseAccelerate: aws.Bool(true),
UseDualStack: aws.Bool(true),
})
runTests(t, s, accelerateDualstack)
}

func TestHostStyleBucketBuild(t *testing.T) {
s := s3.New(unit.Session)
runTests(t, s, sslTests)
Expand Down

0 comments on commit 7cfb296

Please sign in to comment.