diff options
Diffstat (limited to 'Godeps/_workspace/src/github.com/goamz')
13 files changed, 185 insertions, 2764 deletions
diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/LICENSE b/Godeps/_workspace/src/github.com/goamz/goamz/LICENSE new file mode 100644 index 000000000..53320c352 --- /dev/null +++ b/Godeps/_workspace/src/github.com/goamz/goamz/LICENSE @@ -0,0 +1,185 @@ +This software is licensed under the LGPLv3, included below. + +As a special exception to the GNU Lesser General Public License version 3 +("LGPL3"), the copyright holders of this Library give you permission to +convey to a third party a Combined Work that links statically or dynamically +to this Library without providing any Minimal Corresponding Source or +Minimal Application Code as set out in 4d or providing the installation +information set out in section 4e, provided that you comply with the other +provisions of LGPL3 and provided that you meet, for the Application the +terms and conditions of the license(s) which apply to the Application. + +Except as stated in this special exception, the provisions of LGPL3 will +continue to comply in full to this Library. If you modify this Library, you +may apply this exception to your version of this Library, but you are not +obliged to do so. If you do not wish to do so, delete this exception +statement from your version. This exception does not (and cannot) modify any +license terms which apply to the Application, with which you must still +comply. + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/aws/attempt_test.go b/Godeps/_workspace/src/github.com/goamz/goamz/aws/attempt_test.go deleted file mode 100644 index 8ba497715..000000000 --- a/Godeps/_workspace/src/github.com/goamz/goamz/aws/attempt_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package aws_test - -import ( - "time" - - "github.com/goamz/goamz/aws" - . "gopkg.in/check.v1" -) - -func (S) TestAttemptTiming(c *C) { - testAttempt := aws.AttemptStrategy{ - Total: 0.25e9, - Delay: 0.1e9, - } - want := []time.Duration{0, 0.1e9, 0.2e9, 0.2e9} - got := make([]time.Duration, 0, len(want)) // avoid allocation when testing timing - t0 := time.Now() - for a := testAttempt.Start(); a.Next(); { - got = append(got, time.Now().Sub(t0)) - } - got = append(got, time.Now().Sub(t0)) - c.Assert(got, HasLen, len(want)) - const margin = 0.01e9 - for i, got := range want { - lo := want[i] - margin - hi := want[i] + margin - if got < lo || got > hi { - c.Errorf("attempt %d want %g got %g", i, want[i].Seconds(), got.Seconds()) - } - } -} - -func (S) TestAttemptNextHasNext(c *C) { - a := aws.AttemptStrategy{}.Start() - c.Assert(a.Next(), Equals, true) - c.Assert(a.Next(), Equals, false) - - a = aws.AttemptStrategy{}.Start() - c.Assert(a.Next(), Equals, true) - c.Assert(a.HasNext(), Equals, false) - c.Assert(a.Next(), Equals, false) - - a = aws.AttemptStrategy{Total: 2e8}.Start() - c.Assert(a.Next(), Equals, true) - c.Assert(a.HasNext(), Equals, true) - time.Sleep(2e8) - c.Assert(a.HasNext(), Equals, true) - c.Assert(a.Next(), Equals, true) - c.Assert(a.Next(), Equals, false) - - a = aws.AttemptStrategy{Total: 1e8, Min: 2}.Start() - time.Sleep(1e8) - c.Assert(a.Next(), Equals, true) - c.Assert(a.HasNext(), Equals, true) - c.Assert(a.Next(), Equals, true) - c.Assert(a.HasNext(), Equals, false) - c.Assert(a.Next(), Equals, false) -} diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/aws/aws_test.go b/Godeps/_workspace/src/github.com/goamz/goamz/aws/aws_test.go deleted file mode 100644 index 0c74a7905..000000000 --- a/Godeps/_workspace/src/github.com/goamz/goamz/aws/aws_test.go +++ /dev/null @@ -1,211 +0,0 @@ -package aws_test - -import ( - "io/ioutil" - "os" - "strings" - "testing" - "time" - - "github.com/goamz/goamz/aws" - . "gopkg.in/check.v1" -) - -func Test(t *testing.T) { - TestingT(t) -} - -var _ = Suite(&S{}) - -type S struct { - environ []string -} - -func (s *S) SetUpSuite(c *C) { - s.environ = os.Environ() -} - -func (s *S) TearDownTest(c *C) { - os.Clearenv() - for _, kv := range s.environ { - l := strings.SplitN(kv, "=", 2) - os.Setenv(l[0], l[1]) - } -} - -func (s *S) TestSharedAuthNoHome(c *C) { - os.Clearenv() - os.Setenv("AWS_PROFILE", "foo") - _, err := aws.SharedAuth() - c.Assert(err, ErrorMatches, "Could not get HOME") -} - -func (s *S) TestSharedAuthNoCredentialsFile(c *C) { - os.Clearenv() - os.Setenv("AWS_PROFILE", "foo") - os.Setenv("HOME", "/tmp") - _, err := aws.SharedAuth() - c.Assert(err, ErrorMatches, "Couldn't parse AWS credentials file") -} - -func (s *S) TestSharedAuthNoProfileInFile(c *C) { - os.Clearenv() - os.Setenv("AWS_PROFILE", "foo") - - d, err := ioutil.TempDir("", "") - if err != nil { - panic(err) - } - defer os.RemoveAll(d) - - err = os.Mkdir(d+"/.aws", 0755) - if err != nil { - panic(err) - } - - ioutil.WriteFile(d+"/.aws/credentials", []byte("[bar]\n"), 0644) - os.Setenv("HOME", d) - - _, err = aws.SharedAuth() - c.Assert(err, ErrorMatches, "Couldn't find profile in AWS credentials file") -} - -func (s *S) TestSharedAuthNoKeysInProfile(c *C) { - os.Clearenv() - os.Setenv("AWS_PROFILE", "bar") - - d, err := ioutil.TempDir("", "") - if err != nil { - panic(err) - } - defer os.RemoveAll(d) - - err = os.Mkdir(d+"/.aws", 0755) - if err != nil { - panic(err) - } - - ioutil.WriteFile(d+"/.aws/credentials", []byte("[bar]\nawsaccesskeyid = AK.."), 0644) - os.Setenv("HOME", d) - - _, err = aws.SharedAuth() - c.Assert(err, ErrorMatches, "AWS_SECRET_ACCESS_KEY not found in credentials file") -} - -func (s *S) TestSharedAuthDefaultCredentials(c *C) { - os.Clearenv() - - d, err := ioutil.TempDir("", "") - if err != nil { - panic(err) - } - defer os.RemoveAll(d) - - err = os.Mkdir(d+"/.aws", 0755) - if err != nil { - panic(err) - } - - ioutil.WriteFile(d+"/.aws/credentials", []byte("[default]\naws_access_key_id = access\naws_secret_access_key = secret\n"), 0644) - os.Setenv("HOME", d) - - auth, err := aws.SharedAuth() - c.Assert(err, IsNil) - c.Assert(auth, Equals, aws.Auth{SecretKey: "secret", AccessKey: "access"}) -} - -func (s *S) TestSharedAuth(c *C) { - os.Clearenv() - os.Setenv("AWS_PROFILE", "bar") - - d, err := ioutil.TempDir("", "") - if err != nil { - panic(err) - } - defer os.RemoveAll(d) - - err = os.Mkdir(d+"/.aws", 0755) - if err != nil { - panic(err) - } - - ioutil.WriteFile(d+"/.aws/credentials", []byte("[bar]\naws_access_key_id = access\naws_secret_access_key = secret\n"), 0644) - os.Setenv("HOME", d) - - auth, err := aws.SharedAuth() - c.Assert(err, IsNil) - c.Assert(auth, Equals, aws.Auth{SecretKey: "secret", AccessKey: "access"}) -} - -func (s *S) TestEnvAuthNoSecret(c *C) { - os.Clearenv() - _, err := aws.EnvAuth() - c.Assert(err, ErrorMatches, "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment") -} - -func (s *S) TestEnvAuthNoAccess(c *C) { - os.Clearenv() - os.Setenv("AWS_SECRET_ACCESS_KEY", "foo") - _, err := aws.EnvAuth() - c.Assert(err, ErrorMatches, "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment") -} - -func (s *S) TestEnvAuth(c *C) { - os.Clearenv() - os.Setenv("AWS_SECRET_ACCESS_KEY", "secret") - os.Setenv("AWS_ACCESS_KEY_ID", "access") - auth, err := aws.EnvAuth() - c.Assert(err, IsNil) - c.Assert(auth, Equals, aws.Auth{SecretKey: "secret", AccessKey: "access"}) -} - -func (s *S) TestEnvAuthAlt(c *C) { - os.Clearenv() - os.Setenv("AWS_SECRET_KEY", "secret") - os.Setenv("AWS_ACCESS_KEY", "access") - auth, err := aws.EnvAuth() - c.Assert(err, IsNil) - c.Assert(auth, Equals, aws.Auth{SecretKey: "secret", AccessKey: "access"}) -} - -func (s *S) TestEnvAuthToken(c *C) { - os.Clearenv() - os.Setenv("AWS_SECRET_KEY", "secret") - os.Setenv("AWS_ACCESS_KEY", "access") - os.Setenv("AWS_SESSION_TOKEN", "token") - auth, err := aws.EnvAuth() - c.Assert(err, IsNil) - c.Assert(auth.SecretKey, Equals, "secret") - c.Assert(auth.AccessKey, Equals, "access") - c.Assert(auth.Token(), Equals, "token") -} - -func (s *S) TestGetAuthStatic(c *C) { - exptdate := time.Now().Add(time.Hour) - auth, err := aws.GetAuth("access", "secret", "token", exptdate) - c.Assert(err, IsNil) - c.Assert(auth.AccessKey, Equals, "access") - c.Assert(auth.SecretKey, Equals, "secret") - c.Assert(auth.Token(), Equals, "token") - c.Assert(auth.Expiration(), Equals, exptdate) -} - -func (s *S) TestGetAuthEnv(c *C) { - os.Clearenv() - os.Setenv("AWS_SECRET_ACCESS_KEY", "secret") - os.Setenv("AWS_ACCESS_KEY_ID", "access") - auth, err := aws.GetAuth("", "", "", time.Time{}) - c.Assert(err, IsNil) - c.Assert(auth, Equals, aws.Auth{SecretKey: "secret", AccessKey: "access"}) -} - -func (s *S) TestEncode(c *C) { - c.Assert(aws.Encode("foo"), Equals, "foo") - c.Assert(aws.Encode("/"), Equals, "%2F") -} - -func (s *S) TestRegionsAreNamed(c *C) { - for n, r := range aws.Regions { - c.Assert(n, Equals, r.Name) - } -} diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/aws/client_test.go b/Godeps/_workspace/src/github.com/goamz/goamz/aws/client_test.go deleted file mode 100644 index c66a86333..000000000 --- a/Godeps/_workspace/src/github.com/goamz/goamz/aws/client_test.go +++ /dev/null @@ -1,121 +0,0 @@ -package aws_test - -import ( - "fmt" - "github.com/goamz/goamz/aws" - "io/ioutil" - "net/http" - "net/http/httptest" - "strings" - "testing" - "time" -) - -// Retrieve the response from handler using aws.RetryingClient -func serveAndGet(handler http.HandlerFunc) (body string, err error) { - ts := httptest.NewServer(handler) - defer ts.Close() - resp, err := aws.RetryingClient.Get(ts.URL) - if err != nil { - return - } - if resp.StatusCode != 200 { - return "", fmt.Errorf("Bad status code: %d", resp.StatusCode) - } - greeting, err := ioutil.ReadAll(resp.Body) - resp.Body.Close() - if err != nil { - return - } - return strings.TrimSpace(string(greeting)), nil -} - -func TestClient_expected(t *testing.T) { - body := "foo bar" - - resp, err := serveAndGet(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, body) - }) - if err != nil { - t.Fatal(err) - } - if resp != body { - t.Fatal("Body not as expected.") - } -} - -func TestClient_delay(t *testing.T) { - body := "baz" - wait := 4 - resp, err := serveAndGet(func(w http.ResponseWriter, r *http.Request) { - if wait < 0 { - // If we dipped to zero delay and still failed. - t.Fatal("Never succeeded.") - } - wait -= 1 - time.Sleep(time.Second * time.Duration(wait)) - fmt.Fprintln(w, body) - }) - if err != nil { - t.Fatal(err) - } - if resp != body { - t.Fatal("Body not as expected.", resp) - } -} - -func TestClient_no4xxRetry(t *testing.T) { - tries := 0 - - // Fail once before succeeding. - _, err := serveAndGet(func(w http.ResponseWriter, r *http.Request) { - tries += 1 - http.Error(w, "error", 404) - }) - - if err == nil { - t.Fatal("should have error") - } - - if tries != 1 { - t.Fatalf("should only try once: %d", tries) - } -} - -func TestClient_retries(t *testing.T) { - body := "biz" - failed := false - // Fail once before succeeding. - resp, err := serveAndGet(func(w http.ResponseWriter, r *http.Request) { - if !failed { - http.Error(w, "error", 500) - failed = true - } else { - fmt.Fprintln(w, body) - } - }) - if failed != true { - t.Error("We didn't retry!") - } - if err != nil { - t.Fatal(err) - } - if resp != body { - t.Fatal("Body not as expected.") - } -} - -func TestClient_fails(t *testing.T) { - tries := 0 - // Fail 3 times and return the last error. - _, err := serveAndGet(func(w http.ResponseWriter, r *http.Request) { - tries += 1 - http.Error(w, "error", 500) - }) - if err == nil { - t.Fatal(err) - } - if tries != 3 { - t.Fatal("Didn't retry enough") - } -} diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/aws/export_test.go b/Godeps/_workspace/src/github.com/goamz/goamz/aws/export_test.go deleted file mode 100644 index c4aca1d72..000000000 --- a/Godeps/_workspace/src/github.com/goamz/goamz/aws/export_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package aws - -import ( - "net/http" - "time" -) - -// V4Signer: -// Exporting methods for testing - -func (s *V4Signer) RequestTime(req *http.Request) time.Time { - return s.requestTime(req) -} - -func (s *V4Signer) CanonicalRequest(req *http.Request) string { - return s.canonicalRequest(req) -} - -func (s *V4Signer) StringToSign(t time.Time, creq string) string { - return s.stringToSign(t, creq) -} - -func (s *V4Signer) Signature(t time.Time, sts string) string { - return s.signature(t, sts) -} - -func (s *V4Signer) Authorization(header http.Header, t time.Time, signature string) string { - return s.authorization(header, t, signature) -} diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/aws/sign_test.go b/Godeps/_workspace/src/github.com/goamz/goamz/aws/sign_test.go deleted file mode 100644 index c6b685e20..000000000 --- a/Godeps/_workspace/src/github.com/goamz/goamz/aws/sign_test.go +++ /dev/null @@ -1,525 +0,0 @@ -package aws_test - -import ( - "fmt" - "net/http" - "strings" - "time" - - "github.com/goamz/goamz/aws" - . "gopkg.in/check.v1" -) - -var _ = Suite(&V4SignerSuite{}) - -type V4SignerSuite struct { - auth aws.Auth - region aws.Region - cases []V4SignerSuiteCase -} - -type V4SignerSuiteCase struct { - label string - request V4SignerSuiteCaseRequest - canonicalRequest string - stringToSign string - signature string - authorization string -} - -type V4SignerSuiteCaseRequest struct { - method string - host string - url string - headers []string - body string -} - -func (s *V4SignerSuite) SetUpSuite(c *C) { - s.auth = aws.Auth{AccessKey: "AKIDEXAMPLE", SecretKey: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY"} - s.region = aws.USEast - - // Test cases from the Signature Version 4 Test Suite (http://goo.gl/nguvs0) - s.cases = append(s.cases, - - // get-header-key-duplicate - V4SignerSuiteCase{ - label: "get-header-key-duplicate", - request: V4SignerSuiteCaseRequest{ - method: "POST", - host: "host.foo.com", - url: "/", - headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "ZOO:zoobar", "zoo:foobar", "zoo:zoobar"}, - }, - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\nzoo:foobar,zoobar,zoobar\n\ndate;host;zoo\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n3c52f0eaae2b61329c0a332e3fa15842a37bc5812cf4d80eb64784308850e313", - signature: "54afcaaf45b331f81cd2edb974f7b824ff4dd594cbbaa945ed636b48477368ed", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;zoo, Signature=54afcaaf45b331f81cd2edb974f7b824ff4dd594cbbaa945ed636b48477368ed", - }, - - // get-header-value-order - V4SignerSuiteCase{ - label: "get-header-value-order", - request: V4SignerSuiteCaseRequest{ - method: "POST", - host: "host.foo.com", - url: "/", - headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "p:z", "p:a", "p:p", "p:a"}, - }, - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\np:a,a,p,z\n\ndate;host;p\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n94c0389fefe0988cbbedc8606f0ca0b485b48da010d09fc844b45b697c8924fe", - signature: "d2973954263943b11624a11d1c963ca81fb274169c7868b2858c04f083199e3d", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;p, Signature=d2973954263943b11624a11d1c963ca81fb274169c7868b2858c04f083199e3d", - }, - - // get-header-value-trim - V4SignerSuiteCase{ - label: "get-header-value-trim", - request: V4SignerSuiteCaseRequest{ - method: "POST", - host: "host.foo.com", - url: "/", - headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "p: phfft "}, - }, - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\np:phfft\n\ndate;host;p\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ndddd1902add08da1ac94782b05f9278c08dc7468db178a84f8950d93b30b1f35", - signature: "debf546796015d6f6ded8626f5ce98597c33b47b9164cf6b17b4642036fcb592", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;p, Signature=debf546796015d6f6ded8626f5ce98597c33b47b9164cf6b17b4642036fcb592", - }, - - // get-relative-relative - V4SignerSuiteCase{ - label: "get-relative-relative", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/foo/bar/../..", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1", - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470", - }, - - // get-relative - V4SignerSuiteCase{ - label: "get-relative", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/foo/..", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1", - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470", - }, - - // get-slash-dot-slash - V4SignerSuiteCase{ - label: "get-slash-dot-slash", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/./", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1", - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470", - }, - - // get-slash-pointless-dot - V4SignerSuiteCase{ - label: "get-slash-pointless-dot", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/./foo", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/foo\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n8021a97572ee460f87ca67f4e8c0db763216d84715f5424a843a5312a3321e2d", - signature: "910e4d6c9abafaf87898e1eb4c929135782ea25bb0279703146455745391e63a", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=910e4d6c9abafaf87898e1eb4c929135782ea25bb0279703146455745391e63a", - }, - - // get-slash - V4SignerSuiteCase{ - label: "get-slash", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "//", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1", - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470", - }, - - // get-slashes - V4SignerSuiteCase{ - label: "get-slashes", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "//foo//", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/foo/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n6bb4476ee8745730c9cb79f33a0c70baa6d8af29c0077fa12e4e8f1dd17e7098", - signature: "b00392262853cfe3201e47ccf945601079e9b8a7f51ee4c3d9ee4f187aa9bf19", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b00392262853cfe3201e47ccf945601079e9b8a7f51ee4c3d9ee4f187aa9bf19", - }, - - // get-space - V4SignerSuiteCase{ - label: "get-space", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/%20/foo", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/%20/foo\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n69c45fb9fe3fd76442b5086e50b2e9fec8298358da957b293ef26e506fdfb54b", - signature: "f309cfbd10197a230c42dd17dbf5cca8a0722564cb40a872d25623cfa758e374", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=f309cfbd10197a230c42dd17dbf5cca8a0722564cb40a872d25623cfa758e374", - }, - - // get-unreserved - V4SignerSuiteCase{ - label: "get-unreserved", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ndf63ee3247c0356c696a3b21f8d8490b01fa9cd5bc6550ef5ef5f4636b7b8901", - signature: "830cc36d03f0f84e6ee4953fbe701c1c8b71a0372c63af9255aa364dd183281e", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=830cc36d03f0f84e6ee4953fbe701c1c8b71a0372c63af9255aa364dd183281e", - }, - - // get-utf8 - V4SignerSuiteCase{ - label: "get-utf8", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/%E1%88%B4", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/%E1%88%B4\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n27ba31df5dbc6e063d8f87d62eb07143f7f271c5330a917840586ac1c85b6f6b", - signature: "8d6634c189aa8c75c2e51e106b6b5121bed103fdb351f7d7d4381c738823af74", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=8d6634c189aa8c75c2e51e106b6b5121bed103fdb351f7d7d4381c738823af74", - }, - - // get-vanilla-empty-query-key - V4SignerSuiteCase{ - label: "get-vanilla-empty-query-key", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/?foo=bar", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/\nfoo=bar\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n0846c2945b0832deb7a463c66af5c4f8bd54ec28c438e67a214445b157c9ddf8", - signature: "56c054473fd260c13e4e7393eb203662195f5d4a1fada5314b8b52b23f985e9f", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=56c054473fd260c13e4e7393eb203662195f5d4a1fada5314b8b52b23f985e9f", - }, - - // get-vanilla-query-order-key-case - V4SignerSuiteCase{ - label: "get-vanilla-query-order-key-case", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/?foo=Zoo&foo=aha", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/\nfoo=Zoo&foo=aha\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ne25f777ba161a0f1baf778a87faf057187cf5987f17953320e3ca399feb5f00d", - signature: "be7148d34ebccdc6423b19085378aa0bee970bdc61d144bd1a8c48c33079ab09", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=be7148d34ebccdc6423b19085378aa0bee970bdc61d144bd1a8c48c33079ab09", - }, - - // get-vanilla-query-order-key - V4SignerSuiteCase{ - label: "get-vanilla-query-order-key", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/?a=foo&b=foo", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/\na=foo&b=foo\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n2f23d14fe13caebf6dfda346285c6d9c14f49eaca8f5ec55c627dd7404f7a727", - signature: "0dc122f3b28b831ab48ba65cb47300de53fbe91b577fe113edac383730254a3b", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=0dc122f3b28b831ab48ba65cb47300de53fbe91b577fe113edac383730254a3b", - }, - - // get-vanilla-query-order-value - V4SignerSuiteCase{ - label: "get-vanilla-query-order-value", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/?foo=b&foo=a", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/\nfoo=a&foo=b\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n33dffc220e89131f8f6157a35c40903daa658608d9129ff9489e5cf5bbd9b11b", - signature: "feb926e49e382bec75c9d7dcb2a1b6dc8aa50ca43c25d2bc51143768c0875acc", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=feb926e49e382bec75c9d7dcb2a1b6dc8aa50ca43c25d2bc51143768c0875acc", - }, - - // get-vanilla-query-unreserved - V4SignerSuiteCase{ - label: "get-vanilla-query-unreserved", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/?-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/\n-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\nd2578f3156d4c9d180713d1ff20601d8a3eed0dd35447d24603d7d67414bd6b5", - signature: "f1498ddb4d6dae767d97c466fb92f1b59a2c71ca29ac954692663f9db03426fb", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=f1498ddb4d6dae767d97c466fb92f1b59a2c71ca29ac954692663f9db03426fb", - }, - - // get-vanilla-query - V4SignerSuiteCase{ - label: "get-vanilla-query", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1", - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470", - }, - - // get-vanilla-ut8-query - V4SignerSuiteCase{ - label: "get-vanilla-ut8-query", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/?ሴ=bar", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/\n%E1%88%B4=bar\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\nde5065ff39c131e6c2e2bd19cd9345a794bf3b561eab20b8d97b2093fc2a979e", - signature: "6fb359e9a05394cc7074e0feb42573a2601abc0c869a953e8c5c12e4e01f1a8c", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=6fb359e9a05394cc7074e0feb42573a2601abc0c869a953e8c5c12e4e01f1a8c", - }, - - // get-vanilla - V4SignerSuiteCase{ - label: "get-vanilla", - request: V4SignerSuiteCaseRequest{ - method: "GET", - host: "host.foo.com", - url: "/", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1", - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470", - }, - - // post-header-key-case - V4SignerSuiteCase{ - label: "post-header-key-case", - request: V4SignerSuiteCaseRequest{ - method: "POST", - host: "host.foo.com", - url: "/", - headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n05da62cee468d24ae84faff3c39f1b85540de60243c1bcaace39c0a2acc7b2c4", - signature: "22902d79e148b64e7571c3565769328423fe276eae4b26f83afceda9e767f726", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=22902d79e148b64e7571c3565769328423fe276eae4b26f83afceda9e767f726", - }, - - // post-header-key-sort - V4SignerSuiteCase{ - label: "post-header-key-sort", - request: V4SignerSuiteCaseRequest{ - method: "POST", - host: "host.foo.com", - url: "/", - headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "ZOO:zoobar"}, - }, - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\nzoo:zoobar\n\ndate;host;zoo\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n34e1bddeb99e76ee01d63b5e28656111e210529efeec6cdfd46a48e4c734545d", - signature: "b7a95a52518abbca0964a999a880429ab734f35ebbf1235bd79a5de87756dc4a", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;zoo, Signature=b7a95a52518abbca0964a999a880429ab734f35ebbf1235bd79a5de87756dc4a", - }, - - // post-header-value-case - V4SignerSuiteCase{ - label: "post-header-value-case", - request: V4SignerSuiteCaseRequest{ - method: "POST", - host: "host.foo.com", - url: "/", - headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "zoo:ZOOBAR"}, - }, - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\nzoo:ZOOBAR\n\ndate;host;zoo\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n3aae6d8274b8c03e2cc96fc7d6bda4b9bd7a0a184309344470b2c96953e124aa", - signature: "273313af9d0c265c531e11db70bbd653f3ba074c1009239e8559d3987039cad7", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;zoo, Signature=273313af9d0c265c531e11db70bbd653f3ba074c1009239e8559d3987039cad7", - }, - - // post-vanilla-empty-query-value - V4SignerSuiteCase{ - label: "post-vanilla-empty-query-value", - request: V4SignerSuiteCaseRequest{ - method: "POST", - host: "host.foo.com", - url: "/?foo=bar", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "POST\n/\nfoo=bar\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ncd4f39132d8e60bb388831d734230460872b564871c47f5de62e62d1a68dbe1e", - signature: "b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92", - }, - - // post-vanilla-query - V4SignerSuiteCase{ - label: "post-vanilla-query", - request: V4SignerSuiteCaseRequest{ - method: "POST", - host: "host.foo.com", - url: "/?foo=bar", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "POST\n/\nfoo=bar\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ncd4f39132d8e60bb388831d734230460872b564871c47f5de62e62d1a68dbe1e", - signature: "b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92", - }, - - // post-vanilla - V4SignerSuiteCase{ - label: "post-vanilla", - request: V4SignerSuiteCaseRequest{ - method: "POST", - host: "host.foo.com", - url: "/", - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - }, - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n05da62cee468d24ae84faff3c39f1b85540de60243c1bcaace39c0a2acc7b2c4", - signature: "22902d79e148b64e7571c3565769328423fe276eae4b26f83afceda9e767f726", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=22902d79e148b64e7571c3565769328423fe276eae4b26f83afceda9e767f726", - }, - - // post-x-www-form-urlencoded-parameters - V4SignerSuiteCase{ - label: "post-x-www-form-urlencoded-parameters", - request: V4SignerSuiteCaseRequest{ - method: "POST", - host: "host.foo.com", - url: "/", - headers: []string{"Content-Type:application/x-www-form-urlencoded; charset=utf8", "Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - body: "foo=bar", - }, - canonicalRequest: "POST\n/\n\ncontent-type:application/x-www-form-urlencoded; charset=utf8\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ncontent-type;date;host\n3ba8907e7a252327488df390ed517c45b96dead033600219bdca7107d1d3f88a", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\nc4115f9e54b5cecf192b1eaa23b8e88ed8dc5391bd4fde7b3fff3d9c9fe0af1f", - signature: "b105eb10c6d318d2294de9d49dd8b031b55e3c3fe139f2e637da70511e9e7b71", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=content-type;date;host, Signature=b105eb10c6d318d2294de9d49dd8b031b55e3c3fe139f2e637da70511e9e7b71", - }, - - // post-x-www-form-urlencoded - V4SignerSuiteCase{ - label: "post-x-www-form-urlencoded", - request: V4SignerSuiteCaseRequest{ - method: "POST", - host: "host.foo.com", - url: "/", - headers: []string{"Content-Type:application/x-www-form-urlencoded", "Date:Mon, 09 Sep 2011 23:36:00 GMT"}, - body: "foo=bar", - }, - canonicalRequest: "POST\n/\n\ncontent-type:application/x-www-form-urlencoded\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ncontent-type;date;host\n3ba8907e7a252327488df390ed517c45b96dead033600219bdca7107d1d3f88a", - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n4c5c6e4b52fb5fb947a8733982a8a5a61b14f04345cbfe6e739236c76dd48f74", - signature: "5a15b22cf462f047318703b92e6f4f38884e4a7ab7b1d6426ca46a8bd1c26cbc", - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=content-type;date;host, Signature=5a15b22cf462f047318703b92e6f4f38884e4a7ab7b1d6426ca46a8bd1c26cbc", - }, - ) -} - -func (s *V4SignerSuite) TestCases(c *C) { - signer := aws.NewV4Signer(s.auth, "host", s.region) - - for _, testCase := range s.cases { - - req, err := http.NewRequest(testCase.request.method, "http://"+testCase.request.host+testCase.request.url, strings.NewReader(testCase.request.body)) - c.Assert(err, IsNil, Commentf("Testcase: %s", testCase.label)) - for _, v := range testCase.request.headers { - h := strings.SplitN(v, ":", 2) - req.Header.Add(h[0], h[1]) - } - req.Header.Set("host", req.Host) - - t := signer.RequestTime(req) - - canonicalRequest := signer.CanonicalRequest(req) - c.Check(canonicalRequest, Equals, testCase.canonicalRequest, Commentf("Testcase: %s", testCase.label)) - - stringToSign := signer.StringToSign(t, canonicalRequest) - c.Check(stringToSign, Equals, testCase.stringToSign, Commentf("Testcase: %s", testCase.label)) - - signature := signer.Signature(t, stringToSign) - c.Check(signature, Equals, testCase.signature, Commentf("Testcase: %s", testCase.label)) - - authorization := signer.Authorization(req.Header, t, signature) - c.Check(authorization, Equals, testCase.authorization, Commentf("Testcase: %s", testCase.label)) - - signer.Sign(req) - c.Check(req.Header.Get("Authorization"), Equals, testCase.authorization, Commentf("Testcase: %s", testCase.label)) - } -} - -func ExampleV4Signer() { - // Get auth from env vars - auth, err := aws.EnvAuth() - if err != nil { - fmt.Println(err) - } - - // Create a signer with the auth, name of the service, and aws region - signer := aws.NewV4Signer(auth, "dynamodb", aws.USEast) - - // Create a request - req, err := http.NewRequest("POST", aws.USEast.DynamoDBEndpoint, strings.NewReader("sample_request")) - if err != nil { - fmt.Println(err) - } - - // Date or x-amz-date header is required to sign a request - req.Header.Add("Date", time.Now().UTC().Format(http.TimeFormat)) - - // Sign the request - signer.Sign(req) - - // Issue signed request - http.DefaultClient.Do(req) -} diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/s3/export_test.go b/Godeps/_workspace/src/github.com/goamz/goamz/s3/export_test.go deleted file mode 100644 index 4ff913cde..000000000 --- a/Godeps/_workspace/src/github.com/goamz/goamz/s3/export_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package s3 - -import ( - "github.com/goamz/goamz/aws" -) - -func Sign(auth aws.Auth, method, path string, params, headers map[string][]string) { - sign(auth, method, path, params, headers) -} - -func SetListPartsMax(n int) { - listPartsMax = n -} - -func SetListMultiMax(n int) { - listMultiMax = n -} diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/s3/multi_test.go b/Godeps/_workspace/src/github.com/goamz/goamz/s3/multi_test.go deleted file mode 100644 index 5c788d9cc..000000000 --- a/Godeps/_workspace/src/github.com/goamz/goamz/s3/multi_test.go +++ /dev/null @@ -1,373 +0,0 @@ -package s3_test - -import ( - "encoding/xml" - "io" - "io/ioutil" - "strings" - - "github.com/goamz/goamz/s3" - . "gopkg.in/check.v1" -) - -func (s *S) TestInitMulti(c *C) { - testServer.Response(200, nil, InitMultiResultDump) - - b := s.s3.Bucket("sample") - - multi, err := b.InitMulti("multi", "text/plain", s3.Private) - c.Assert(err, IsNil) - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "POST") - c.Assert(req.URL.Path, Equals, "/sample/multi") - c.Assert(req.Header["Content-Type"], DeepEquals, []string{"text/plain"}) - c.Assert(req.Header["X-Amz-Acl"], DeepEquals, []string{"private"}) - c.Assert(req.Form["uploads"], DeepEquals, []string{""}) - - c.Assert(multi.UploadId, Matches, "JNbR_[A-Za-z0-9.]+QQ--") -} - -func (s *S) TestMultiNoPreviousUpload(c *C) { - // Don't retry the NoSuchUpload error. - s.DisableRetries() - - testServer.Response(404, nil, NoSuchUploadErrorDump) - testServer.Response(200, nil, InitMultiResultDump) - - b := s.s3.Bucket("sample") - - multi, err := b.Multi("multi", "text/plain", s3.Private) - c.Assert(err, IsNil) - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/sample/") - c.Assert(req.Form["uploads"], DeepEquals, []string{""}) - c.Assert(req.Form["prefix"], DeepEquals, []string{"multi"}) - - req = testServer.WaitRequest() - c.Assert(req.Method, Equals, "POST") - c.Assert(req.URL.Path, Equals, "/sample/multi") - c.Assert(req.Form["uploads"], DeepEquals, []string{""}) - - c.Assert(multi.UploadId, Matches, "JNbR_[A-Za-z0-9.]+QQ--") -} - -func (s *S) TestMultiReturnOld(c *C) { - testServer.Response(200, nil, ListMultiResultDump) - - b := s.s3.Bucket("sample") - - multi, err := b.Multi("multi1", "text/plain", s3.Private) - c.Assert(err, IsNil) - c.Assert(multi.Key, Equals, "multi1") - c.Assert(multi.UploadId, Equals, "iUVug89pPvSswrikD") - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/sample/") - c.Assert(req.Form["uploads"], DeepEquals, []string{""}) - c.Assert(req.Form["prefix"], DeepEquals, []string{"multi1"}) -} - -func (s *S) TestListParts(c *C) { - testServer.Response(200, nil, InitMultiResultDump) - testServer.Response(200, nil, ListPartsResultDump1) - testServer.Response(404, nil, NoSuchUploadErrorDump) // :-( - testServer.Response(200, nil, ListPartsResultDump2) - - b := s.s3.Bucket("sample") - - multi, err := b.InitMulti("multi", "text/plain", s3.Private) - c.Assert(err, IsNil) - - parts, err := multi.ListParts() - c.Assert(err, IsNil) - c.Assert(parts, HasLen, 3) - c.Assert(parts[0].N, Equals, 1) - c.Assert(parts[0].Size, Equals, int64(5)) - c.Assert(parts[0].ETag, Equals, `"ffc88b4ca90a355f8ddba6b2c3b2af5c"`) - c.Assert(parts[1].N, Equals, 2) - c.Assert(parts[1].Size, Equals, int64(5)) - c.Assert(parts[1].ETag, Equals, `"d067a0fa9dc61a6e7195ca99696b5a89"`) - c.Assert(parts[2].N, Equals, 3) - c.Assert(parts[2].Size, Equals, int64(5)) - c.Assert(parts[2].ETag, Equals, `"49dcd91231f801159e893fb5c6674985"`) - testServer.WaitRequest() - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/sample/multi") - c.Assert(req.Form.Get("uploadId"), Matches, "JNbR_[A-Za-z0-9.]+QQ--") - c.Assert(req.Form["max-parts"], DeepEquals, []string{"1000"}) - - testServer.WaitRequest() // The internal error. - req = testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/sample/multi") - c.Assert(req.Form.Get("uploadId"), Matches, "JNbR_[A-Za-z0-9.]+QQ--") - c.Assert(req.Form["max-parts"], DeepEquals, []string{"1000"}) - c.Assert(req.Form["part-number-marker"], DeepEquals, []string{"2"}) -} - -func (s *S) TestPutPart(c *C) { - headers := map[string]string{ - "ETag": `"26f90efd10d614f100252ff56d88dad8"`, - } - testServer.Response(200, nil, InitMultiResultDump) - testServer.Response(200, headers, "") - - b := s.s3.Bucket("sample") - - multi, err := b.InitMulti("multi", "text/plain", s3.Private) - c.Assert(err, IsNil) - - part, err := multi.PutPart(1, strings.NewReader("<part 1>")) - c.Assert(err, IsNil) - c.Assert(part.N, Equals, 1) - c.Assert(part.Size, Equals, int64(8)) - c.Assert(part.ETag, Equals, headers["ETag"]) - - testServer.WaitRequest() - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "PUT") - c.Assert(req.URL.Path, Equals, "/sample/multi") - c.Assert(req.Form.Get("uploadId"), Matches, "JNbR_[A-Za-z0-9.]+QQ--") - c.Assert(req.Form["partNumber"], DeepEquals, []string{"1"}) - c.Assert(req.Header["Content-Length"], DeepEquals, []string{"8"}) - c.Assert(req.Header["Content-Md5"], DeepEquals, []string{"JvkO/RDWFPEAJS/1bYja2A=="}) -} - -func readAll(r io.Reader) string { - data, err := ioutil.ReadAll(r) - if err != nil { - panic(err) - } - return string(data) -} - -func (s *S) TestPutAllNoPreviousUpload(c *C) { - // Don't retry the NoSuchUpload error. - s.DisableRetries() - - etag1 := map[string]string{"ETag": `"etag1"`} - etag2 := map[string]string{"ETag": `"etag2"`} - etag3 := map[string]string{"ETag": `"etag3"`} - testServer.Response(200, nil, InitMultiResultDump) - testServer.Response(404, nil, NoSuchUploadErrorDump) - testServer.Response(200, etag1, "") - testServer.Response(200, etag2, "") - testServer.Response(200, etag3, "") - - b := s.s3.Bucket("sample") - - multi, err := b.InitMulti("multi", "text/plain", s3.Private) - c.Assert(err, IsNil) - - parts, err := multi.PutAll(strings.NewReader("part1part2last"), 5) - c.Assert(parts, HasLen, 3) - c.Assert(parts[0].ETag, Equals, `"etag1"`) - c.Assert(parts[1].ETag, Equals, `"etag2"`) - c.Assert(parts[2].ETag, Equals, `"etag3"`) - c.Assert(err, IsNil) - - // Init - testServer.WaitRequest() - - // List old parts. Won't find anything. - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/sample/multi") - - // Send part 1. - req = testServer.WaitRequest() - c.Assert(req.Method, Equals, "PUT") - c.Assert(req.URL.Path, Equals, "/sample/multi") - c.Assert(req.Form["partNumber"], DeepEquals, []string{"1"}) - c.Assert(req.Header["Content-Length"], DeepEquals, []string{"5"}) - c.Assert(readAll(req.Body), Equals, "part1") - - // Send part 2. - req = testServer.WaitRequest() - c.Assert(req.Method, Equals, "PUT") - c.Assert(req.URL.Path, Equals, "/sample/multi") - c.Assert(req.Form["partNumber"], DeepEquals, []string{"2"}) - c.Assert(req.Header["Content-Length"], DeepEquals, []string{"5"}) - c.Assert(readAll(req.Body), Equals, "part2") - - // Send part 3 with shorter body. - req = testServer.WaitRequest() - c.Assert(req.Method, Equals, "PUT") - c.Assert(req.URL.Path, Equals, "/sample/multi") - c.Assert(req.Form["partNumber"], DeepEquals, []string{"3"}) - c.Assert(req.Header["Content-Length"], DeepEquals, []string{"4"}) - c.Assert(readAll(req.Body), Equals, "last") -} - -func (s *S) TestPutAllZeroSizeFile(c *C) { - // Don't retry the NoSuchUpload error. - s.DisableRetries() - - etag1 := map[string]string{"ETag": `"etag1"`} - testServer.Response(200, nil, InitMultiResultDump) - testServer.Response(404, nil, NoSuchUploadErrorDump) - testServer.Response(200, etag1, "") - - b := s.s3.Bucket("sample") - - multi, err := b.InitMulti("multi", "text/plain", s3.Private) - c.Assert(err, IsNil) - - // Must send at least one part, so that completing it will work. - parts, err := multi.PutAll(strings.NewReader(""), 5) - c.Assert(parts, HasLen, 1) - c.Assert(parts[0].ETag, Equals, `"etag1"`) - c.Assert(err, IsNil) - - // Init - testServer.WaitRequest() - - // List old parts. Won't find anything. - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/sample/multi") - - // Send empty part. - req = testServer.WaitRequest() - c.Assert(req.Method, Equals, "PUT") - c.Assert(req.URL.Path, Equals, "/sample/multi") - c.Assert(req.Form["partNumber"], DeepEquals, []string{"1"}) - c.Assert(req.Header["Content-Length"], DeepEquals, []string{"0"}) - c.Assert(readAll(req.Body), Equals, "") -} - -func (s *S) TestPutAllResume(c *C) { - etag2 := map[string]string{"ETag": `"etag2"`} - testServer.Response(200, nil, InitMultiResultDump) - testServer.Response(200, nil, ListPartsResultDump1) - testServer.Response(200, nil, ListPartsResultDump2) - testServer.Response(200, etag2, "") - - b := s.s3.Bucket("sample") - - multi, err := b.InitMulti("multi", "text/plain", s3.Private) - c.Assert(err, IsNil) - - // "part1" and "part3" match the checksums in ResultDump1. - // The middle one is a mismatch (it refers to "part2"). - parts, err := multi.PutAll(strings.NewReader("part1partXpart3"), 5) - c.Assert(parts, HasLen, 3) - c.Assert(parts[0].N, Equals, 1) - c.Assert(parts[0].Size, Equals, int64(5)) - c.Assert(parts[0].ETag, Equals, `"ffc88b4ca90a355f8ddba6b2c3b2af5c"`) - c.Assert(parts[1].N, Equals, 2) - c.Assert(parts[1].Size, Equals, int64(5)) - c.Assert(parts[1].ETag, Equals, `"etag2"`) - c.Assert(parts[2].N, Equals, 3) - c.Assert(parts[2].Size, Equals, int64(5)) - c.Assert(parts[2].ETag, Equals, `"49dcd91231f801159e893fb5c6674985"`) - c.Assert(err, IsNil) - - // Init - testServer.WaitRequest() - - // List old parts, broken in two requests. - for i := 0; i < 2; i++ { - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/sample/multi") - } - - // Send part 2, as it didn't match the checksum. - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "PUT") - c.Assert(req.URL.Path, Equals, "/sample/multi") - c.Assert(req.Form["partNumber"], DeepEquals, []string{"2"}) - c.Assert(req.Header["Content-Length"], DeepEquals, []string{"5"}) - c.Assert(readAll(req.Body), Equals, "partX") -} - -func (s *S) TestMultiComplete(c *C) { - testServer.Response(200, nil, InitMultiResultDump) - // Note the 200 response. Completing will hold the connection on some - // kind of long poll, and may return a late error even after a 200. - testServer.Response(200, nil, InternalErrorDump) - testServer.Response(200, nil, "") - - b := s.s3.Bucket("sample") - - multi, err := b.InitMulti("multi", "text/plain", s3.Private) - c.Assert(err, IsNil) - - err = multi.Complete([]s3.Part{{2, `"ETag2"`, 32}, {1, `"ETag1"`, 64}}) - // returns InternalErrorDump in the payload, which should manifest as - // an error. - c.Assert(err, NotNil) - - testServer.WaitRequest() - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "POST") - c.Assert(req.URL.Path, Equals, "/sample/multi") - c.Assert(req.Form.Get("uploadId"), Matches, "JNbR_[A-Za-z0-9.]+QQ--") - - var payload struct { - XMLName xml.Name - Part []struct { - PartNumber int - ETag string - } - } - - dec := xml.NewDecoder(req.Body) - err = dec.Decode(&payload) - c.Assert(err, IsNil) - - c.Assert(payload.XMLName.Local, Equals, "CompleteMultipartUpload") - c.Assert(len(payload.Part), Equals, 2) - c.Assert(payload.Part[0].PartNumber, Equals, 1) - c.Assert(payload.Part[0].ETag, Equals, `"ETag1"`) - c.Assert(payload.Part[1].PartNumber, Equals, 2) - c.Assert(payload.Part[1].ETag, Equals, `"ETag2"`) -} - -func (s *S) TestMultiAbort(c *C) { - testServer.Response(200, nil, InitMultiResultDump) - testServer.Response(200, nil, "") - - b := s.s3.Bucket("sample") - - multi, err := b.InitMulti("multi", "text/plain", s3.Private) - c.Assert(err, IsNil) - - err = multi.Abort() - c.Assert(err, IsNil) - - testServer.WaitRequest() - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "DELETE") - c.Assert(req.URL.Path, Equals, "/sample/multi") - c.Assert(req.Form.Get("uploadId"), Matches, "JNbR_[A-Za-z0-9.]+QQ--") -} - -func (s *S) TestListMulti(c *C) { - testServer.Response(200, nil, ListMultiResultDump) - - b := s.s3.Bucket("sample") - - multis, prefixes, err := b.ListMulti("", "/") - c.Assert(err, IsNil) - c.Assert(prefixes, DeepEquals, []string{"a/", "b/"}) - c.Assert(multis, HasLen, 2) - c.Assert(multis[0].Key, Equals, "multi1") - c.Assert(multis[0].UploadId, Equals, "iUVug89pPvSswrikD") - c.Assert(multis[1].Key, Equals, "multi2") - c.Assert(multis[1].UploadId, Equals, "DkirwsSvPp98guVUi") - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/sample/") - c.Assert(req.Form["uploads"], DeepEquals, []string{""}) - c.Assert(req.Form["prefix"], DeepEquals, []string{""}) - c.Assert(req.Form["delimiter"], DeepEquals, []string{"/"}) - c.Assert(req.Form["max-uploads"], DeepEquals, []string{"1000"}) -} diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/s3/responses_test.go b/Godeps/_workspace/src/github.com/goamz/goamz/s3/responses_test.go deleted file mode 100644 index 414ede0a7..000000000 --- a/Godeps/_workspace/src/github.com/goamz/goamz/s3/responses_test.go +++ /dev/null @@ -1,202 +0,0 @@ -package s3_test - -var GetObjectErrorDump = ` -<?xml version="1.0" encoding="UTF-8"?> -<Error> - <Code>NoSuchBucket</Code> - <Message>The specified bucket does not exist</Message> - <BucketName>non-existent-bucket</BucketName> - <RequestId>3F1B667FAD71C3D8</RequestId> - <HostId>L4ee/zrm1irFXY5F45fKXIRdOf9ktsKY/8TDVawuMK2jWRb1RF84i1uBzkdNqS5D</HostId> -</Error> -` - -var GetListResultDump1 = ` -<?xml version="1.0" encoding="UTF-8"?> -<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01"> - <Name>quotes</Name> - <Prefix>N</Prefix> - <IsTruncated>false</IsTruncated> - <Contents> - <Key>Nelson</Key> - <LastModified>2006-01-01T12:00:00.000Z</LastModified> - <ETag>"828ef3fdfa96f00ad9f27c383fc9ac7f"</ETag> - <Size>5</Size> - <StorageClass>STANDARD</StorageClass> - <Owner> - <ID>bcaf161ca5fb16fd081034f</ID> - <DisplayName>webfile</DisplayName> - </Owner> - </Contents> - <Contents> - <Key>Neo</Key> - <LastModified>2006-01-01T12:00:00.000Z</LastModified> - <ETag>"828ef3fdfa96f00ad9f27c383fc9ac7f"</ETag> - <Size>4</Size> - <StorageClass>STANDARD</StorageClass> - <Owner> - <ID>bcaf1ffd86a5fb16fd081034f</ID> - <DisplayName>webfile</DisplayName> - </Owner> - </Contents> -</ListBucketResult> -` - -var GetListResultDump2 = ` -<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> - <Name>example-bucket</Name> - <Prefix>photos/2006/</Prefix> - <Marker>some-marker</Marker> - <MaxKeys>1000</MaxKeys> - <Delimiter>/</Delimiter> - <IsTruncated>false</IsTruncated> - - <CommonPrefixes> - <Prefix>photos/2006/feb/</Prefix> - </CommonPrefixes> - <CommonPrefixes> - <Prefix>photos/2006/jan/</Prefix> - </CommonPrefixes> -</ListBucketResult> -` - -var InitMultiResultDump = ` -<?xml version="1.0" encoding="UTF-8"?> -<InitiateMultipartUploadResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> - <Bucket>sample</Bucket> - <Key>multi</Key> - <UploadId>JNbR_cMdwnGiD12jKAd6WK2PUkfj2VxA7i4nCwjE6t71nI9Tl3eVDPFlU0nOixhftH7I17ZPGkV3QA.l7ZD.QQ--</UploadId> -</InitiateMultipartUploadResult> -` - -var ListPartsResultDump1 = ` -<?xml version="1.0" encoding="UTF-8"?> -<ListPartsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> - <Bucket>sample</Bucket> - <Key>multi</Key> - <UploadId>JNbR_cMdwnGiD12jKAd6WK2PUkfj2VxA7i4nCwjE6t71nI9Tl3eVDPFlU0nOixhftH7I17ZPGkV3QA.l7ZD.QQ--</UploadId> - <Initiator> - <ID>bb5c0f63b0b25f2d099c</ID> - <DisplayName>joe</DisplayName> - </Initiator> - <Owner> - <ID>bb5c0f63b0b25f2d099c</ID> - <DisplayName>joe</DisplayName> - </Owner> - <StorageClass>STANDARD</StorageClass> - <PartNumberMarker>0</PartNumberMarker> - <NextPartNumberMarker>2</NextPartNumberMarker> - <MaxParts>2</MaxParts> - <IsTruncated>true</IsTruncated> - <Part> - <PartNumber>1</PartNumber> - <LastModified>2013-01-30T13:45:51.000Z</LastModified> - <ETag>"ffc88b4ca90a355f8ddba6b2c3b2af5c"</ETag> - <Size>5</Size> - </Part> - <Part> - <PartNumber>2</PartNumber> - <LastModified>2013-01-30T13:45:52.000Z</LastModified> - <ETag>"d067a0fa9dc61a6e7195ca99696b5a89"</ETag> - <Size>5</Size> - </Part> -</ListPartsResult> -` - -var ListPartsResultDump2 = ` -<?xml version="1.0" encoding="UTF-8"?> -<ListPartsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> - <Bucket>sample</Bucket> - <Key>multi</Key> - <UploadId>JNbR_cMdwnGiD12jKAd6WK2PUkfj2VxA7i4nCwjE6t71nI9Tl3eVDPFlU0nOixhftH7I17ZPGkV3QA.l7ZD.QQ--</UploadId> - <Initiator> - <ID>bb5c0f63b0b25f2d099c</ID> - <DisplayName>joe</DisplayName> - </Initiator> - <Owner> - <ID>bb5c0f63b0b25f2d099c</ID> - <DisplayName>joe</DisplayName> - </Owner> - <StorageClass>STANDARD</StorageClass> - <PartNumberMarker>2</PartNumberMarker> - <NextPartNumberMarker>3</NextPartNumberMarker> - <MaxParts>2</MaxParts> - <IsTruncated>false</IsTruncated> - <Part> - <PartNumber>3</PartNumber> - <LastModified>2013-01-30T13:46:50.000Z</LastModified> - <ETag>"49dcd91231f801159e893fb5c6674985"</ETag> - <Size>5</Size> - </Part> -</ListPartsResult> -` - -var ListMultiResultDump = ` -<?xml version="1.0"?> -<ListMultipartUploadsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> - <Bucket>goamz-test-bucket-us-east-1-akiajk3wyewhctyqbf7a</Bucket> - <KeyMarker/> - <UploadIdMarker/> - <NextKeyMarker>multi1</NextKeyMarker> - <NextUploadIdMarker>iUVug89pPvSswrikD72p8uO62EzhNtpDxRmwC5WSiWDdK9SfzmDqe3xpP1kMWimyimSnz4uzFc3waVM5ufrKYQ--</NextUploadIdMarker> - <Delimiter>/</Delimiter> - <MaxUploads>1000</MaxUploads> - <IsTruncated>false</IsTruncated> - <Upload> - <Key>multi1</Key> - <UploadId>iUVug89pPvSswrikD</UploadId> - <Initiator> - <ID>bb5c0f63b0b25f2d0</ID> - <DisplayName>gustavoniemeyer</DisplayName> - </Initiator> - <Owner> - <ID>bb5c0f63b0b25f2d0</ID> - <DisplayName>gustavoniemeyer</DisplayName> - </Owner> - <StorageClass>STANDARD</StorageClass> - <Initiated>2013-01-30T18:15:47.000Z</Initiated> - </Upload> - <Upload> - <Key>multi2</Key> - <UploadId>DkirwsSvPp98guVUi</UploadId> - <Initiator> - <ID>bb5c0f63b0b25f2d0</ID> - <DisplayName>joe</DisplayName> - </Initiator> - <Owner> - <ID>bb5c0f63b0b25f2d0</ID> - <DisplayName>joe</DisplayName> - </Owner> - <StorageClass>STANDARD</StorageClass> - <Initiated>2013-01-30T18:15:47.000Z</Initiated> - </Upload> - <CommonPrefixes> - <Prefix>a/</Prefix> - </CommonPrefixes> - <CommonPrefixes> - <Prefix>b/</Prefix> - </CommonPrefixes> -</ListMultipartUploadsResult> -` - -var NoSuchUploadErrorDump = ` -<?xml version="1.0" encoding="UTF-8"?> -<Error> - <Code>NoSuchUpload</Code> - <Message>Not relevant</Message> - <BucketName>sample</BucketName> - <RequestId>3F1B667FAD71C3D8</RequestId> - <HostId>kjhwqk</HostId> -</Error> -` - -var InternalErrorDump = ` -<?xml version="1.0" encoding="UTF-8"?> -<Error> - <Code>InternalError</Code> - <Message>Not relevant</Message> - <BucketName>sample</BucketName> - <RequestId>3F1B667FAD71C3D8</RequestId> - <HostId>kjhwqk</HostId> -</Error> -` diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3_test.go b/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3_test.go deleted file mode 100644 index 24d4dfcc0..000000000 --- a/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3_test.go +++ /dev/null @@ -1,427 +0,0 @@ -package s3_test - -import ( - "bytes" - "io/ioutil" - "net/http" - "testing" - "time" - - "github.com/goamz/goamz/aws" - "github.com/goamz/goamz/s3" - "github.com/goamz/goamz/testutil" - . "gopkg.in/check.v1" -) - -func Test(t *testing.T) { - TestingT(t) -} - -type S struct { - s3 *s3.S3 -} - -var _ = Suite(&S{}) - -var testServer = testutil.NewHTTPServer() - -func (s *S) SetUpSuite(c *C) { - testServer.Start() - auth := aws.Auth{AccessKey: "abc", SecretKey: "123"} - s.s3 = s3.New(auth, aws.Region{Name: "faux-region-1", S3Endpoint: testServer.URL}) -} - -func (s *S) TearDownSuite(c *C) { - s.s3.AttemptStrategy = s3.DefaultAttemptStrategy -} - -func (s *S) SetUpTest(c *C) { - s.s3.AttemptStrategy = aws.AttemptStrategy{ - Total: 300 * time.Millisecond, - Delay: 100 * time.Millisecond, - } -} - -func (s *S) TearDownTest(c *C) { - testServer.Flush() -} - -func (s *S) DisableRetries() { - s.s3.AttemptStrategy = aws.AttemptStrategy{} -} - -// PutBucket docs: http://goo.gl/kBTCu - -func (s *S) TestPutBucket(c *C) { - testServer.Response(200, nil, "") - - b := s.s3.Bucket("bucket") - err := b.PutBucket(s3.Private) - c.Assert(err, IsNil) - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "PUT") - c.Assert(req.URL.Path, Equals, "/bucket/") - c.Assert(req.Header["Date"], Not(Equals), "") -} - -// Head docs: http://bit.ly/17K1ylI - -func (s *S) TestHead(c *C) { - testServer.Response(200, nil, "content") - - b := s.s3.Bucket("bucket") - resp, err := b.Head("name", nil) - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "HEAD") - c.Assert(req.URL.Path, Equals, "/bucket/name") - c.Assert(req.Header["Date"], Not(Equals), "") - - c.Assert(err, IsNil) - c.Assert(resp.ContentLength, FitsTypeOf, int64(0)) - c.Assert(resp, FitsTypeOf, &http.Response{}) -} - -// DeleteBucket docs: http://goo.gl/GoBrY - -func (s *S) TestDelBucket(c *C) { - testServer.Response(204, nil, "") - - b := s.s3.Bucket("bucket") - err := b.DelBucket() - c.Assert(err, IsNil) - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "DELETE") - c.Assert(req.URL.Path, Equals, "/bucket/") - c.Assert(req.Header["Date"], Not(Equals), "") -} - -// GetObject docs: http://goo.gl/isCO7 - -func (s *S) TestGet(c *C) { - testServer.Response(200, nil, "content") - - b := s.s3.Bucket("bucket") - data, err := b.Get("name") - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/bucket/name") - c.Assert(req.Header["Date"], Not(Equals), "") - - c.Assert(err, IsNil) - c.Assert(string(data), Equals, "content") -} - -func (s *S) TestURL(c *C) { - testServer.Response(200, nil, "content") - - b := s.s3.Bucket("bucket") - url := b.URL("name") - r, err := http.Get(url) - c.Assert(err, IsNil) - data, err := ioutil.ReadAll(r.Body) - r.Body.Close() - c.Assert(err, IsNil) - c.Assert(string(data), Equals, "content") - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/bucket/name") -} - -func (s *S) TestGetReader(c *C) { - testServer.Response(200, nil, "content") - - b := s.s3.Bucket("bucket") - rc, err := b.GetReader("name") - c.Assert(err, IsNil) - data, err := ioutil.ReadAll(rc) - rc.Close() - c.Assert(err, IsNil) - c.Assert(string(data), Equals, "content") - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/bucket/name") - c.Assert(req.Header["Date"], Not(Equals), "") -} - -func (s *S) TestGetNotFound(c *C) { - for i := 0; i < 10; i++ { - testServer.Response(404, nil, GetObjectErrorDump) - } - - b := s.s3.Bucket("non-existent-bucket") - data, err := b.Get("non-existent") - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/non-existent-bucket/non-existent") - c.Assert(req.Header["Date"], Not(Equals), "") - - s3err, _ := err.(*s3.Error) - c.Assert(s3err, NotNil) - c.Assert(s3err.StatusCode, Equals, 404) - c.Assert(s3err.BucketName, Equals, "non-existent-bucket") - c.Assert(s3err.RequestId, Equals, "3F1B667FAD71C3D8") - c.Assert(s3err.HostId, Equals, "L4ee/zrm1irFXY5F45fKXIRdOf9ktsKY/8TDVawuMK2jWRb1RF84i1uBzkdNqS5D") - c.Assert(s3err.Code, Equals, "NoSuchBucket") - c.Assert(s3err.Message, Equals, "The specified bucket does not exist") - c.Assert(s3err.Error(), Equals, "The specified bucket does not exist") - c.Assert(data, IsNil) -} - -// PutObject docs: http://goo.gl/FEBPD - -func (s *S) TestPutObject(c *C) { - testServer.Response(200, nil, "") - - b := s.s3.Bucket("bucket") - err := b.Put("name", []byte("content"), "content-type", s3.Private, s3.Options{}) - c.Assert(err, IsNil) - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "PUT") - c.Assert(req.URL.Path, Equals, "/bucket/name") - c.Assert(req.Header["Date"], Not(DeepEquals), []string{""}) - c.Assert(req.Header["Content-Type"], DeepEquals, []string{"content-type"}) - c.Assert(req.Header["Content-Length"], DeepEquals, []string{"7"}) - //c.Assert(req.Header["Content-MD5"], DeepEquals, "...") - c.Assert(req.Header["X-Amz-Acl"], DeepEquals, []string{"private"}) -} - -func (s *S) TestPutObjectReadTimeout(c *C) { - s.s3.ReadTimeout = 50 * time.Millisecond - defer func() { - s.s3.ReadTimeout = 0 - }() - - b := s.s3.Bucket("bucket") - err := b.Put("name", []byte("content"), "content-type", s3.Private, s3.Options{}) - - // Make sure that we get a timeout error. - c.Assert(err, NotNil) - - // Set the response after the request times out so that the next request will work. - testServer.Response(200, nil, "") - - // This time set the response within our timeout period so that we expect the call - // to return successfully. - go func() { - time.Sleep(25 * time.Millisecond) - testServer.Response(200, nil, "") - }() - err = b.Put("name", []byte("content"), "content-type", s3.Private, s3.Options{}) - c.Assert(err, IsNil) -} - -func (s *S) TestPutObjectHeader(c *C) { - testServer.Response(200, nil, "") - - b := s.s3.Bucket("bucket") - err := b.PutHeader( - "name", - []byte("content"), - map[string][]string{"Content-Type": {"content-type"}}, - s3.Private, - ) - c.Assert(err, IsNil) - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "PUT") - c.Assert(req.URL.Path, Equals, "/bucket/name") - c.Assert(req.Header["Date"], Not(DeepEquals), []string{""}) - c.Assert(req.Header["Content-Type"], DeepEquals, []string{"content-type"}) - c.Assert(req.Header["Content-Length"], DeepEquals, []string{"7"}) - //c.Assert(req.Header["Content-MD5"], DeepEquals, "...") - c.Assert(req.Header["X-Amz-Acl"], DeepEquals, []string{"private"}) -} - -func (s *S) TestPutReader(c *C) { - testServer.Response(200, nil, "") - - b := s.s3.Bucket("bucket") - buf := bytes.NewBufferString("content") - err := b.PutReader("name", buf, int64(buf.Len()), "content-type", s3.Private, s3.Options{}) - c.Assert(err, IsNil) - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "PUT") - c.Assert(req.URL.Path, Equals, "/bucket/name") - c.Assert(req.Header["Date"], Not(DeepEquals), []string{""}) - c.Assert(req.Header["Content-Type"], DeepEquals, []string{"content-type"}) - c.Assert(req.Header["Content-Length"], DeepEquals, []string{"7"}) - //c.Assert(req.Header["Content-MD5"], Equals, "...") - c.Assert(req.Header["X-Amz-Acl"], DeepEquals, []string{"private"}) -} - -func (s *S) TestPutReaderHeader(c *C) { - testServer.Response(200, nil, "") - - b := s.s3.Bucket("bucket") - buf := bytes.NewBufferString("content") - err := b.PutReaderHeader( - "name", - buf, - int64(buf.Len()), - map[string][]string{"Content-Type": {"content-type"}}, - s3.Private, - ) - c.Assert(err, IsNil) - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "PUT") - c.Assert(req.URL.Path, Equals, "/bucket/name") - c.Assert(req.Header["Date"], Not(DeepEquals), []string{""}) - c.Assert(req.Header["Content-Type"], DeepEquals, []string{"content-type"}) - c.Assert(req.Header["Content-Length"], DeepEquals, []string{"7"}) - //c.Assert(req.Header["Content-MD5"], Equals, "...") - c.Assert(req.Header["X-Amz-Acl"], DeepEquals, []string{"private"}) -} - -// DelObject docs: http://goo.gl/APeTt - -func (s *S) TestDelObject(c *C) { - testServer.Response(200, nil, "") - - b := s.s3.Bucket("bucket") - err := b.Del("name") - c.Assert(err, IsNil) - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "DELETE") - c.Assert(req.URL.Path, Equals, "/bucket/name") - c.Assert(req.Header["Date"], Not(Equals), "") -} - -func (s *S) TestDelMultiObjects(c *C) { - testServer.Response(200, nil, "") - - b := s.s3.Bucket("bucket") - objects := []s3.Object{s3.Object{Key: "test"}} - err := b.DelMulti(s3.Delete{ - Quiet: false, - Objects: objects, - }) - c.Assert(err, IsNil) - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "POST") - c.Assert(req.URL.RawQuery, Equals, "delete=") - c.Assert(req.Header["Date"], Not(Equals), "") - c.Assert(req.Header["Content-MD5"], Not(Equals), "") - c.Assert(req.Header["Content-Type"], Not(Equals), "") - c.Assert(req.ContentLength, Not(Equals), "") -} - -// Bucket List Objects docs: http://goo.gl/YjQTc - -func (s *S) TestList(c *C) { - testServer.Response(200, nil, GetListResultDump1) - - b := s.s3.Bucket("quotes") - - data, err := b.List("N", "", "", 0) - c.Assert(err, IsNil) - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/quotes/") - c.Assert(req.Header["Date"], Not(Equals), "") - c.Assert(req.Form["prefix"], DeepEquals, []string{"N"}) - c.Assert(req.Form["delimiter"], DeepEquals, []string{""}) - c.Assert(req.Form["marker"], DeepEquals, []string{""}) - c.Assert(req.Form["max-keys"], DeepEquals, []string(nil)) - - c.Assert(data.Name, Equals, "quotes") - c.Assert(data.Prefix, Equals, "N") - c.Assert(data.IsTruncated, Equals, false) - c.Assert(len(data.Contents), Equals, 2) - - c.Assert(data.Contents[0].Key, Equals, "Nelson") - c.Assert(data.Contents[0].LastModified, Equals, "2006-01-01T12:00:00.000Z") - c.Assert(data.Contents[0].ETag, Equals, `"828ef3fdfa96f00ad9f27c383fc9ac7f"`) - c.Assert(data.Contents[0].Size, Equals, int64(5)) - c.Assert(data.Contents[0].StorageClass, Equals, "STANDARD") - c.Assert(data.Contents[0].Owner.ID, Equals, "bcaf161ca5fb16fd081034f") - c.Assert(data.Contents[0].Owner.DisplayName, Equals, "webfile") - - c.Assert(data.Contents[1].Key, Equals, "Neo") - c.Assert(data.Contents[1].LastModified, Equals, "2006-01-01T12:00:00.000Z") - c.Assert(data.Contents[1].ETag, Equals, `"828ef3fdfa96f00ad9f27c383fc9ac7f"`) - c.Assert(data.Contents[1].Size, Equals, int64(4)) - c.Assert(data.Contents[1].StorageClass, Equals, "STANDARD") - c.Assert(data.Contents[1].Owner.ID, Equals, "bcaf1ffd86a5fb16fd081034f") - c.Assert(data.Contents[1].Owner.DisplayName, Equals, "webfile") -} - -func (s *S) TestListWithDelimiter(c *C) { - testServer.Response(200, nil, GetListResultDump2) - - b := s.s3.Bucket("quotes") - - data, err := b.List("photos/2006/", "/", "some-marker", 1000) - c.Assert(err, IsNil) - - req := testServer.WaitRequest() - c.Assert(req.Method, Equals, "GET") - c.Assert(req.URL.Path, Equals, "/quotes/") - c.Assert(req.Header["Date"], Not(Equals), "") - c.Assert(req.Form["prefix"], DeepEquals, []string{"photos/2006/"}) - c.Assert(req.Form["delimiter"], DeepEquals, []string{"/"}) - c.Assert(req.Form["marker"], DeepEquals, []string{"some-marker"}) - c.Assert(req.Form["max-keys"], DeepEquals, []string{"1000"}) - - c.Assert(data.Name, Equals, "example-bucket") - c.Assert(data.Prefix, Equals, "photos/2006/") - c.Assert(data.Delimiter, Equals, "/") - c.Assert(data.Marker, Equals, "some-marker") - c.Assert(data.IsTruncated, Equals, false) - c.Assert(len(data.Contents), Equals, 0) - c.Assert(data.CommonPrefixes, DeepEquals, []string{"photos/2006/feb/", "photos/2006/jan/"}) -} - -func (s *S) TestExists(c *C) { - testServer.Response(200, nil, "") - - b := s.s3.Bucket("bucket") - result, err := b.Exists("name") - - req := testServer.WaitRequest() - - c.Assert(req.Method, Equals, "HEAD") - - c.Assert(err, IsNil) - c.Assert(result, Equals, true) -} - -func (s *S) TestExistsNotFound404(c *C) { - testServer.Response(404, nil, "") - - b := s.s3.Bucket("bucket") - result, err := b.Exists("name") - - req := testServer.WaitRequest() - - c.Assert(req.Method, Equals, "HEAD") - - c.Assert(err, IsNil) - c.Assert(result, Equals, false) -} - -func (s *S) TestExistsNotFound403(c *C) { - testServer.Response(403, nil, "") - - b := s.s3.Bucket("bucket") - result, err := b.Exists("name") - - req := testServer.WaitRequest() - - c.Assert(req.Method, Equals, "HEAD") - - c.Assert(err, IsNil) - c.Assert(result, Equals, false) -} diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3i_test.go b/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3i_test.go deleted file mode 100644 index 1b898efc4..000000000 --- a/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3i_test.go +++ /dev/null @@ -1,590 +0,0 @@ -package s3_test - -import ( - "bytes" - "crypto/md5" - "fmt" - "io/ioutil" - "net" - "net/http" - "sort" - "strings" - "time" - - "github.com/goamz/goamz/aws" - "github.com/goamz/goamz/s3" - "github.com/goamz/goamz/testutil" - . "gopkg.in/check.v1" -) - -// AmazonServer represents an Amazon S3 server. -type AmazonServer struct { - auth aws.Auth -} - -func (s *AmazonServer) SetUp(c *C) { - auth, err := aws.EnvAuth() - if err != nil { - c.Fatal(err.Error()) - } - s.auth = auth -} - -var _ = Suite(&AmazonClientSuite{Region: aws.USEast}) -var _ = Suite(&AmazonClientSuite{Region: aws.EUWest}) -var _ = Suite(&AmazonDomainClientSuite{Region: aws.USEast}) - -// AmazonClientSuite tests the client against a live S3 server. -type AmazonClientSuite struct { - aws.Region - srv AmazonServer - ClientTests -} - -func (s *AmazonClientSuite) SetUpSuite(c *C) { - if !testutil.Amazon { - c.Skip("live tests against AWS disabled (no -amazon)") - } - s.srv.SetUp(c) - s.s3 = s3.New(s.srv.auth, s.Region) - // In case tests were interrupted in the middle before. - s.ClientTests.Cleanup() -} - -func (s *AmazonClientSuite) TearDownTest(c *C) { - s.ClientTests.Cleanup() -} - -// AmazonDomainClientSuite tests the client against a live S3 -// server using bucket names in the endpoint domain name rather -// than the request path. -type AmazonDomainClientSuite struct { - aws.Region - srv AmazonServer - ClientTests -} - -func (s *AmazonDomainClientSuite) SetUpSuite(c *C) { - if !testutil.Amazon { - c.Skip("live tests against AWS disabled (no -amazon)") - } - s.srv.SetUp(c) - region := s.Region - region.S3BucketEndpoint = "https://${bucket}.s3.amazonaws.com" - s.s3 = s3.New(s.srv.auth, region) - s.ClientTests.Cleanup() -} - -func (s *AmazonDomainClientSuite) TearDownTest(c *C) { - s.ClientTests.Cleanup() -} - -// ClientTests defines integration tests designed to test the client. -// It is not used as a test suite in itself, but embedded within -// another type. -type ClientTests struct { - s3 *s3.S3 - authIsBroken bool -} - -func (s *ClientTests) Cleanup() { - killBucket(testBucket(s.s3)) -} - -func testBucket(s *s3.S3) *s3.Bucket { - // Watch out! If this function is corrupted and made to match with something - // people own, killBucket will happily remove *everything* inside the bucket. - key := s.Auth.AccessKey - if len(key) >= 8 { - key = s.Auth.AccessKey[:8] - } - return s.Bucket(fmt.Sprintf("goamz-%s-%s", s.Region.Name, key)) -} - -var attempts = aws.AttemptStrategy{ - Min: 5, - Total: 20 * time.Second, - Delay: 100 * time.Millisecond, -} - -func killBucket(b *s3.Bucket) { - var err error - for attempt := attempts.Start(); attempt.Next(); { - err = b.DelBucket() - if err == nil { - return - } - if _, ok := err.(*net.DNSError); ok { - return - } - e, ok := err.(*s3.Error) - if ok && e.Code == "NoSuchBucket" { - return - } - if ok && e.Code == "BucketNotEmpty" { - // Errors are ignored here. Just retry. - resp, err := b.List("", "", "", 1000) - if err == nil { - for _, key := range resp.Contents { - _ = b.Del(key.Key) - } - } - multis, _, _ := b.ListMulti("", "") - for _, m := range multis { - _ = m.Abort() - } - } - } - message := "cannot delete test bucket" - if err != nil { - message += ": " + err.Error() - } - panic(message) -} - -func get(url string) ([]byte, error) { - for attempt := attempts.Start(); attempt.Next(); { - resp, err := http.Get(url) - if err != nil { - if attempt.HasNext() { - continue - } - return nil, err - } - data, err := ioutil.ReadAll(resp.Body) - resp.Body.Close() - if err != nil { - if attempt.HasNext() { - continue - } - return nil, err - } - return data, err - } - panic("unreachable") -} - -func (s *ClientTests) TestBasicFunctionality(c *C) { - b := testBucket(s.s3) - err := b.PutBucket(s3.PublicRead) - c.Assert(err, IsNil) - - err = b.Put("name", []byte("yo!"), "text/plain", s3.PublicRead, s3.Options{}) - c.Assert(err, IsNil) - defer b.Del("name") - - data, err := b.Get("name") - c.Assert(err, IsNil) - c.Assert(string(data), Equals, "yo!") - - data, err = get(b.URL("name")) - c.Assert(err, IsNil) - c.Assert(string(data), Equals, "yo!") - - buf := bytes.NewBufferString("hey!") - err = b.PutReader("name2", buf, int64(buf.Len()), "text/plain", s3.Private, s3.Options{}) - c.Assert(err, IsNil) - defer b.Del("name2") - - rc, err := b.GetReader("name2") - c.Assert(err, IsNil) - data, err = ioutil.ReadAll(rc) - c.Check(err, IsNil) - c.Check(string(data), Equals, "hey!") - rc.Close() - - data, err = get(b.SignedURL("name2", time.Now().Add(time.Hour))) - c.Assert(err, IsNil) - c.Assert(string(data), Equals, "hey!") - - if !s.authIsBroken { - data, err = get(b.SignedURL("name2", time.Now().Add(-time.Hour))) - c.Assert(err, IsNil) - c.Assert(string(data), Matches, "(?s).*AccessDenied.*") - } - - err = b.DelBucket() - c.Assert(err, NotNil) - - s3err, ok := err.(*s3.Error) - c.Assert(ok, Equals, true) - c.Assert(s3err.Code, Equals, "BucketNotEmpty") - c.Assert(s3err.BucketName, Equals, b.Name) - c.Assert(s3err.Message, Equals, "The bucket you tried to delete is not empty") - - err = b.Del("name") - c.Assert(err, IsNil) - err = b.Del("name2") - c.Assert(err, IsNil) - - err = b.DelBucket() - c.Assert(err, IsNil) -} - -func (s *ClientTests) TestGetNotFound(c *C) { - b := s.s3.Bucket("goamz-" + s.s3.Auth.AccessKey) - data, err := b.Get("non-existent") - - s3err, _ := err.(*s3.Error) - c.Assert(s3err, NotNil) - c.Assert(s3err.StatusCode, Equals, 404) - c.Assert(s3err.Code, Equals, "NoSuchBucket") - c.Assert(s3err.Message, Equals, "The specified bucket does not exist") - c.Assert(data, IsNil) -} - -// Communicate with all endpoints to see if they are alive. -func (s *ClientTests) TestRegions(c *C) { - errs := make(chan error, len(aws.Regions)) - for _, region := range aws.Regions { - go func(r aws.Region) { - s := s3.New(s.s3.Auth, r) - b := s.Bucket("goamz-" + s.Auth.AccessKey) - _, err := b.Get("non-existent") - errs <- err - }(region) - } - for _ = range aws.Regions { - err := <-errs - if err != nil { - s3_err, ok := err.(*s3.Error) - if ok { - c.Check(s3_err.Code, Matches, "NoSuchBucket") - } else if _, ok = err.(*net.DNSError); ok { - // Okay as well. - } else { - c.Errorf("Non-S3 error: %s", err) - } - } else { - c.Errorf("Test should have errored but it seems to have succeeded") - } - } -} - -var objectNames = []string{ - "index.html", - "index2.html", - "photos/2006/February/sample2.jpg", - "photos/2006/February/sample3.jpg", - "photos/2006/February/sample4.jpg", - "photos/2006/January/sample.jpg", - "test/bar", - "test/foo", -} - -func keys(names ...string) []s3.Key { - ks := make([]s3.Key, len(names)) - for i, name := range names { - ks[i].Key = name - } - return ks -} - -// As the ListResp specifies all the parameters to the -// request too, we use it to specify request parameters -// and expected results. The Contents field is -// used only for the key names inside it. -var listTests = []s3.ListResp{ - // normal list. - { - Contents: keys(objectNames...), - }, { - Marker: objectNames[0], - Contents: keys(objectNames[1:]...), - }, { - Marker: objectNames[0] + "a", - Contents: keys(objectNames[1:]...), - }, { - Marker: "z", - }, - - // limited results. - { - MaxKeys: 2, - Contents: keys(objectNames[0:2]...), - IsTruncated: true, - }, { - MaxKeys: 2, - Marker: objectNames[0], - Contents: keys(objectNames[1:3]...), - IsTruncated: true, - }, { - MaxKeys: 2, - Marker: objectNames[len(objectNames)-2], - Contents: keys(objectNames[len(objectNames)-1:]...), - }, - - // with delimiter - { - Delimiter: "/", - CommonPrefixes: []string{"photos/", "test/"}, - Contents: keys("index.html", "index2.html"), - }, { - Delimiter: "/", - Prefix: "photos/2006/", - CommonPrefixes: []string{"photos/2006/February/", "photos/2006/January/"}, - }, { - Delimiter: "/", - Prefix: "t", - CommonPrefixes: []string{"test/"}, - }, { - Delimiter: "/", - MaxKeys: 1, - Contents: keys("index.html"), - IsTruncated: true, - }, { - Delimiter: "/", - MaxKeys: 1, - Marker: "index2.html", - CommonPrefixes: []string{"photos/"}, - IsTruncated: true, - }, { - Delimiter: "/", - MaxKeys: 1, - Marker: "photos/", - CommonPrefixes: []string{"test/"}, - IsTruncated: false, - }, { - Delimiter: "Feb", - CommonPrefixes: []string{"photos/2006/Feb"}, - Contents: keys("index.html", "index2.html", "photos/2006/January/sample.jpg", "test/bar", "test/foo"), - }, -} - -func (s *ClientTests) TestDoublePutBucket(c *C) { - b := testBucket(s.s3) - err := b.PutBucket(s3.PublicRead) - c.Assert(err, IsNil) - - err = b.PutBucket(s3.PublicRead) - if err != nil { - c.Assert(err, FitsTypeOf, new(s3.Error)) - c.Assert(err.(*s3.Error).Code, Equals, "BucketAlreadyOwnedByYou") - } -} - -func (s *ClientTests) TestBucketList(c *C) { - b := testBucket(s.s3) - err := b.PutBucket(s3.Private) - c.Assert(err, IsNil) - - objData := make(map[string][]byte) - for i, path := range objectNames { - data := []byte(strings.Repeat("a", i)) - err := b.Put(path, data, "text/plain", s3.Private, s3.Options{}) - c.Assert(err, IsNil) - defer b.Del(path) - objData[path] = data - } - - for i, t := range listTests { - c.Logf("test %d", i) - resp, err := b.List(t.Prefix, t.Delimiter, t.Marker, t.MaxKeys) - c.Assert(err, IsNil) - c.Check(resp.Name, Equals, b.Name) - c.Check(resp.Delimiter, Equals, t.Delimiter) - c.Check(resp.IsTruncated, Equals, t.IsTruncated) - c.Check(resp.CommonPrefixes, DeepEquals, t.CommonPrefixes) - checkContents(c, resp.Contents, objData, t.Contents) - } -} - -func etag(data []byte) string { - sum := md5.New() - sum.Write(data) - return fmt.Sprintf(`"%x"`, sum.Sum(nil)) -} - -func checkContents(c *C, contents []s3.Key, data map[string][]byte, expected []s3.Key) { - c.Assert(contents, HasLen, len(expected)) - for i, k := range contents { - c.Check(k.Key, Equals, expected[i].Key) - // TODO mtime - c.Check(k.Size, Equals, int64(len(data[k.Key]))) - c.Check(k.ETag, Equals, etag(data[k.Key])) - } -} - -func (s *ClientTests) TestMultiInitPutList(c *C) { - b := testBucket(s.s3) - err := b.PutBucket(s3.Private) - c.Assert(err, IsNil) - - multi, err := b.InitMulti("multi", "text/plain", s3.Private) - c.Assert(err, IsNil) - c.Assert(multi.UploadId, Matches, ".+") - defer multi.Abort() - - var sent []s3.Part - - for i := 0; i < 5; i++ { - p, err := multi.PutPart(i+1, strings.NewReader(fmt.Sprintf("<part %d>", i+1))) - c.Assert(err, IsNil) - c.Assert(p.N, Equals, i+1) - c.Assert(p.Size, Equals, int64(8)) - c.Assert(p.ETag, Matches, ".+") - sent = append(sent, p) - } - - s3.SetListPartsMax(2) - - parts, err := multi.ListParts() - c.Assert(err, IsNil) - c.Assert(parts, HasLen, len(sent)) - for i := range parts { - c.Assert(parts[i].N, Equals, sent[i].N) - c.Assert(parts[i].Size, Equals, sent[i].Size) - c.Assert(parts[i].ETag, Equals, sent[i].ETag) - } - - err = multi.Complete(parts) - s3err, failed := err.(*s3.Error) - c.Assert(failed, Equals, true) - c.Assert(s3err.Code, Equals, "EntityTooSmall") - - err = multi.Abort() - c.Assert(err, IsNil) - _, err = multi.ListParts() - s3err, ok := err.(*s3.Error) - c.Assert(ok, Equals, true) - c.Assert(s3err.Code, Equals, "NoSuchUpload") -} - -// This may take a minute or more due to the minimum size accepted S3 -// on multipart upload parts. -func (s *ClientTests) TestMultiComplete(c *C) { - b := testBucket(s.s3) - err := b.PutBucket(s3.Private) - c.Assert(err, IsNil) - - multi, err := b.InitMulti("multi", "text/plain", s3.Private) - c.Assert(err, IsNil) - c.Assert(multi.UploadId, Matches, ".+") - defer multi.Abort() - - // Minimum size S3 accepts for all but the last part is 5MB. - data1 := make([]byte, 5*1024*1024) - data2 := []byte("<part 2>") - - part1, err := multi.PutPart(1, bytes.NewReader(data1)) - c.Assert(err, IsNil) - part2, err := multi.PutPart(2, bytes.NewReader(data2)) - c.Assert(err, IsNil) - - // Purposefully reversed. The order requirement must be handled. - err = multi.Complete([]s3.Part{part2, part1}) - c.Assert(err, IsNil) - - data, err := b.Get("multi") - c.Assert(err, IsNil) - - c.Assert(len(data), Equals, len(data1)+len(data2)) - for i := range data1 { - if data[i] != data1[i] { - c.Fatalf("uploaded object at byte %d: want %d, got %d", data1[i], data[i]) - } - } - c.Assert(string(data[len(data1):]), Equals, string(data2)) -} - -type multiList []*s3.Multi - -func (l multiList) Len() int { return len(l) } -func (l multiList) Less(i, j int) bool { return l[i].Key < l[j].Key } -func (l multiList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } - -func (s *ClientTests) TestListMulti(c *C) { - b := testBucket(s.s3) - err := b.PutBucket(s3.Private) - c.Assert(err, IsNil) - - // Ensure an empty state before testing its behavior. - multis, _, err := b.ListMulti("", "") - for _, m := range multis { - err := m.Abort() - c.Assert(err, IsNil) - } - - keys := []string{ - "a/multi2", - "a/multi3", - "b/multi4", - "multi1", - } - for _, key := range keys { - m, err := b.InitMulti(key, "", s3.Private) - c.Assert(err, IsNil) - defer m.Abort() - } - - // Amazon's implementation of the multiple-request listing for - // multipart uploads in progress seems broken in multiple ways. - // (next tokens are not provided, etc). - //s3.SetListMultiMax(2) - - multis, prefixes, err := b.ListMulti("", "") - c.Assert(err, IsNil) - for attempt := attempts.Start(); attempt.Next() && len(multis) < len(keys); { - multis, prefixes, err = b.ListMulti("", "") - c.Assert(err, IsNil) - } - sort.Sort(multiList(multis)) - c.Assert(prefixes, IsNil) - var gotKeys []string - for _, m := range multis { - gotKeys = append(gotKeys, m.Key) - } - c.Assert(gotKeys, DeepEquals, keys) - for _, m := range multis { - c.Assert(m.Bucket, Equals, b) - c.Assert(m.UploadId, Matches, ".+") - } - - multis, prefixes, err = b.ListMulti("", "/") - for attempt := attempts.Start(); attempt.Next() && len(prefixes) < 2; { - multis, prefixes, err = b.ListMulti("", "") - c.Assert(err, IsNil) - } - c.Assert(err, IsNil) - c.Assert(prefixes, DeepEquals, []string{"a/", "b/"}) - c.Assert(multis, HasLen, 1) - c.Assert(multis[0].Bucket, Equals, b) - c.Assert(multis[0].Key, Equals, "multi1") - c.Assert(multis[0].UploadId, Matches, ".+") - - for attempt := attempts.Start(); attempt.Next() && len(multis) < 2; { - multis, prefixes, err = b.ListMulti("", "") - c.Assert(err, IsNil) - } - multis, prefixes, err = b.ListMulti("a/", "/") - c.Assert(err, IsNil) - c.Assert(prefixes, IsNil) - c.Assert(multis, HasLen, 2) - c.Assert(multis[0].Bucket, Equals, b) - c.Assert(multis[0].Key, Equals, "a/multi2") - c.Assert(multis[0].UploadId, Matches, ".+") - c.Assert(multis[1].Bucket, Equals, b) - c.Assert(multis[1].Key, Equals, "a/multi3") - c.Assert(multis[1].UploadId, Matches, ".+") -} - -func (s *ClientTests) TestMultiPutAllZeroLength(c *C) { - b := testBucket(s.s3) - err := b.PutBucket(s3.Private) - c.Assert(err, IsNil) - - multi, err := b.InitMulti("multi", "text/plain", s3.Private) - c.Assert(err, IsNil) - defer multi.Abort() - - // This tests an edge case. Amazon requires at least one - // part for multiprat uploads to work, even the part is empty. - parts, err := multi.PutAll(strings.NewReader(""), 5*1024*1024) - c.Assert(err, IsNil) - c.Assert(parts, HasLen, 1) - c.Assert(parts[0].Size, Equals, int64(0)) - c.Assert(parts[0].ETag, Equals, `"d41d8cd98f00b204e9800998ecf8427e"`) - - err = multi.Complete(parts) - c.Assert(err, IsNil) -} diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3t_test.go b/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3t_test.go deleted file mode 100644 index e98c50b29..000000000 --- a/Godeps/_workspace/src/github.com/goamz/goamz/s3/s3t_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package s3_test - -import ( - "github.com/goamz/goamz/aws" - "github.com/goamz/goamz/s3" - "github.com/goamz/goamz/s3/s3test" - . "gopkg.in/check.v1" -) - -type LocalServer struct { - auth aws.Auth - region aws.Region - srv *s3test.Server - config *s3test.Config -} - -func (s *LocalServer) SetUp(c *C) { - srv, err := s3test.NewServer(s.config) - c.Assert(err, IsNil) - c.Assert(srv, NotNil) - - s.srv = srv - s.region = aws.Region{ - Name: "faux-region-1", - S3Endpoint: srv.URL(), - S3LocationConstraint: true, // s3test server requires a LocationConstraint - } -} - -// LocalServerSuite defines tests that will run -// against the local s3test server. It includes -// selected tests from ClientTests; -// when the s3test functionality is sufficient, it should -// include all of them, and ClientTests can be simply embedded. -type LocalServerSuite struct { - srv LocalServer - clientTests ClientTests -} - -var ( - // run tests twice, once in us-east-1 mode, once not. - _ = Suite(&LocalServerSuite{}) - _ = Suite(&LocalServerSuite{ - srv: LocalServer{ - config: &s3test.Config{ - Send409Conflict: true, - }, - }, - }) -) - -func (s *LocalServerSuite) SetUpSuite(c *C) { - s.srv.SetUp(c) - s.clientTests.s3 = s3.New(s.srv.auth, s.srv.region) - - // TODO Sadly the fake server ignores auth completely right now. :-( - s.clientTests.authIsBroken = true - s.clientTests.Cleanup() -} - -func (s *LocalServerSuite) TearDownTest(c *C) { - s.clientTests.Cleanup() -} - -func (s *LocalServerSuite) TestBasicFunctionality(c *C) { - s.clientTests.TestBasicFunctionality(c) -} - -func (s *LocalServerSuite) TestGetNotFound(c *C) { - s.clientTests.TestGetNotFound(c) -} - -func (s *LocalServerSuite) TestBucketList(c *C) { - s.clientTests.TestBucketList(c) -} - -func (s *LocalServerSuite) TestDoublePutBucket(c *C) { - s.clientTests.TestDoublePutBucket(c) -} diff --git a/Godeps/_workspace/src/github.com/goamz/goamz/s3/sign_test.go b/Godeps/_workspace/src/github.com/goamz/goamz/s3/sign_test.go deleted file mode 100644 index 112e1ca3e..000000000 --- a/Godeps/_workspace/src/github.com/goamz/goamz/s3/sign_test.go +++ /dev/null @@ -1,132 +0,0 @@ -package s3_test - -import ( - "github.com/goamz/goamz/aws" - "github.com/goamz/goamz/s3" - . "gopkg.in/check.v1" -) - -// S3 ReST authentication docs: http://goo.gl/G1LrK - -var testAuth = aws.Auth{AccessKey: "0PN5J17HBGZHT7JJ3X82", SecretKey: "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o"} - -func (s *S) TestSignExampleObjectGet(c *C) { - method := "GET" - path := "/johnsmith/photos/puppy.jpg" - headers := map[string][]string{ - "Host": {"johnsmith.s3.amazonaws.com"}, - "Date": {"Tue, 27 Mar 2007 19:36:42 +0000"}, - } - s3.Sign(testAuth, method, path, nil, headers) - expected := "AWS 0PN5J17HBGZHT7JJ3X82:xXjDGYUmKxnwqr5KXNPGldn5LbA=" - c.Assert(headers["Authorization"], DeepEquals, []string{expected}) -} - -func (s *S) TestSignExampleObjectPut(c *C) { - method := "PUT" - path := "/johnsmith/photos/puppy.jpg" - headers := map[string][]string{ - "Host": {"johnsmith.s3.amazonaws.com"}, - "Date": {"Tue, 27 Mar 2007 21:15:45 +0000"}, - "Content-Type": {"image/jpeg"}, - "Content-Length": {"94328"}, - } - s3.Sign(testAuth, method, path, nil, headers) - expected := "AWS 0PN5J17HBGZHT7JJ3X82:hcicpDDvL9SsO6AkvxqmIWkmOuQ=" - c.Assert(headers["Authorization"], DeepEquals, []string{expected}) -} - -func (s *S) TestSignExampleList(c *C) { - method := "GET" - path := "/johnsmith/" - params := map[string][]string{ - "prefix": {"photos"}, - "max-keys": {"50"}, - "marker": {"puppy"}, - } - headers := map[string][]string{ - "Host": {"johnsmith.s3.amazonaws.com"}, - "Date": {"Tue, 27 Mar 2007 19:42:41 +0000"}, - "User-Agent": {"Mozilla/5.0"}, - } - s3.Sign(testAuth, method, path, params, headers) - expected := "AWS 0PN5J17HBGZHT7JJ3X82:jsRt/rhG+Vtp88HrYL706QhE4w4=" - c.Assert(headers["Authorization"], DeepEquals, []string{expected}) -} - -func (s *S) TestSignExampleFetch(c *C) { - method := "GET" - path := "/johnsmith/" - params := map[string][]string{ - "acl": {""}, - } - headers := map[string][]string{ - "Host": {"johnsmith.s3.amazonaws.com"}, - "Date": {"Tue, 27 Mar 2007 19:44:46 +0000"}, - } - s3.Sign(testAuth, method, path, params, headers) - expected := "AWS 0PN5J17HBGZHT7JJ3X82:thdUi9VAkzhkniLj96JIrOPGi0g=" - c.Assert(headers["Authorization"], DeepEquals, []string{expected}) -} - -func (s *S) TestSignExampleDelete(c *C) { - method := "DELETE" - path := "/johnsmith/photos/puppy.jpg" - params := map[string][]string{} - headers := map[string][]string{ - "Host": {"s3.amazonaws.com"}, - "Date": {"Tue, 27 Mar 2007 21:20:27 +0000"}, - "User-Agent": {"dotnet"}, - "x-amz-date": {"Tue, 27 Mar 2007 21:20:26 +0000"}, - } - s3.Sign(testAuth, method, path, params, headers) - expected := "AWS 0PN5J17HBGZHT7JJ3X82:k3nL7gH3+PadhTEVn5Ip83xlYzk=" - c.Assert(headers["Authorization"], DeepEquals, []string{expected}) -} - -func (s *S) TestSignExampleUpload(c *C) { - method := "PUT" - path := "/static.johnsmith.net/db-backup.dat.gz" - params := map[string][]string{} - headers := map[string][]string{ - "Host": {"static.johnsmith.net:8080"}, - "Date": {"Tue, 27 Mar 2007 21:06:08 +0000"}, - "User-Agent": {"curl/7.15.5"}, - "x-amz-acl": {"public-read"}, - "content-type": {"application/x-download"}, - "Content-MD5": {"4gJE4saaMU4BqNR0kLY+lw=="}, - "X-Amz-Meta-ReviewedBy": {"joe@johnsmith.net,jane@johnsmith.net"}, - "X-Amz-Meta-FileChecksum": {"0x02661779"}, - "X-Amz-Meta-ChecksumAlgorithm": {"crc32"}, - "Content-Disposition": {"attachment; filename=database.dat"}, - "Content-Encoding": {"gzip"}, - "Content-Length": {"5913339"}, - } - s3.Sign(testAuth, method, path, params, headers) - expected := "AWS 0PN5J17HBGZHT7JJ3X82:C0FlOtU8Ylb9KDTpZqYkZPX91iI=" - c.Assert(headers["Authorization"], DeepEquals, []string{expected}) -} - -func (s *S) TestSignExampleListAllMyBuckets(c *C) { - method := "GET" - path := "/" - headers := map[string][]string{ - "Host": {"s3.amazonaws.com"}, - "Date": {"Wed, 28 Mar 2007 01:29:59 +0000"}, - } - s3.Sign(testAuth, method, path, nil, headers) - expected := "AWS 0PN5J17HBGZHT7JJ3X82:Db+gepJSUbZKwpx1FR0DLtEYoZA=" - c.Assert(headers["Authorization"], DeepEquals, []string{expected}) -} - -func (s *S) TestSignExampleUnicodeKeys(c *C) { - method := "GET" - path := "/dictionary/fran%C3%A7ais/pr%c3%a9f%c3%a8re" - headers := map[string][]string{ - "Host": {"s3.amazonaws.com"}, - "Date": {"Wed, 28 Mar 2007 01:49:49 +0000"}, - } - s3.Sign(testAuth, method, path, nil, headers) - expected := "AWS 0PN5J17HBGZHT7JJ3X82:dxhSBHoI6eVSPcXJqEghlUzZMnY=" - c.Assert(headers["Authorization"], DeepEquals, []string{expected}) -} |