1package s3_test
2
3import (
4	"crypto/md5"
5	"encoding/base64"
6	"io/ioutil"
7	"net/http"
8	"net/http/httptest"
9	"strings"
10	"testing"
11
12	"github.com/aws/aws-sdk-go/aws"
13	"github.com/aws/aws-sdk-go/aws/request"
14	"github.com/aws/aws-sdk-go/awstesting/unit"
15	"github.com/aws/aws-sdk-go/service/s3"
16)
17
18func assertMD5(t *testing.T, req *request.Request) {
19	err := req.Build()
20	if err != nil {
21		t.Errorf("expected no error, but received %v", err)
22	}
23
24	b, _ := ioutil.ReadAll(req.HTTPRequest.Body)
25	out := md5.Sum(b)
26	if len(b) == 0 {
27		t.Error("expected non-empty value")
28	}
29	if e, a := base64.StdEncoding.EncodeToString(out[:]), req.HTTPRequest.Header.Get("Content-MD5"); e != a {
30		t.Errorf("expected %s, but received %s", e, a)
31	}
32}
33
34func TestMD5InPutBucketCors(t *testing.T) {
35	svc := s3.New(unit.Session)
36	req, _ := svc.PutBucketCorsRequest(&s3.PutBucketCorsInput{
37		Bucket: aws.String("bucketname"),
38		CORSConfiguration: &s3.CORSConfiguration{
39			CORSRules: []*s3.CORSRule{
40				{
41					AllowedMethods: []*string{aws.String("GET")},
42					AllowedOrigins: []*string{aws.String("*")},
43				},
44			},
45		},
46	})
47	assertMD5(t, req)
48}
49
50func TestMD5InPutBucketLifecycle(t *testing.T) {
51	svc := s3.New(unit.Session)
52	req, _ := svc.PutBucketLifecycleRequest(&s3.PutBucketLifecycleInput{
53		Bucket: aws.String("bucketname"),
54		LifecycleConfiguration: &s3.LifecycleConfiguration{
55			Rules: []*s3.Rule{
56				{
57					ID:     aws.String("ID"),
58					Prefix: aws.String("Prefix"),
59					Status: aws.String("Enabled"),
60				},
61			},
62		},
63	})
64	assertMD5(t, req)
65}
66
67func TestMD5InPutBucketPolicy(t *testing.T) {
68	svc := s3.New(unit.Session)
69	req, _ := svc.PutBucketPolicyRequest(&s3.PutBucketPolicyInput{
70		Bucket: aws.String("bucketname"),
71		Policy: aws.String("{}"),
72	})
73	assertMD5(t, req)
74}
75
76func TestMD5InPutBucketTagging(t *testing.T) {
77	svc := s3.New(unit.Session)
78	req, _ := svc.PutBucketTaggingRequest(&s3.PutBucketTaggingInput{
79		Bucket: aws.String("bucketname"),
80		Tagging: &s3.Tagging{
81			TagSet: []*s3.Tag{
82				{Key: aws.String("KEY"), Value: aws.String("VALUE")},
83			},
84		},
85	})
86	assertMD5(t, req)
87}
88
89func TestMD5InDeleteObjects(t *testing.T) {
90	svc := s3.New(unit.Session)
91	req, _ := svc.DeleteObjectsRequest(&s3.DeleteObjectsInput{
92		Bucket: aws.String("bucketname"),
93		Delete: &s3.Delete{
94			Objects: []*s3.ObjectIdentifier{
95				{Key: aws.String("key")},
96			},
97		},
98	})
99	assertMD5(t, req)
100}
101
102func TestMD5InPutBucketLifecycleConfiguration(t *testing.T) {
103	svc := s3.New(unit.Session)
104	req, _ := svc.PutBucketLifecycleConfigurationRequest(&s3.PutBucketLifecycleConfigurationInput{
105		Bucket: aws.String("bucketname"),
106		LifecycleConfiguration: &s3.BucketLifecycleConfiguration{
107			Rules: []*s3.LifecycleRule{
108				{Prefix: aws.String("prefix"), Status: aws.String(s3.ExpirationStatusEnabled)},
109			},
110		},
111	})
112	assertMD5(t, req)
113}
114
115const (
116	metaKeyPrefix = `X-Amz-Meta-`
117	utf8KeySuffix = `My-Info`
118	utf8Value     = "hello-世界\u0444"
119)
120
121func TestPutObjectMetadataWithUnicode(t *testing.T) {
122	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
123		if e, a := utf8Value, r.Header.Get(metaKeyPrefix+utf8KeySuffix); e != a {
124			t.Errorf("expected %s, but received %s", e, a)
125		}
126	}))
127	svc := s3.New(unit.Session, &aws.Config{
128		Endpoint:   aws.String(server.URL),
129		DisableSSL: aws.Bool(true),
130	})
131
132	_, err := svc.PutObject(&s3.PutObjectInput{
133		Bucket: aws.String("my_bucket"),
134		Key:    aws.String("my_key"),
135		Body:   strings.NewReader(""),
136		Metadata: func() map[string]*string {
137			v := map[string]*string{}
138			v[utf8KeySuffix] = aws.String(utf8Value)
139			return v
140		}(),
141	})
142
143	if err != nil {
144		t.Errorf("expected no error, but received %v", err)
145	}
146}
147
148func TestGetObjectMetadataWithUnicode(t *testing.T) {
149	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
150		w.Header().Set(metaKeyPrefix+utf8KeySuffix, utf8Value)
151	}))
152	svc := s3.New(unit.Session, &aws.Config{
153		Endpoint:   aws.String(server.URL),
154		DisableSSL: aws.Bool(true),
155	})
156
157	resp, err := svc.GetObject(&s3.GetObjectInput{
158		Bucket: aws.String("my_bucket"),
159		Key:    aws.String("my_key"),
160	})
161
162	if err != nil {
163		t.Errorf("expected no error, but received %v", err)
164	}
165	resp.Body.Close()
166
167	if e, a := utf8Value, *resp.Metadata[utf8KeySuffix]; e != a {
168		t.Errorf("expected %s, but received %s", e, a)
169	}
170
171}
172