Merge lp:~nick-craig-wood/goamz/list-buckets2 into lp:goamz

Proposed by Nick Craig-Wood
Status: Needs review
Proposed branch: lp:~nick-craig-wood/goamz/list-buckets2
Merge into: lp:goamz
Diff against target: 164 lines (+103/-13)
3 files modified
s3/responses_test.go (+19/-0)
s3/s3.go (+55/-13)
s3/s3_test.go (+29/-0)
To merge this branch: bzr merge lp:~nick-craig-wood/goamz/list-buckets2
Reviewer Review Type Date Requested Status
goamz maintainers Pending
Review via email: mp+171786@code.launchpad.net

Description of the change

Implement S3.List to list all Buckets

This allows the user to discover all S3 buckets that they have

https://codereview.appspot.com/10684043/

To post a comment you must log in.
Revision history for this message
Nick Craig-Wood (nick-craig-wood) wrote :

See https://code.launchpad.net/~nick-craig-wood/goamz/list-buckets/+merge/146925 for old code review.

I've messed up that branch somehow so here is a new one

39. By Nick Craig-Wood

s3: ListBuckets: Fix signpath which was causing authentication errors

Unmerged revisions

39. By Nick Craig-Wood

s3: ListBuckets: Fix signpath which was causing authentication errors

38. By Nick Craig-Wood

Implement S3.List to list all Buckets

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 's3/responses_test.go'
--- s3/responses_test.go 2013-02-12 04:50:11 +0000
+++ s3/responses_test.go 2013-06-29 10:57:22 +0000
@@ -196,3 +196,22 @@
196 <HostId>kjhwqk</HostId>196 <HostId>kjhwqk</HostId>
197</Error>197</Error>
198`198`
199
200var GetBucketsListResultDump = `
201<ListAllMyBucketsResult xmlns="http://doc.s3.amazonaws.com/2006-03-01">
202 <Owner>
203 <ID>bcaf1ffd86f461ca5fb16fd081034f</ID>
204 <DisplayName>webfile</DisplayName>
205 </Owner>
206 <Buckets>
207 <Bucket>
208 <Name>quotes</Name>
209 <CreationDate>2006-02-03T16:45:09.000Z</CreationDate>
210 </Bucket>
211 <Bucket>
212 <Name>samples</Name>
213 <CreationDate>2006-02-03T16:41:58.000Z</CreationDate>
214 </Bucket>
215 </Buckets>
216</ListAllMyBucketsResult>
217`
199218
=== modified file 's3/s3.go'
--- s3/s3.go 2013-05-21 14:39:01 +0000
+++ s3/s3.go 2013-06-29 10:57:22 +0000
@@ -40,6 +40,9 @@
40type Bucket struct {40type Bucket struct {
41 *S341 *S3
42 Name string42 Name string
43 // The following fields are only set on buckets returned from the ListBuckets call
44 Owner Owner // Owner of the bucket
45 CreationDate time.Time // When the bucket was created
43}46}
4447
45// The Owner type represents the owner of the object in an S3 bucket.48// The Owner type represents the owner of the object in an S3 bucket.
@@ -64,7 +67,44 @@
64 if s3.Region.S3BucketEndpoint != "" || s3.Region.S3LowercaseBucket {67 if s3.Region.S3BucketEndpoint != "" || s3.Region.S3LowercaseBucket {
65 name = strings.ToLower(name)68 name = strings.ToLower(name)
66 }69 }
67 return &Bucket{s3, name}70 return &Bucket{S3: s3, Name: name}
71}
72
73// bucketsResp is returned by S3.Buckets
74type bucketsResp struct {
75 Owner Owner
76 Buckets []struct {
77 Name string
78 CreationDate string // Date the bucket was created, e.g., 2009-02-03T16:45:09.000Z
79 } `xml:"Buckets>Bucket"`
80}
81
82// List returns a list of all buckets owned by the sender
83//
84// See http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTServiceGET.html
85func (s3 *S3) ListBuckets() (buckets []*Bucket, err error) {
86 req := &request{
87 method: "GET",
88 bucket: "",
89 path: "",
90 }
91 result := &bucketsResp{}
92 err = s3.query(req, result)
93 if err != nil {
94 return nil, err
95 }
96 buckets = make([]*Bucket, len(result.Buckets))
97 for i := range buckets {
98 info := result.Buckets[i]
99 b := s3.Bucket(info.Name)
100 b.CreationDate, err = time.Parse(time.RFC3339Nano, info.CreationDate)
101 if err != nil {
102 return nil, err
103 }
104 b.Owner = result.Owner
105 buckets[i] = b
106 }
107 return buckets, nil
68}108}
69109
70var createBucketConfiguration = `<CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 110var createBucketConfiguration = `<CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
@@ -418,19 +458,21 @@
418 req.path = "/" + req.path458 req.path = "/" + req.path
419 }459 }
420 req.signpath = req.path460 req.signpath = req.path
461 req.baseurl = s3.Region.S3BucketEndpoint
462 if req.baseurl == "" {
463 // Use the path method to address the bucket.
464 req.baseurl = s3.Region.S3Endpoint
465 if req.bucket != "" {
466 req.path = "/" + req.bucket + req.path
467 }
468 } else {
469 // Just in case, prevent injection.
470 if strings.IndexAny(req.bucket, "/:@") >= 0 {
471 return fmt.Errorf("bad S3 bucket: %q", req.bucket)
472 }
473 req.baseurl = strings.Replace(req.baseurl, "${bucket}", req.bucket, -1)
474 }
421 if req.bucket != "" {475 if req.bucket != "" {
422 req.baseurl = s3.Region.S3BucketEndpoint
423 if req.baseurl == "" {
424 // Use the path method to address the bucket.
425 req.baseurl = s3.Region.S3Endpoint
426 req.path = "/" + req.bucket + req.path
427 } else {
428 // Just in case, prevent injection.
429 if strings.IndexAny(req.bucket, "/:@") >= 0 {
430 return fmt.Errorf("bad S3 bucket: %q", req.bucket)
431 }
432 req.baseurl = strings.Replace(req.baseurl, "${bucket}", req.bucket, -1)
433 }
434 req.signpath = "/" + req.bucket + req.signpath476 req.signpath = "/" + req.bucket + req.signpath
435 }477 }
436 }478 }
437479
=== modified file 's3/s3_test.go'
--- s3/s3_test.go 2013-05-23 02:56:41 +0000
+++ s3/s3_test.go 2013-06-29 10:57:22 +0000
@@ -4,6 +4,7 @@
4 "bytes"4 "bytes"
5 "io/ioutil"5 "io/ioutil"
6 "net/http"6 "net/http"
7 "net/url"
7 "testing"8 "testing"
89
9 "launchpad.net/goamz/aws"10 "launchpad.net/goamz/aws"
@@ -276,3 +277,31 @@
276 c.Assert(len(data.Contents), Equals, 0)277 c.Assert(len(data.Contents), Equals, 0)
277 c.Assert(data.CommonPrefixes, DeepEquals, []string{"photos/2006/feb/", "photos/2006/jan/"})278 c.Assert(data.CommonPrefixes, DeepEquals, []string{"photos/2006/feb/", "photos/2006/jan/"})
278}279}
280
281// List buckets docs: See http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTServiceGET.html
282
283func (s *S) TestListBuckets(c *C) {
284 testServer.Response(200, nil, GetBucketsListResultDump)
285
286 buckets, err := s.s3.ListBuckets()
287 c.Assert(err, IsNil)
288
289 req := testServer.WaitRequest()
290 c.Assert(req.Method, Equals, "GET")
291 c.Assert(req.URL.Path, Equals, "/")
292 c.Assert(req.Header["Date"], Not(Equals), "")
293 c.Assert(req.Form, DeepEquals, url.Values{})
294
295 c.Assert(len(buckets), Equals, 2)
296
297 c.Assert(buckets[0].Name, Equals, "quotes")
298 c.Assert(buckets[0].CreationDate, Equals, time.Date(2006, 2, 3, 16, 45, 9, 0, time.UTC))
299 c.Assert(buckets[0].Owner.ID, Equals, "bcaf1ffd86f461ca5fb16fd081034f")
300 c.Assert(buckets[0].Owner.DisplayName, Equals, "webfile")
301
302 c.Assert(buckets[1].Name, Equals, "samples")
303 c.Assert(buckets[1].CreationDate, Equals, time.Date(2006, 2, 3, 16, 41, 58, 0, time.UTC))
304 c.Assert(buckets[1].Owner.ID, Equals, "bcaf1ffd86f461ca5fb16fd081034f")
305 c.Assert(buckets[1].Owner.DisplayName, Equals, "webfile")
306
307}

Subscribers

People subscribed via source and target branches