Codebase list golang-github-ncw-swift / 63e9a60
New upstream snapshot. Debian Janitor 2 years ago
17 changed file(s) with 808 addition(s) and 637 deletion(s). Raw diff Collapse all Expand all
00 language: go
11 sudo: false
22
3 arch:
4 - amd64
5 - ppc64le
6
7 go_import_path: github.com/ncw/swift
8
39 go:
4 - 1.2.x
5 - 1.3.x
6 - 1.4.x
7 - 1.5.x
8 - 1.6.x
9 - 1.7.x
10 - 1.8.x
11 - 1.9.x
12 - 1.10.x
13 - 1.11.x
14 - 1.12.x
1510 - 1.13.x
1611 - 1.14.x
12 - 1.15.x
1713 - master
1814
1915 matrix:
2016 include:
21 - go: 1.14.x
17 - go: 1.15.x
2218 env: TEST_REAL_SERVER=rackspace
23 - go: 1.14.x
19 - go: 1.15.x
20 env: TEST_REAL_SERVER=memset
21 - go: 1.15.x
22 arch: ppc64le
23 env: TEST_REAL_SERVER=rackspace
24 - go: 1.15.x
25 arch: ppc64le
2426 env: TEST_REAL_SERVER=memset
2527 allow_failures:
26 - go: 1.14.x
28 - go: 1.15.x
2729 env: TEST_REAL_SERVER=rackspace
28 - go: 1.14.x
30 - go: 1.15.x
31 env: TEST_REAL_SERVER=memset
32 - go: 1.15.x
33 arch: ppc64le
34 env: TEST_REAL_SERVER=rackspace
35 - go: 1.15.x
36 arch: ppc64le
2937 env: TEST_REAL_SERVER=memset
3038 install: go test -i ./...
3139 script:
00 Swift
11 =====
22
3 This package provides an easy to use library for interfacing with
4 Swift / Openstack Object Storage / Rackspace cloud files from the Go
5 Language
3 This package provides an easy to use library for interfacing with Swift / Openstack Object Storage / Rackspace cloud
4 files from the Go Language
65
76 See here for package docs
87
9 http://godoc.org/github.com/ncw/swift
8 http://godoc.org/github.com/ncw/swift/v2
109
11 [![Build Status](https://api.travis-ci.org/ncw/swift.svg?branch=master)](https://travis-ci.org/ncw/swift) [![GoDoc](https://godoc.org/github.com/ncw/swift?status.svg)](https://godoc.org/github.com/ncw/swift)
10 [![Build Status](https://api.travis-ci.org/ncw/swift.svg?branch=master)](https://travis-ci.org/ncw/swift) [![GoDoc](https://godoc.org/github.com/ncw/swift/v2?status.svg)](https://godoc.org/github.com/ncw/swift/v2)
1211
1312 Install
1413 -------
1514
1615 Use go to install the library
1716
18 go get github.com/ncw/swift
17 go get github.com/ncw/swift/v2
1918
2019 Usage
2120 -----
2221
2322 See here for full package docs
2423
25 - http://godoc.org/github.com/ncw/swift
24 - http://godoc.org/github.com/ncw/swift/v2
2625
2726 Here is a short example from the docs
27
2828 ```go
29 import "github.com/ncw/swift"
29 import "github.com/ncw/swift/v2"
3030
3131 // Create a connection
3232 c := swift.Connection{
33 UserName: "user",
34 ApiKey: "key",
35 AuthUrl: "auth_url",
36 Domain: "domain", // Name of the domain (v3 auth only)
37 Tenant: "tenant", // Name of the tenant (v2 auth only)
33 UserName: "user",
34 ApiKey: "key",
35 AuthUrl: "auth_url",
36 Domain: "domain", // Name of the domain (v3 auth only)
37 Tenant: "tenant", // Name of the tenant (v2 auth only)
3838 }
3939 // Authenticate
4040 err := c.Authenticate()
4141 if err != nil {
42 panic(err)
42 panic(err)
4343 }
4444 // List all the containers
4545 containers, err := c.ContainerNames(nil)
4646 fmt.Println(containers)
4747 // etc...
4848 ```
49
50 Migrating from `v1`
51 -----
52 The library has current major version v2. If you want to migrate from the first version of
53 library `github.com/ncw/swift` you have to explicitly add the `/v2` suffix to the imports.
54
55 Most of the exported functions were added a new `context.Context` parameter in the `v2`, which you will have to provide
56 when migrating.
4957
5058 Additions
5159 ---------
5563 Testing
5664 -------
5765
58 To run the tests you can either use an embedded fake Swift server
59 either use a real Openstack Swift server or a Rackspace Cloud files account.
66 To run the tests you can either use an embedded fake Swift server either use a real Openstack Swift server or a
67 Rackspace Cloud files account.
6068
61 When using a real Swift server, you need to set these environment variables
62 before running the tests
69 When using a real Swift server, you need to set these environment variables before running the tests
6370
6471 export SWIFT_API_USER='user'
6572 export SWIFT_API_KEY='key'
98105 License
99106 -------
100107
101 This is free software under the terms of MIT license (check COPYING file
102 included in this package).
108 This is free software under the terms of MIT license (check COPYING file included in this package).
103109
104110 Contact and support
105111 -------------------
160166 - Brandon WELSCH <dev@brandon-welsch.eu>
161167 - Damien Tournoud <damien@platform.sh>
162168 - Pedro Kiefer <pedro@kiefer.com.br>
169 - Martin Chodur <m.chodur@seznam.cz>
170 - Devendra <devendranath.thadi3@gmail.com>
11
22 import (
33 "bytes"
4 "context"
45 "encoding/json"
56 "net/http"
67 "net/url"
1314 // This encapsulates the different authentication schemes in use
1415 type Authenticator interface {
1516 // Request creates an http.Request for the auth - return nil if not needed
16 Request(*Connection) (*http.Request, error)
17 Request(context.Context, *Connection) (*http.Request, error)
1718 // Response parses the http.Response
18 Response(resp *http.Response) error
19 Response(ctx context.Context, resp *http.Response) error
1920 // The public storage URL - set Internal to true to read
2021 // internal/service net URL
2122 StorageUrl(Internal bool) string
8788 }
8889
8990 // v1 Authentication - make request
90 func (auth *v1Auth) Request(c *Connection) (*http.Request, error) {
91 req, err := http.NewRequest("GET", c.AuthUrl, nil)
91 func (auth *v1Auth) Request(ctx context.Context, c *Connection) (*http.Request, error) {
92 req, err := http.NewRequestWithContext(ctx, "GET", c.AuthUrl, nil)
9293 if err != nil {
9394 return nil, err
9495 }
99100 }
100101
101102 // v1 Authentication - read response
102 func (auth *v1Auth) Response(resp *http.Response) error {
103 func (auth *v1Auth) Response(_ context.Context, resp *http.Response) error {
103104 auth.Headers = resp.Header
104105 return nil
105106 }
140141 }
141142
142143 // v2 Authentication - make request
143 func (auth *v2Auth) Request(c *Connection) (*http.Request, error) {
144 func (auth *v2Auth) Request(ctx context.Context, c *Connection) (*http.Request, error) {
144145 auth.Region = c.Region
145146 // Toggle useApiKey if not first run and not OK yet
146147 if auth.notFirst && !auth.useApiKeyOk {
175176 url += "/"
176177 }
177178 url += "tokens"
178 req, err := http.NewRequest("POST", url, bytes.NewBuffer(body))
179 req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(body))
179180 if err != nil {
180181 return nil, err
181182 }
185186 }
186187
187188 // v2 Authentication - read response
188 func (auth *v2Auth) Response(resp *http.Response) error {
189 func (auth *v2Auth) Response(_ context.Context, resp *http.Response) error {
189190 auth.Auth = new(v2AuthResponse)
190191 err := readJson(resp, auth.Auth)
191192 // If successfully read Auth then no need to toggle useApiKey any more
11
22 import (
33 "bytes"
4 "context"
45 "encoding/json"
56 "fmt"
67 "net/http"
121122 Headers http.Header
122123 }
123124
124 func (auth *v3Auth) Request(c *Connection) (*http.Request, error) {
125 func (auth *v3Auth) Request(ctx context.Context, c *Connection) (*http.Request, error) {
125126 auth.Region = c.Region
126127
127128 var v3i interface{}
241242 url += "/"
242243 }
243244 url += "auth/tokens"
244 req, err := http.NewRequest("POST", url, bytes.NewBuffer(body))
245 req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(body))
245246 if err != nil {
246247 return nil, err
247248 }
250251 return req, nil
251252 }
252253
253 func (auth *v3Auth) Response(resp *http.Response) error {
254 func (auth *v3Auth) Response(_ context.Context, resp *http.Response) error {
254255 auth.Auth = &v3AuthResponse{}
255256 auth.Headers = resp.Header
256257 err := readJson(resp, auth.Auth)
0 golang-github-ncw-swift (2.0.0+git20210122.1.30f52fe-1) UNRELEASED; urgency=low
1
2 * New upstream snapshot.
3
4 -- Debian Janitor <janitor@jelmer.uk> Fri, 23 Jul 2021 14:51:02 -0000
5
06 golang-github-ncw-swift (1.0.52-1) unstable; urgency=medium
17
28 * Team upload.
00 package swift
11
22 import (
3 "context"
34 "os"
45 "strings"
56 )
1314 // returning an object which satisfies io.Writer, io.Seeker, io.Closer
1415 // and io.ReaderFrom. The flags are as passes to the
1516 // largeObjectCreate method.
16 func (c *Connection) DynamicLargeObjectCreateFile(opts *LargeObjectOpts) (LargeObjectFile, error) {
17 lo, err := c.largeObjectCreate(opts)
17 func (c *Connection) DynamicLargeObjectCreateFile(ctx context.Context, opts *LargeObjectOpts) (LargeObjectFile, error) {
18 lo, err := c.largeObjectCreate(ctx, opts)
1819 if err != nil {
1920 return nil, err
2021 }
2728 // DynamicLargeObjectCreate creates or truncates an existing dynamic
2829 // large object returning a writeable object. This sets opts.Flags to
2930 // an appropriate value before calling DynamicLargeObjectCreateFile
30 func (c *Connection) DynamicLargeObjectCreate(opts *LargeObjectOpts) (LargeObjectFile, error) {
31 func (c *Connection) DynamicLargeObjectCreate(ctx context.Context, opts *LargeObjectOpts) (LargeObjectFile, error) {
3132 opts.Flags = os.O_TRUNC | os.O_CREATE
32 return c.DynamicLargeObjectCreateFile(opts)
33 return c.DynamicLargeObjectCreateFile(ctx, opts)
3334 }
3435
3536 // DynamicLargeObjectDelete deletes a dynamic large object and all of its segments.
36 func (c *Connection) DynamicLargeObjectDelete(container string, path string) error {
37 return c.LargeObjectDelete(container, path)
37 func (c *Connection) DynamicLargeObjectDelete(ctx context.Context, container string, path string) error {
38 return c.LargeObjectDelete(ctx, container, path)
3839 }
3940
4041 // DynamicLargeObjectMove moves a dynamic large object from srcContainer, srcObjectName to dstContainer, dstObjectName
41 func (c *Connection) DynamicLargeObjectMove(srcContainer string, srcObjectName string, dstContainer string, dstObjectName string) error {
42 info, headers, err := c.Object(srcContainer, srcObjectName)
42 func (c *Connection) DynamicLargeObjectMove(ctx context.Context, srcContainer string, srcObjectName string, dstContainer string, dstObjectName string) error {
43 info, headers, err := c.Object(ctx, srcContainer, srcObjectName)
4344 if err != nil {
4445 return err
4546 }
4647
4748 segmentContainer, segmentPath := parseFullPath(headers["X-Object-Manifest"])
48 if err := c.createDLOManifest(dstContainer, dstObjectName, segmentContainer+"/"+segmentPath, info.ContentType, sanitizeLargeObjectMoveHeaders(headers)); err != nil {
49 if err := c.createDLOManifest(ctx, dstContainer, dstObjectName, segmentContainer+"/"+segmentPath, info.ContentType, sanitizeLargeObjectMoveHeaders(headers)); err != nil {
4950 return err
5051 }
5152
52 if err := c.ObjectDelete(srcContainer, srcObjectName); err != nil {
53 if err := c.ObjectDelete(ctx, srcContainer, srcObjectName); err != nil {
5354 return err
5455 }
5556
6768 }
6869
6970 // createDLOManifest creates a dynamic large object manifest
70 func (c *Connection) createDLOManifest(container string, objectName string, prefix string, contentType string, headers Headers) error {
71 func (c *Connection) createDLOManifest(ctx context.Context, container string, objectName string, prefix string, contentType string, headers Headers) error {
7172 if headers == nil {
7273 headers = make(Headers)
7374 }
7475 headers["X-Object-Manifest"] = prefix
75 manifest, err := c.ObjectCreate(container, objectName, false, "", contentType, headers)
76 manifest, err := c.ObjectCreate(ctx, container, objectName, false, "", contentType, headers)
7677 if err != nil {
7778 return err
7879 }
8687
8788 // Close satisfies the io.Closer interface
8889 func (file *DynamicLargeObjectCreateFile) Close() error {
89 return file.Flush()
90 return file.CloseWithContext(context.Background())
9091 }
9192
92 func (file *DynamicLargeObjectCreateFile) Flush() error {
93 err := file.conn.createDLOManifest(file.container, file.objectName, file.segmentContainer+"/"+file.prefix, file.contentType, file.headers)
93 func (file *DynamicLargeObjectCreateFile) CloseWithContext(ctx context.Context) error {
94 return file.Flush(ctx)
95 }
96
97 func (file *DynamicLargeObjectCreateFile) Flush(ctx context.Context) error {
98 err := file.conn.createDLOManifest(ctx, file.container, file.objectName, file.segmentContainer+"/"+file.prefix, file.contentType, file.headers)
9499 if err != nil {
95100 return err
96101 }
97 return file.conn.waitForSegmentsToShowUp(file.container, file.objectName, file.Size())
102 return file.conn.waitForSegmentsToShowUp(ctx, file.container, file.objectName, file.Size())
98103 }
99104
100 func (c *Connection) getAllDLOSegments(segmentContainer, segmentPath string) ([]Object, error) {
105 func (c *Connection) getAllDLOSegments(ctx context.Context, segmentContainer, segmentPath string) ([]Object, error) {
101106 //a simple container listing works 99.9% of the time
102 segments, err := c.ObjectsAll(segmentContainer, &ObjectsOpts{Prefix: segmentPath})
107 segments, err := c.ObjectsAll(ctx, segmentContainer, &ObjectsOpts{Prefix: segmentPath})
103108 if err != nil {
104109 return nil, err
105110 }
125130 //guaranteed to return the correct metadata, except for the pathological
126131 //case of an outage of large parts of the Swift cluster or its network,
127132 //since every segment is only written once.)
128 segment, _, err := c.Object(segmentContainer, segmentName)
133 segment, _, err := c.Object(ctx, segmentContainer, segmentName)
129134 switch err {
130135 case nil:
131136 //found new segment -> add it in the correct position and keep
11
22 import (
33 "bytes"
4 "github.com/ncw/swift/swifttest"
4 "context"
5 "github.com/ncw/swift/v2/swifttest"
56 "net/http"
67 "testing"
78 "time"
4647 Domain: "Default",
4748 AuthVersion: 1,
4849 }
49 err = swiftCon.Authenticate()
50 err = swiftCon.Authenticate(context.Background())
5051 return &swiftCon, err
5152 }
5253 func TestCases(t *testing.T) {
6263 }
6364
6465 func createContainers(containers []string, t *testing.T) {
66 ctx := context.Background()
6567 for i := 0; i < len(containers); i++ {
66 err = con.ContainerCreate(containers[i], nil) // Create container
68 err = con.ContainerCreate(ctx, containers[i], nil) // Create container
6769 if err != nil {
6870 t.Errorf("Fail at create container %s", containers[i])
6971 }
7173 }
7274
7375 func createDynamicObject(container, object string, t *testing.T) {
76 ctx := context.Background()
7477 metadata := map[string]string{}
7578 metadata["Custom-Field"] = "SomeValue"
7679 ops := LargeObjectOpts{
8285 SegmentContainer: segmentContainer, // Name of the container to place segments
8386 SegmentPrefix: "sg", // Prefix to use for the segments
8487 }
85 bigfile, err := con.DynamicLargeObjectCreate(&ops)
88 bigfile, err := con.DynamicLargeObjectCreate(ctx, &ops)
8689 if err != nil {
8790 t.Errorf("Fail at dynamic create Large Object")
8891 }
89 bigfile.Write(filecontent)
90 bigfile.Close()
92 bigfile.WriteWithContext(ctx, filecontent)
93 bigfile.CloseWithContext(ctx)
9194 checkObject(container, object, t)
9295 }
9396 func checkObject(container, object string, t *testing.T) {
94 info, header, err := con.Object(container, object)
97 ctx := context.Background()
98 info, header, err := con.Object(ctx, container, object)
9599 if err != nil {
96100 t.Errorf("Fail at get Large Object metadata: %s", err.Error())
97101 }
105109 t.Errorf("Fail: lost custom metadata header")
106110 }
107111
108 content, err := con.ObjectGetBytes(container, object)
112 content, err := con.ObjectGetBytes(ctx, container, object)
109113 if err != nil {
110114 t.Errorf("Fail at read Large Object : %s", err.Error())
111115 }
115119
116120 }
117121 func checkNotExistObject(container, object string, t *testing.T) {
118 _, _, err = con.Object(container, object)
122 _, _, err = con.Object(context.Background(), container, object)
119123 if err == nil || err.Error() != "Object Not Found" {
120124 t.Errorf("Fail at checkNotExistObject object: %s", err)
121125 }
122126 }
123127 func moveDynamicObject(sc, so, dc, do string, t *testing.T) {
124 err = con.DynamicLargeObjectMove(sc, so, dc, do)
128 err = con.DynamicLargeObjectMove(context.Background(), sc, so, dc, do)
125129 if err != nil {
126130 t.Errorf("Fail at dynamic move Large Object: %s", err.Error())
127131 }
129133 checkObject(dc, do, t)
130134 }
131135 func deleteDynamicObject(container, object string, t *testing.T) {
132 err = con.DynamicLargeObjectDelete(container, object)
136 ctx := context.Background()
137 err = con.DynamicLargeObjectDelete(ctx, container, object)
133138 if err != nil {
134139 t.Errorf("Fail at delte dynamic Large Object: %s", err.Error())
135140 }
136141 checkNotExistObject(container, object, t)
137 objs, err := con.ObjectsAll(segmentContainer, nil)
142 objs, err := con.ObjectsAll(ctx, segmentContainer, nil)
138143 if err != nil {
139144 t.Errorf("Fail at check delte dynamic Large Object: %s", err.Error())
140145 }
143148 }
144149 }
145150 func createStaticObject(container, object string, t *testing.T) {
151 ctx := context.Background()
146152 metadata := map[string]string{}
147153 metadata["Custom-Field"] = "SomeValue"
148154 ops := LargeObjectOpts{
154160 SegmentContainer: segmentContainer, // Name of the container to place segments
155161 SegmentPrefix: "sg", // Prefix to use for the segments
156162 }
157 bigfile, err := con.StaticLargeObjectCreate(&ops)
163 bigfile, err := con.StaticLargeObjectCreate(ctx, &ops)
158164 if err != nil {
159165 t.Errorf("Fail at static create Large Object")
160166 }
161 bigfile.Write(filecontent)
162 bigfile.Close()
167 bigfile.WriteWithContext(ctx, filecontent)
168 bigfile.CloseWithContext(ctx)
163169 checkObject(container, object, t)
164170 }
165171 func moveStaticObject(sc, so, dc, do string, t *testing.T) {
166 err = con.StaticLargeObjectMove(sc, so, dc, do)
172 err = con.StaticLargeObjectMove(context.Background(), sc, so, dc, do)
167173 if err != nil {
168174 t.Errorf("Fail at static move Large Object: %s", err.Error())
169175 }
171177 checkObject(dc, do, t)
172178 }
173179 func deleteStaticObject(container, object string, t *testing.T) {
174 err = con.StaticLargeObjectDelete(container, object)
180 ctx := context.Background()
181 err = con.StaticLargeObjectDelete(ctx, container, object)
175182 if err != nil {
176183 t.Errorf("Fail at delte dynamic Large Object: %s", err.Error())
177184 }
178185 checkNotExistObject(container, object, t)
179 objs, err := con.ObjectsAll(segmentContainer, nil)
186 objs, err := con.ObjectsAll(ctx, segmentContainer, nil)
180187 if err != nil {
181188 t.Errorf("Fail at check delte dynamic Large Object: %s", err.Error())
182189 }
33 package swift_test
44
55 import (
6 "context"
67 "fmt"
78
8 "github.com/ncw/swift"
9 "github.com/ncw/swift/v2"
910 )
1011
1112 func ExampleConnection() {
13 ctx := context.Background()
1214 // Create a v1 auth connection
1315 c := &swift.Connection{
1416 // This should be your username
2325 }
2426
2527 // Authenticate
26 err := c.Authenticate()
28 err := c.Authenticate(ctx)
2729 if err != nil {
2830 panic(err)
2931 }
3032 // List all the containers
31 containers, err := c.ContainerNames(nil)
33 containers, err := c.ContainerNames(ctx, nil)
3234 fmt.Println(containers)
3335 // etc...
3436
6062 defer rollback()
6163
6264 objects := make([]string, 0)
63 err := c.ObjectsWalk(container, nil, func(opts *swift.ObjectsOpts) (interface{}, error) {
64 newObjects, err := c.ObjectNames(container, opts)
65 err := c.ObjectsWalk(context.Background(), container, nil, func(ctx context.Context, opts *swift.ObjectsOpts) (interface{}, error) {
66 newObjects, err := c.ObjectNames(ctx, container, opts)
6567 if err == nil {
6668 objects = append(objects, newObjects...)
6769 }
7577 defer rollback()
7678
7779 // Use the helper method to create the current and versions container.
78 if err := c.VersionContainerCreate("cds", "cd-versions"); err != nil {
80 if err := c.VersionContainerCreate(context.Background(), "cds", "cd-versions"); err != nil {
7981 fmt.Print(err.Error())
8082 }
8183 }
8284
8385 func ExampleConnection_VersionEnable() {
86 ctx := context.Background()
8487 c, rollback := makeConnection(nil)
8588 defer rollback()
8689
8790 // Build the containers manually and enable them.
88 if err := c.ContainerCreate("movie-versions", nil); err != nil {
91 if err := c.ContainerCreate(ctx, "movie-versions", nil); err != nil {
8992 fmt.Print(err.Error())
9093 }
91 if err := c.ContainerCreate("movies", nil); err != nil {
94 if err := c.ContainerCreate(ctx, "movies", nil); err != nil {
9295 fmt.Print(err.Error())
9396 }
94 if err := c.VersionEnable("movies", "movie-versions"); err != nil {
97 if err := c.VersionEnable(ctx, "movies", "movie-versions"); err != nil {
9598 fmt.Print(err.Error())
9699 }
97100
104107 defer rollback()
105108
106109 // Disable versioning on a container. Note that this does not delete the versioning container.
107 c.VersionDisable("movies")
110 c.VersionDisable(context.Background(), "movies")
108111 }
0 module github.com/ncw/swift
0 module github.com/ncw/swift/v2
1
2 go 1.15
(New empty file)
22 import (
33 "bufio"
44 "bytes"
5 "context"
56 "crypto/rand"
67 "crypto/sha1"
78 "encoding/hex"
7879 return headers.IsLargeObjectSLO() || headers.IsLargeObjectDLO()
7980 }
8081
81 func (c *Connection) getAllSegments(container string, path string, headers Headers) (string, []Object, error) {
82 func (c *Connection) getAllSegments(ctx context.Context, container string, path string, headers Headers) (string, []Object, error) {
8283 if manifest, isDLO := headers["X-Object-Manifest"]; isDLO {
8384 segmentContainer, segmentPath := parseFullPath(manifest)
84 segments, err := c.getAllDLOSegments(segmentContainer, segmentPath)
85 segments, err := c.getAllDLOSegments(ctx, segmentContainer, segmentPath)
8586 return segmentContainer, segments, err
8687 }
8788 if headers.IsLargeObjectSLO() {
88 return c.getAllSLOSegments(container, path)
89 return c.getAllSLOSegments(ctx, container, path)
8990 }
9091 return "", nil, NotLargeObject
9192 }
107108 }
108109
109110 type LargeObjectFile interface {
111 io.Seeker
110112 io.Writer
111 io.Seeker
112113 io.Closer
114
115 WriteWithContext(ctx context.Context, p []byte) (n int, err error)
116 CloseWithContext(ctx context.Context) error
113117 Size() int64
114 Flush() error
118 Flush(ctx context.Context) error
115119 }
116120
117121 // largeObjectCreate creates a large object at opts.Container, opts.ObjectName.
119123 // opts.Flags can have the following bits set
120124 // os.TRUNC - remove the contents of the large object if it exists
121125 // os.APPEND - write at the end of the large object
122 func (c *Connection) largeObjectCreate(opts *LargeObjectOpts) (*largeObjectCreateFile, error) {
126 func (c *Connection) largeObjectCreate(ctx context.Context, opts *LargeObjectOpts) (*largeObjectCreateFile, error) {
123127 var (
124128 segmentPath string
125129 segmentContainer string
134138 return nil, err
135139 }
136140
137 if info, headers, err := c.Object(opts.Container, opts.ObjectName); err == nil {
141 if info, headers, err := c.Object(ctx, opts.Container, opts.ObjectName); err == nil {
138142 if opts.Flags&os.O_TRUNC != 0 {
139 c.LargeObjectDelete(opts.Container, opts.ObjectName)
143 c.LargeObjectDelete(ctx, opts.Container, opts.ObjectName)
140144 } else {
141145 currentLength = info.Bytes
142146 if headers.IsLargeObject() {
143 segmentContainer, segments, err = c.getAllSegments(opts.Container, opts.ObjectName, headers)
147 segmentContainer, segments, err = c.getAllSegments(ctx, opts.Container, opts.ObjectName, headers)
144148 if err != nil {
145149 return nil, err
146150 }
148152 segmentPath = gopath.Dir(segments[0].Name)
149153 }
150154 } else {
151 if err = c.ObjectMove(opts.Container, opts.ObjectName, opts.Container, getSegment(segmentPath, 1)); err != nil {
155 if err = c.ObjectMove(ctx, opts.Container, opts.ObjectName, opts.Container, getSegment(segmentPath, 1)); err != nil {
152156 return nil, err
153157 }
154158 segments = append(segments, info)
197201 }
198202
199203 // LargeObjectDelete deletes the large object named by container, path
200 func (c *Connection) LargeObjectDelete(container string, objectName string) error {
201 _, headers, err := c.Object(container, objectName)
204 func (c *Connection) LargeObjectDelete(ctx context.Context, container string, objectName string) error {
205 _, headers, err := c.Object(ctx, container, objectName)
202206 if err != nil {
203207 return err
204208 }
205209
206210 var objects [][]string
207211 if headers.IsLargeObject() {
208 segmentContainer, segments, err := c.getAllSegments(container, objectName, headers)
212 segmentContainer, segments, err := c.getAllSegments(ctx, container, objectName, headers)
209213 if err != nil {
210214 return err
211215 }
215219 }
216220 objects = append(objects, []string{container, objectName})
217221
218 info, err := c.cachedQueryInfo()
222 info, err := c.cachedQueryInfo(ctx)
219223 if err == nil && info.SupportsBulkDelete() && len(objects) > 0 {
220224 filenames := make([]string, len(objects))
221225 for i, obj := range objects {
222226 filenames[i] = obj[0] + "/" + obj[1]
223227 }
224 _, err = c.doBulkDelete(filenames, nil)
228 _, err = c.doBulkDelete(ctx, filenames, nil)
225229 // Don't fail on ObjectNotFound because eventual consistency
226230 // makes this situation normal.
227231 if err != nil && err != Forbidden && err != ObjectNotFound {
229233 }
230234 } else {
231235 for _, obj := range objects {
232 if err := c.ObjectDelete(obj[0], obj[1]); err != nil {
236 if err := c.ObjectDelete(ctx, obj[0], obj[1]); err != nil {
233237 return err
234238 }
235239 }
243247 // that have the prefix as indicated by the manifest.
244248 // If the object is a Static Large Object (SLO), it retrieves the JSON content
245249 // of the manifest and return all the segments of it.
246 func (c *Connection) LargeObjectGetSegments(container string, path string) (string, []Object, error) {
247 _, headers, err := c.Object(container, path)
250 func (c *Connection) LargeObjectGetSegments(ctx context.Context, container string, path string) (string, []Object, error) {
251 _, headers, err := c.Object(ctx, container, path)
248252 if err != nil {
249253 return "", nil, err
250254 }
251255
252 return c.getAllSegments(container, path, headers)
256 return c.getAllSegments(ctx, container, path, headers)
253257 }
254258
255259 // Seek sets the offset for the next write operation
300304 }
301305 }
302306
303 func (c *Connection) waitForSegmentsToShowUp(container, objectName string, expectedSize int64) (err error) {
307 func (c *Connection) waitForSegmentsToShowUp(ctx context.Context, container, objectName string, expectedSize int64) (err error) {
304308 err = withLORetry(expectedSize, func() (Headers, int64, error) {
305309 var info Object
306310 var headers Headers
307 info, headers, err = c.objectBase(container, objectName)
311 info, headers, err = c.objectBase(ctx, container, objectName)
308312 if err != nil {
309313 return headers, 0, err
310314 }
313317 return
314318 }
315319
316 // Write satisfies the io.Writer interface
317320 func (file *largeObjectCreateFile) Write(buf []byte) (int, error) {
321 return file.WriteWithContext(context.Background(), buf)
322 }
323
324 func (file *largeObjectCreateFile) WriteWithContext(ctx context.Context, buf []byte) (int, error) {
318325 var sz int64
319326 var relativeFilePos int
320327 writeSegmentIdx := 0
328335 }
329336 sizeToWrite := len(buf)
330337 for offset := 0; offset < sizeToWrite; {
331 newSegment, n, err := file.writeSegment(buf[offset:], writeSegmentIdx, relativeFilePos)
338 newSegment, n, err := file.writeSegment(ctx, buf[offset:], writeSegmentIdx, relativeFilePos)
332339 if err != nil {
333340 return 0, err
334341 }
349356 return sizeToWrite, nil
350357 }
351358
352 func (file *largeObjectCreateFile) writeSegment(buf []byte, writeSegmentIdx int, relativeFilePos int) (*Object, int, error) {
359 func (file *largeObjectCreateFile) writeSegment(ctx context.Context, buf []byte, writeSegmentIdx int, relativeFilePos int) (*Object, int, error) {
353360 var (
354361 readers []io.Reader
355362 existingSegment *Object
365372 if relativeFilePos > 0 {
366373 headers := make(Headers)
367374 headers["Range"] = "bytes=0-" + strconv.FormatInt(int64(relativeFilePos-1), 10)
368 existingSegmentReader, _, err := file.conn.ObjectOpen(file.segmentContainer, segmentName, true, headers)
375 existingSegmentReader, _, err := file.conn.ObjectOpen(ctx, file.segmentContainer, segmentName, true, headers)
369376 if err != nil {
370377 return nil, 0, err
371378 }
383390 if existingSegment != nil && segmentSize < int(existingSegment.Bytes) {
384391 headers := make(Headers)
385392 headers["Range"] = "bytes=" + strconv.FormatInt(int64(segmentSize), 10) + "-"
386 tailSegmentReader, _, err := file.conn.ObjectOpen(file.segmentContainer, segmentName, true, headers)
393 tailSegmentReader, _, err := file.conn.ObjectOpen(ctx, file.segmentContainer, segmentName, true, headers)
387394 if err != nil {
388395 return nil, 0, err
389396 }
392399 readers = append(readers, tailSegmentReader)
393400 }
394401 segmentReader := io.MultiReader(readers...)
395 headers, err := file.conn.ObjectPut(file.segmentContainer, segmentName, segmentReader, true, "", file.contentType, nil)
402 headers, err := file.conn.ObjectPut(ctx, file.segmentContainer, segmentName, segmentReader, true, "", file.contentType, nil)
396403 if err != nil {
397404 return nil, 0, err
398405 }
415422 }
416423
417424 func (blo *bufferedLargeObjectFile) Close() error {
425 return blo.CloseWithContext(context.Background())
426 }
427
428 func (blo *bufferedLargeObjectFile) CloseWithContext(ctx context.Context) error {
418429 err := blo.bw.Flush()
419430 if err != nil {
420431 return err
421432 }
422 return blo.LargeObjectFile.Close()
433 return blo.LargeObjectFile.CloseWithContext(ctx)
434 }
435
436 func (blo *bufferedLargeObjectFile) WriteWithContext(_ context.Context, p []byte) (n int, err error) {
437 return blo.Write(p)
423438 }
424439
425440 func (blo *bufferedLargeObjectFile) Write(p []byte) (n int, err error) {
438453 return blo.LargeObjectFile.Size() + int64(blo.bw.Buffered())
439454 }
440455
441 func (blo *bufferedLargeObjectFile) Flush() error {
456 func (blo *bufferedLargeObjectFile) Flush(ctx context.Context) error {
442457 err := blo.bw.Flush()
443458 if err != nil {
444459 return err
445460 }
446 return blo.LargeObjectFile.Flush()
447 }
461 return blo.LargeObjectFile.Flush(ctx)
462 }
00 package rs
11
22 import (
3 "context"
34 "errors"
45 "net/http"
56 "strconv"
67
7 "github.com/ncw/swift"
8 "github.com/ncw/swift/v2"
89 )
910
1011 // RsConnection is a RackSpace specific wrapper to the core swift library which
1516 }
1617
1718 // manage is similar to the swift storage method, but uses the CDN Management URL for CDN specific calls.
18 func (c *RsConnection) manage(p swift.RequestOpts) (resp *http.Response, headers swift.Headers, err error) {
19 func (c *RsConnection) manage(ctx context.Context, p swift.RequestOpts) (resp *http.Response, headers swift.Headers, err error) {
1920 p.OnReAuth = func() (string, error) {
2021 if c.cdnUrl == "" {
2122 c.cdnUrl = c.Auth.CdnUrl()
3132 return nil, nil, err
3233 }
3334 }
34 return c.Connection.Call(c.cdnUrl, p)
35 return c.Connection.Call(ctx, c.cdnUrl, p)
3536 }
3637
3738 // ContainerCDNEnable enables a container for public CDN usage.
3940 // Change the default TTL of 259200 seconds (72 hours) by passing in an integer value.
4041 //
4142 // This method can be called again to change the TTL.
42 func (c *RsConnection) ContainerCDNEnable(container string, ttl int) (swift.Headers, error) {
43 func (c *RsConnection) ContainerCDNEnable(ctx context.Context, container string, ttl int) (swift.Headers, error) {
4344 h := swift.Headers{"X-CDN-Enabled": "true"}
4445 if ttl > 0 {
4546 h["X-TTL"] = strconv.Itoa(ttl)
4647 }
4748
48 _, headers, err := c.manage(swift.RequestOpts{
49 _, headers, err := c.manage(ctx, swift.RequestOpts{
4950 Container: container,
5051 Operation: "PUT",
5152 ErrorMap: swift.ContainerErrorMap,
5657 }
5758
5859 // ContainerCDNDisable disables CDN access to a container.
59 func (c *RsConnection) ContainerCDNDisable(container string) error {
60 func (c *RsConnection) ContainerCDNDisable(ctx context.Context, container string) error {
6061 h := swift.Headers{"X-CDN-Enabled": "false"}
6162
62 _, _, err := c.manage(swift.RequestOpts{
63 _, _, err := c.manage(ctx, swift.RequestOpts{
6364 Container: container,
6465 Operation: "PUT",
6566 ErrorMap: swift.ContainerErrorMap,
7071 }
7172
7273 // ContainerCDNMeta returns the CDN metadata for a container.
73 func (c *RsConnection) ContainerCDNMeta(container string) (swift.Headers, error) {
74 _, headers, err := c.manage(swift.RequestOpts{
74 func (c *RsConnection) ContainerCDNMeta(ctx context.Context, container string) (swift.Headers, error) {
75 _, headers, err := c.manage(ctx, swift.RequestOpts{
7576 Container: container,
7677 Operation: "HEAD",
7778 ErrorMap: swift.ContainerErrorMap,
11 package rs_test
22
33 import (
4 "context"
45 "os"
56 "testing"
67
7 "github.com/ncw/swift/rs"
8 "github.com/ncw/swift/v2/rs"
89 )
910
1011 var (
3132 c.UserName = UserName
3233 c.ApiKey = ApiKey
3334 c.AuthUrl = AuthUrl
34 err := c.Authenticate()
35 err := c.Authenticate(context.Background())
3536 if err != nil {
3637 t.Fatal("Auth failed", err)
3738 }
4243
4344 // Setup
4445 func TestContainerCreate(t *testing.T) {
45 err := c.ContainerCreate(CONTAINER, nil)
46 err := c.ContainerCreate(context.Background(), CONTAINER, nil)
4647 if err != nil {
4748 t.Fatal(err)
4849 }
4950 }
5051
5152 func TestCDNEnable(t *testing.T) {
52 headers, err := c.ContainerCDNEnable(CONTAINER, 0)
53 headers, err := c.ContainerCDNEnable(context.Background(), CONTAINER, 0)
5354 if err != nil {
5455 t.Error(err)
5556 }
6364 c2.UserName = c.UserName
6465 c2.ApiKey = c.ApiKey
6566 c2.AuthUrl = c.AuthUrl
66 _, err := c2.ContainerCDNEnable(CONTAINER, 0)
67 _, err := c2.ContainerCDNEnable(context.Background(), CONTAINER, 0)
6768 if err != nil {
6869 t.Fatalf("Failed to reauthenticate: %v", err)
6970 }
7071 }
7172
7273 func TestCDNMeta(t *testing.T) {
73 headers, err := c.ContainerCDNMeta(CONTAINER)
74 headers, err := c.ContainerCDNMeta(context.Background(), CONTAINER)
7475 if err != nil {
7576 t.Error(err)
7677 }
8081 }
8182
8283 func TestCDNDisable(t *testing.T) {
83 err := c.ContainerCDNDisable(CONTAINER) // files stick in CDN until TTL expires
84 err := c.ContainerCDNDisable(context.Background(), CONTAINER) // files stick in CDN until TTL expires
8485 if err != nil {
8586 t.Error(err)
8687 }
8889
8990 // Teardown
9091 func TestContainerDelete(t *testing.T) {
91 err := c.ContainerDelete(CONTAINER)
92 err := c.ContainerDelete(context.Background(), CONTAINER)
9293 if err != nil {
9394 t.Fatal(err)
9495 }
11
22 import (
33 "bytes"
4 "context"
45 "encoding/json"
56 "errors"
67 "fmt"
3637 // an object which satisfies io.Writer, io.Seeker, io.Closer and
3738 // io.ReaderFrom. The flags are as passed to the largeObjectCreate
3839 // method.
39 func (c *Connection) StaticLargeObjectCreateFile(opts *LargeObjectOpts) (LargeObjectFile, error) {
40 info, err := c.cachedQueryInfo()
40 func (c *Connection) StaticLargeObjectCreateFile(ctx context.Context, opts *LargeObjectOpts) (LargeObjectFile, error) {
41 info, err := c.cachedQueryInfo(ctx)
4142 if err != nil || !info.SupportsSLO() {
4243 return nil, SLONotSupported
4344 }
4546 if realMinChunkSize > opts.MinChunkSize {
4647 opts.MinChunkSize = realMinChunkSize
4748 }
48 lo, err := c.largeObjectCreate(opts)
49 lo, err := c.largeObjectCreate(ctx, opts)
4950 if err != nil {
5051 return nil, err
5152 }
5758 // StaticLargeObjectCreate creates or truncates an existing static
5859 // large object returning a writeable object. This sets opts.Flags to
5960 // an appropriate value before calling StaticLargeObjectCreateFile
60 func (c *Connection) StaticLargeObjectCreate(opts *LargeObjectOpts) (LargeObjectFile, error) {
61 func (c *Connection) StaticLargeObjectCreate(ctx context.Context, opts *LargeObjectOpts) (LargeObjectFile, error) {
6162 opts.Flags = os.O_TRUNC | os.O_CREATE
62 return c.StaticLargeObjectCreateFile(opts)
63 return c.StaticLargeObjectCreateFile(ctx, opts)
6364 }
6465
6566 // StaticLargeObjectDelete deletes a static large object and all of its segments.
66 func (c *Connection) StaticLargeObjectDelete(container string, path string) error {
67 info, err := c.cachedQueryInfo()
67 func (c *Connection) StaticLargeObjectDelete(ctx context.Context, container string, path string) error {
68 info, err := c.cachedQueryInfo(ctx)
6869 if err != nil || !info.SupportsSLO() {
6970 return SLONotSupported
7071 }
71 return c.LargeObjectDelete(container, path)
72 return c.LargeObjectDelete(ctx, container, path)
7273 }
7374
7475 // StaticLargeObjectMove moves a static large object from srcContainer, srcObjectName to dstContainer, dstObjectName
75 func (c *Connection) StaticLargeObjectMove(srcContainer string, srcObjectName string, dstContainer string, dstObjectName string) error {
76 swiftInfo, err := c.cachedQueryInfo()
76 func (c *Connection) StaticLargeObjectMove(ctx context.Context, srcContainer string, srcObjectName string, dstContainer string, dstObjectName string) error {
77 swiftInfo, err := c.cachedQueryInfo(ctx)
7778 if err != nil || !swiftInfo.SupportsSLO() {
7879 return SLONotSupported
7980 }
80 info, headers, err := c.Object(srcContainer, srcObjectName)
81 info, headers, err := c.Object(ctx, srcContainer, srcObjectName)
8182 if err != nil {
8283 return err
8384 }
8485
85 container, segments, err := c.getAllSegments(srcContainer, srcObjectName, headers)
86 container, segments, err := c.getAllSegments(ctx, srcContainer, srcObjectName, headers)
8687 if err != nil {
8788 return err
8889 }
9091 //copy only metadata during move (other headers might not be safe for copying)
9192 headers = headers.ObjectMetadata().ObjectHeaders()
9293
93 if err := c.createSLOManifest(dstContainer, dstObjectName, info.ContentType, container, segments, headers); err != nil {
94 if err := c.createSLOManifest(ctx, dstContainer, dstObjectName, info.ContentType, container, segments, headers); err != nil {
9495 return err
9596 }
9697
97 if err := c.ObjectDelete(srcContainer, srcObjectName); err != nil {
98 if err := c.ObjectDelete(ctx, srcContainer, srcObjectName); err != nil {
9899 return err
99100 }
100101
102103 }
103104
104105 // createSLOManifest creates a static large object manifest
105 func (c *Connection) createSLOManifest(container string, path string, contentType string, segmentContainer string, segments []Object, h Headers) error {
106 func (c *Connection) createSLOManifest(ctx context.Context, container string, path string, contentType string, segmentContainer string, segments []Object, h Headers) error {
106107 sloSegments := make([]swiftSegment, len(segments))
107108 for i, segment := range segments {
108109 sloSegments[i].Path = fmt.Sprintf("%s/%s", segmentContainer, segment.Name)
117118
118119 values := url.Values{}
119120 values.Set("multipart-manifest", "put")
120 if _, err := c.objectPut(container, path, bytes.NewBuffer(content), false, "", contentType, h, values); err != nil {
121 if _, err := c.objectPut(ctx, container, path, bytes.NewBuffer(content), false, "", contentType, h, values); err != nil {
121122 return err
122123 }
123124
125126 }
126127
127128 func (file *StaticLargeObjectCreateFile) Close() error {
128 return file.Flush()
129 return file.CloseWithContext(context.Background())
129130 }
130131
131 func (file *StaticLargeObjectCreateFile) Flush() error {
132 if err := file.conn.createSLOManifest(file.container, file.objectName, file.contentType, file.segmentContainer, file.segments, file.headers); err != nil {
132 func (file *StaticLargeObjectCreateFile) CloseWithContext(ctx context.Context) error {
133 return file.Flush(ctx)
134 }
135
136 func (file *StaticLargeObjectCreateFile) Flush(ctx context.Context) error {
137 if err := file.conn.createSLOManifest(ctx, file.container, file.objectName, file.contentType, file.segmentContainer, file.segments, file.headers); err != nil {
133138 return err
134139 }
135 return file.conn.waitForSegmentsToShowUp(file.container, file.objectName, file.Size())
140 return file.conn.waitForSegmentsToShowUp(ctx, file.container, file.objectName, file.Size())
136141 }
137142
138 func (c *Connection) getAllSLOSegments(container, path string) (string, []Object, error) {
143 func (c *Connection) getAllSLOSegments(ctx context.Context, container, path string) (string, []Object, error) {
139144 var (
140145 segmentList []swiftSegment
141146 segments []Object
146151 values := url.Values{}
147152 values.Set("multipart-manifest", "get")
148153
149 file, _, err := c.objectOpen(container, path, true, nil, values)
154 file, _, err := c.objectOpen(ctx, container, path, true, nil, values)
150155 if err != nil {
151156 return "", nil, err
152157 }
+122
-121
swift.go less more
22 import (
33 "bufio"
44 "bytes"
5 "context"
56 "crypto/hmac"
67 "crypto/md5"
78 "crypto/sha1"
7172 // import (
7273 // "appengine/urlfetch"
7374 // "fmt"
74 // "github.com/ncw/swift"
75 // "github.com/ncw/swift/v2"
7576 // )
7677 //
7778 // func handler(w http.ResponseWriter, r *http.Request) {
456457 //
457458 // If you don't call it before calling one of the connection methods
458459 // then it will be called for you on the first access.
459 func (c *Connection) Authenticate() (err error) {
460 func (c *Connection) Authenticate(ctx context.Context) (err error) {
460461 if c.authLock == nil {
461462 c.authLock = &sync.Mutex{}
462463 }
463464 c.authLock.Lock()
464465 defer c.authLock.Unlock()
465 return c.authenticate()
466 return c.authenticate(ctx)
466467 }
467468
468469 // Internal implementation of Authenticate
469470 //
470471 // Call with authLock held
471 func (c *Connection) authenticate() (err error) {
472 func (c *Connection) authenticate(ctx context.Context) (err error) {
472473 c.setDefaults()
473474
474475 // Flush the keepalives connection - if we are
485486 retries := 1
486487 again:
487488 var req *http.Request
488 req, err = c.Auth.Request(c)
489 req, err = c.Auth.Request(ctx, c)
489490 if err != nil {
490491 return
491492 }
513514 }
514515 return
515516 }
516 err = c.Auth.Response(resp)
517 err = c.Auth.Response(ctx, resp)
517518 if err != nil {
518519 return
519520 }
540541 // Get an authToken and url
541542 //
542543 // The Url may be updated if it needed to authenticate using the OnReAuth function
543 func (c *Connection) getUrlAndAuthToken(targetUrlIn string, OnReAuth func() (string, error)) (targetUrlOut, authToken string, err error) {
544 func (c *Connection) getUrlAndAuthToken(ctx context.Context, targetUrlIn string, OnReAuth func() (string, error)) (targetUrlOut, authToken string, err error) {
544545 c.authLock.Lock()
545546 defer c.authLock.Unlock()
546547 targetUrlOut = targetUrlIn
547548 if !c.authenticated() {
548 err = c.authenticate()
549 err = c.authenticate(ctx)
549550 if err != nil {
550551 return
551552 }
628629 }
629630
630631 // Discover Swift configuration by doing a request against /info
631 func (c *Connection) QueryInfo() (infos SwiftInfo, err error) {
632 func (c *Connection) QueryInfo(ctx context.Context) (infos SwiftInfo, err error) {
632633 infoUrl, err := url.Parse(c.StorageUrl)
633634 if err != nil {
634635 return nil, err
635636 }
636637 infoUrl.Path = path.Join(infoUrl.Path, "..", "..", "info")
637 resp, err := c.client.Get(infoUrl.String())
638 req, err := http.NewRequestWithContext(ctx, http.MethodGet, infoUrl.String(), nil)
639 if err != nil {
640 return nil, err
641 }
642 resp, err := c.client.Do(req)
638643 if err == nil {
639644 if resp.StatusCode != http.StatusOK {
640645 drainAndClose(resp.Body, nil)
651656 return nil, err
652657 }
653658
654 func (c *Connection) cachedQueryInfo() (infos SwiftInfo, err error) {
659 func (c *Connection) cachedQueryInfo(ctx context.Context) (infos SwiftInfo, err error) {
655660 c.authLock.Lock()
656661 infos = c.swiftInfo
657662 c.authLock.Unlock()
658663 if infos == nil {
659 infos, err = c.QueryInfo()
664 infos, err = c.QueryInfo(ctx)
660665 if err != nil {
661666 return
662667 }
699704 // receives a 401 error which means the token has expired
700705 //
701706 // This method is exported so extensions can call it.
702 func (c *Connection) Call(targetUrl string, p RequestOpts) (resp *http.Response, headers Headers, err error) {
707 func (c *Connection) Call(ctx context.Context, targetUrl string, p RequestOpts) (resp *http.Response, headers Headers, err error) {
703708 c.authLock.Lock()
704709 c.setDefaults()
705710 c.authLock.Unlock()
710715 var req *http.Request
711716 for {
712717 var authToken string
713 if targetUrl, authToken, err = c.getUrlAndAuthToken(targetUrl, p.OnReAuth); err != nil {
718 if targetUrl, authToken, err = c.getUrlAndAuthToken(ctx, targetUrl, p.OnReAuth); err != nil {
714719 return //authentication failure
715720 }
716721 var URL *url.URL
733738 if reader != nil {
734739 reader = newWatchdogReader(reader, c.Timeout, timer)
735740 }
736 req, err = http.NewRequest(p.Operation, URL.String(), reader)
741 req, err = http.NewRequestWithContext(ctx, p.Operation, URL.String(), reader)
737742 if err != nil {
738743 return
739744 }
808813 //
809814 // This will Authenticate if necessary, and re-authenticate if it
810815 // receives a 401 error which means the token has expired
811 func (c *Connection) storage(p RequestOpts) (resp *http.Response, headers Headers, err error) {
816 func (c *Connection) storage(ctx context.Context, p RequestOpts) (resp *http.Response, headers Headers, err error) {
812817 p.OnReAuth = func() (string, error) {
813818 return c.StorageUrl, nil
814819 }
815820 c.authLock.Lock()
816821 url := c.StorageUrl
817822 c.authLock.Unlock()
818 return c.Call(url, p)
823 return c.Call(ctx, url, p)
819824 }
820825
821826 // readLines reads the response into an array of strings.
886891 }
887892
888893 // ContainerNames returns a slice of names of containers in this account.
889 func (c *Connection) ContainerNames(opts *ContainersOpts) ([]string, error) {
894 func (c *Connection) ContainerNames(ctx context.Context, opts *ContainersOpts) ([]string, error) {
890895 v, h := opts.parse()
891 resp, _, err := c.storage(RequestOpts{
896 resp, _, err := c.storage(ctx, RequestOpts{
892897 Operation: "GET",
893898 Parameters: v,
894899 ErrorMap: ContainerErrorMap,
910915
911916 // Containers returns a slice of structures with full information as
912917 // described in Container.
913 func (c *Connection) Containers(opts *ContainersOpts) ([]Container, error) {
918 func (c *Connection) Containers(ctx context.Context, opts *ContainersOpts) ([]Container, error) {
914919 v, h := opts.parse()
915920 v.Set("format", "json")
916 resp, _, err := c.storage(RequestOpts{
921 resp, _, err := c.storage(ctx, RequestOpts{
917922 Operation: "GET",
918923 Parameters: v,
919924 ErrorMap: ContainerErrorMap,
946951 // It calls Containers multiple times using the Marker parameter
947952 //
948953 // It has a default Limit parameter but you may pass in your own
949 func (c *Connection) ContainersAll(opts *ContainersOpts) ([]Container, error) {
954 func (c *Connection) ContainersAll(ctx context.Context, opts *ContainersOpts) ([]Container, error) {
950955 opts = containersAllOpts(opts)
951956 containers := make([]Container, 0)
952957 for {
953 newContainers, err := c.Containers(opts)
958 newContainers, err := c.Containers(ctx, opts)
954959 if err != nil {
955960 return nil, err
956961 }
968973 // It calls ContainerNames multiple times using the Marker parameter
969974 //
970975 // It has a default Limit parameter but you may pass in your own
971 func (c *Connection) ContainerNamesAll(opts *ContainersOpts) ([]string, error) {
976 func (c *Connection) ContainerNamesAll(ctx context.Context, opts *ContainersOpts) ([]string, error) {
972977 opts = containersAllOpts(opts)
973978 containers := make([]string, 0)
974979 for {
975 newContainers, err := c.ContainerNames(opts)
980 newContainers, err := c.ContainerNames(ctx, opts)
976981 if err != nil {
977982 return nil, err
978983 }
10281033 }
10291034
10301035 // ObjectNames returns a slice of names of objects in a given container.
1031 func (c *Connection) ObjectNames(container string, opts *ObjectsOpts) ([]string, error) {
1036 func (c *Connection) ObjectNames(ctx context.Context, container string, opts *ObjectsOpts) ([]string, error) {
10321037 v, h := opts.parse()
1033 resp, _, err := c.storage(RequestOpts{
1038 resp, _, err := c.storage(ctx, RequestOpts{
10341039 Container: container,
10351040 Operation: "GET",
10361041 Parameters: v,
10641069 // with ContentType 'application/directory'. These are not real
10651070 // objects but represent directories of objects which haven't had an
10661071 // object created for them.
1067 func (c *Connection) Objects(container string, opts *ObjectsOpts) ([]Object, error) {
1072 func (c *Connection) Objects(ctx context.Context, container string, opts *ObjectsOpts) ([]Object, error) {
10681073 v, h := opts.parse()
10691074 v.Set("format", "json")
1070 resp, _, err := c.storage(RequestOpts{
1075 resp, _, err := c.storage(ctx, RequestOpts{
10711076 Container: container,
10721077 Operation: "GET",
10731078 Parameters: v,
11291134
11301135 // A closure defined by the caller to iterate through all objects
11311136 //
1132 // Call Objects or ObjectNames from here with the *ObjectOpts passed in
1137 // Call Objects or ObjectNames from here with the context.Context and *ObjectOpts passed in
11331138 //
11341139 // Do whatever is required with the results then return them
1135 type ObjectsWalkFn func(*ObjectsOpts) (interface{}, error)
1140 type ObjectsWalkFn func(context.Context, *ObjectsOpts) (interface{}, error)
11361141
11371142 // ObjectsWalk is uses to iterate through all the objects in chunks as
11381143 // returned by Objects or ObjectNames using the Marker and Limit
11441149 // Errors will be returned from this function
11451150 //
11461151 // It has a default Limit parameter but you may pass in your own
1147 func (c *Connection) ObjectsWalk(container string, opts *ObjectsOpts, walkFn ObjectsWalkFn) error {
1152 func (c *Connection) ObjectsWalk(ctx context.Context, container string, opts *ObjectsOpts, walkFn ObjectsWalkFn) error {
11481153 opts = objectsAllOpts(opts, allObjectsChanLimit)
11491154 for {
1150 objects, err := walkFn(opts)
1155 objects, err := walkFn(ctx, opts)
11511156 if err != nil {
11521157 return err
11531158 }
11781183 // ObjectsAll is like Objects but it returns an unlimited number of Objects in a slice
11791184 //
11801185 // It calls Objects multiple times using the Marker parameter
1181 func (c *Connection) ObjectsAll(container string, opts *ObjectsOpts) ([]Object, error) {
1186 func (c *Connection) ObjectsAll(ctx context.Context, container string, opts *ObjectsOpts) ([]Object, error) {
11821187 objects := make([]Object, 0)
1183 err := c.ObjectsWalk(container, opts, func(opts *ObjectsOpts) (interface{}, error) {
1184 newObjects, err := c.Objects(container, opts)
1188 err := c.ObjectsWalk(ctx, container, opts, func(ctx context.Context, opts *ObjectsOpts) (interface{}, error) {
1189 newObjects, err := c.Objects(ctx, container, opts)
11851190 if err == nil {
11861191 objects = append(objects, newObjects...)
11871192 }
11961201 // reset unless KeepMarker is set
11971202 //
11981203 // It has a default Limit parameter but you may pass in your own
1199 func (c *Connection) ObjectNamesAll(container string, opts *ObjectsOpts) ([]string, error) {
1204 func (c *Connection) ObjectNamesAll(ctx context.Context, container string, opts *ObjectsOpts) ([]string, error) {
12001205 objects := make([]string, 0)
1201 err := c.ObjectsWalk(container, opts, func(opts *ObjectsOpts) (interface{}, error) {
1202 newObjects, err := c.ObjectNames(container, opts)
1206 err := c.ObjectsWalk(ctx, container, opts, func(ctx context.Context, opts *ObjectsOpts) (interface{}, error) {
1207 newObjects, err := c.ObjectNames(ctx, container, opts)
12031208 if err == nil {
12041209 objects = append(objects, newObjects...)
12051210 }
12261231 }
12271232
12281233 // Account returns info about the account in an Account struct.
1229 func (c *Connection) Account() (info Account, headers Headers, err error) {
1234 func (c *Connection) Account(ctx context.Context) (info Account, headers Headers, err error) {
12301235 var resp *http.Response
1231 resp, headers, err = c.storage(RequestOpts{
1236 resp, headers, err = c.storage(ctx, RequestOpts{
12321237 Operation: "HEAD",
12331238 ErrorMap: ContainerErrorMap,
12341239 NoResponse: true,
12611266 // Add or update keys by mentioning them in the Headers.
12621267 //
12631268 // Remove keys by setting them to an empty string.
1264 func (c *Connection) AccountUpdate(h Headers) error {
1265 _, _, err := c.storage(RequestOpts{
1269 func (c *Connection) AccountUpdate(ctx context.Context, h Headers) error {
1270 _, _, err := c.storage(ctx, RequestOpts{
12661271 Operation: "POST",
12671272 ErrorMap: ContainerErrorMap,
12681273 NoResponse: true,
12761281 // If you don't want to add Headers just pass in nil
12771282 //
12781283 // No error is returned if it already exists but the metadata if any will be updated.
1279 func (c *Connection) ContainerCreate(container string, h Headers) error {
1280 _, _, err := c.storage(RequestOpts{
1284 func (c *Connection) ContainerCreate(ctx context.Context, container string, h Headers) error {
1285 _, _, err := c.storage(ctx, RequestOpts{
12811286 Container: container,
12821287 Operation: "PUT",
12831288 ErrorMap: ContainerErrorMap,
12901295 // ContainerDelete deletes a container.
12911296 //
12921297 // May return ContainerDoesNotExist or ContainerNotEmpty
1293 func (c *Connection) ContainerDelete(container string) error {
1294 _, _, err := c.storage(RequestOpts{
1298 func (c *Connection) ContainerDelete(ctx context.Context, container string) error {
1299 _, _, err := c.storage(ctx, RequestOpts{
12951300 Container: container,
12961301 Operation: "DELETE",
12971302 ErrorMap: ContainerErrorMap,
13021307
13031308 // Container returns info about a single container including any
13041309 // metadata in the headers.
1305 func (c *Connection) Container(container string) (info Container, headers Headers, err error) {
1310 func (c *Connection) Container(ctx context.Context, container string) (info Container, headers Headers, err error) {
13061311 var resp *http.Response
1307 resp, headers, err = c.storage(RequestOpts{
1312 resp, headers, err = c.storage(ctx, RequestOpts{
13081313 Container: container,
13091314 Operation: "HEAD",
13101315 ErrorMap: ContainerErrorMap,
13311336 // Remove keys by setting them to an empty string.
13321337 //
13331338 // Container metadata can only be read with Container() not with Containers().
1334 func (c *Connection) ContainerUpdate(container string, h Headers) error {
1335 _, _, err := c.storage(RequestOpts{
1339 func (c *Connection) ContainerUpdate(ctx context.Context, container string, h Headers) error {
1340 _, _, err := c.storage(ctx, RequestOpts{
13361341 Container: container,
13371342 Operation: "POST",
13381343 ErrorMap: ContainerErrorMap,
14681473 //
14691474 // If contentType is set it will be used, otherwise one will be
14701475 // guessed from objectName using mime.TypeByExtension
1471 func (c *Connection) ObjectCreate(container string, objectName string, checkHash bool, Hash string, contentType string, h Headers) (file *ObjectCreateFile, err error) {
1476 func (c *Connection) ObjectCreate(ctx context.Context, container string, objectName string, checkHash bool, Hash string, contentType string, h Headers) (file *ObjectCreateFile, err error) {
14721477 extraHeaders := objectPutHeaders(objectName, &checkHash, Hash, contentType, h)
14731478 pipeReader, pipeWriter := io.Pipe()
14741479 file = &ObjectCreateFile{
14891494 NoResponse: true,
14901495 ErrorMap: objectErrorMap,
14911496 }
1492 file.resp, file.headers, file.err = c.storage(opts)
1497 file.resp, file.headers, file.err = c.storage(ctx, opts)
14931498 // Signal finished
14941499 pipeReader.Close()
14951500 close(file.done)
14971502 return
14981503 }
14991504
1500 func (c *Connection) ObjectSymlinkCreate(container string, symlink string, targetAccount string, targetContainer string, targetObject string, targetEtag string) (headers Headers, err error) {
1505 func (c *Connection) ObjectSymlinkCreate(ctx context.Context, container string, symlink string, targetAccount string, targetContainer string, targetObject string, targetEtag string) (headers Headers, err error) {
15011506
15021507 EMPTY_MD5 := "d41d8cd98f00b204e9800998ecf8427e"
15031508 symHeaders := Headers{}
15091514 symHeaders["X-Symlink-Target-Etag"] = targetEtag
15101515 }
15111516 symHeaders["X-Symlink-Target"] = fmt.Sprintf("%s/%s", targetContainer, targetObject)
1512 _, err = c.ObjectPut(container, symlink, contents, true, EMPTY_MD5, "application/symlink", symHeaders)
1513 return
1514 }
1515
1516 func (c *Connection) objectPut(container string, objectName string, contents io.Reader, checkHash bool, Hash string, contentType string, h Headers, parameters url.Values) (headers Headers, err error) {
1517 _, err = c.ObjectPut(ctx, container, symlink, contents, true, EMPTY_MD5, "application/symlink", symHeaders)
1518 return
1519 }
1520
1521 func (c *Connection) objectPut(ctx context.Context, container string, objectName string, contents io.Reader, checkHash bool, Hash string, contentType string, h Headers, parameters url.Values) (headers Headers, err error) {
15171522 extraHeaders := objectPutHeaders(objectName, &checkHash, Hash, contentType, h)
15181523 hash := md5.New()
15191524 var body io.Reader = contents
15201525 if checkHash {
15211526 body = io.TeeReader(contents, hash)
15221527 }
1523 _, headers, err = c.storage(RequestOpts{
1528 _, headers, err = c.storage(ctx, RequestOpts{
15241529 Container: container,
15251530 ObjectName: objectName,
15261531 Operation: "PUT",
15651570 //
15661571 // If contentType is set it will be used, otherwise one will be
15671572 // guessed from objectName using mime.TypeByExtension
1568 func (c *Connection) ObjectPut(container string, objectName string, contents io.Reader, checkHash bool, Hash string, contentType string, h Headers) (headers Headers, err error) {
1569 return c.objectPut(container, objectName, contents, checkHash, Hash, contentType, h, nil)
1573 func (c *Connection) ObjectPut(ctx context.Context, container string, objectName string, contents io.Reader, checkHash bool, Hash string, contentType string, h Headers) (headers Headers, err error) {
1574 return c.objectPut(ctx, container, objectName, contents, checkHash, Hash, contentType, h, nil)
15701575 }
15711576
15721577 // ObjectPutBytes creates an object from a []byte in a container.
15731578 //
15741579 // This is a simplified interface which checks the MD5.
1575 func (c *Connection) ObjectPutBytes(container string, objectName string, contents []byte, contentType string) (err error) {
1580 func (c *Connection) ObjectPutBytes(ctx context.Context, container string, objectName string, contents []byte, contentType string) (err error) {
15761581 buf := bytes.NewBuffer(contents)
15771582 h := Headers{"Content-Length": strconv.Itoa(len(contents))}
1578 _, err = c.ObjectPut(container, objectName, buf, true, "", contentType, h)
1583 _, err = c.ObjectPut(ctx, container, objectName, buf, true, "", contentType, h)
15791584 return
15801585 }
15811586
15821587 // ObjectPutString creates an object from a string in a container.
15831588 //
15841589 // This is a simplified interface which checks the MD5
1585 func (c *Connection) ObjectPutString(container string, objectName string, contents string, contentType string) (err error) {
1590 func (c *Connection) ObjectPutString(ctx context.Context, container string, objectName string, contents string, contentType string) (err error) {
15861591 buf := strings.NewReader(contents)
15871592 h := Headers{"Content-Length": strconv.Itoa(len(contents))}
1588 _, err = c.ObjectPut(container, objectName, buf, true, "", contentType, h)
1593 _, err = c.ObjectPut(ctx, container, objectName, buf, true, "", contentType, h)
15891594 return
15901595 }
15911596
16351640 // unlike os.File
16361641 //
16371642 // Seek(0, 1) will return the current file pointer.
1638 func (file *ObjectOpenFile) Seek(offset int64, whence int) (newPos int64, err error) {
1643 func (file *ObjectOpenFile) Seek(ctx context.Context, offset int64, whence int) (newPos int64, err error) {
16391644 file.overSeeked = false
16401645 switch whence {
16411646 case 0: // relative to start
16731678 } else {
16741679 delete(file.headers, "Range")
16751680 }
1676 newFile, _, err := file.connection.ObjectOpen(file.container, file.objectName, false, file.headers)
1681 newFile, _, err := file.connection.ObjectOpen(ctx, file.container, file.objectName, false, file.headers)
16771682 if err != nil {
16781683 return
16791684 }
16871692
16881693 // Length gets the objects content length either from a cached copy or
16891694 // from the server.
1690 func (file *ObjectOpenFile) Length() (int64, error) {
1695 func (file *ObjectOpenFile) Length(ctx context.Context) (int64, error) {
16911696 if !file.lengthOk {
1692 info, _, err := file.connection.Object(file.container, file.objectName)
1697 info, _, err := file.connection.Object(ctx, file.container, file.objectName)
16931698 file.length = info.Bytes
16941699 file.lengthOk = (err == nil)
16951700 return file.length, err
17261731 return
17271732 }
17281733
1729 // Check it satisfies the interfaces
1730 var _ io.ReadCloser = &ObjectOpenFile{}
1731 var _ io.Seeker = &ObjectOpenFile{}
1732
1733 func (c *Connection) objectOpenBase(container string, objectName string, checkHash bool, h Headers, parameters url.Values) (file *ObjectOpenFile, headers Headers, err error) {
1734 func (c *Connection) objectOpenBase(ctx context.Context, container string, objectName string, checkHash bool, h Headers, parameters url.Values) (file *ObjectOpenFile, headers Headers, err error) {
17341735 var resp *http.Response
17351736 opts := RequestOpts{
17361737 Container: container,
17401741 Headers: h,
17411742 Parameters: parameters,
17421743 }
1743 resp, headers, err = c.storage(opts)
1744 resp, headers, err = c.storage(ctx, opts)
17441745 if err != nil {
17451746 return
17461747 }
17701771 return
17711772 }
17721773
1773 func (c *Connection) objectOpen(container string, objectName string, checkHash bool, h Headers, parameters url.Values) (file *ObjectOpenFile, headers Headers, err error) {
1774 func (c *Connection) objectOpen(ctx context.Context, container string, objectName string, checkHash bool, h Headers, parameters url.Values) (file *ObjectOpenFile, headers Headers, err error) {
17741775 err = withLORetry(0, func() (Headers, int64, error) {
1775 file, headers, err = c.objectOpenBase(container, objectName, checkHash, h, parameters)
1776 file, headers, err = c.objectOpenBase(ctx, container, objectName, checkHash, h, parameters)
17761777 if err != nil {
17771778 return headers, 0, err
17781779 }
18041805 // you will need to download everything in the manifest separately.
18051806 //
18061807 // headers["Content-Type"] will give the content type if desired.
1807 func (c *Connection) ObjectOpen(container string, objectName string, checkHash bool, h Headers) (file *ObjectOpenFile, headers Headers, err error) {
1808 return c.objectOpen(container, objectName, checkHash, h, nil)
1808 func (c *Connection) ObjectOpen(ctx context.Context, container string, objectName string, checkHash bool, h Headers) (file *ObjectOpenFile, headers Headers, err error) {
1809 return c.objectOpen(ctx, container, objectName, checkHash, h, nil)
18091810 }
18101811
18111812 // ObjectGet gets the object into the io.Writer contents.
18171818 // server. If it is wrong then it will return ObjectCorrupted.
18181819 //
18191820 // headers["Content-Type"] will give the content type if desired.
1820 func (c *Connection) ObjectGet(container string, objectName string, contents io.Writer, checkHash bool, h Headers) (headers Headers, err error) {
1821 file, headers, err := c.ObjectOpen(container, objectName, checkHash, h)
1821 func (c *Connection) ObjectGet(ctx context.Context, container string, objectName string, contents io.Writer, checkHash bool, h Headers) (headers Headers, err error) {
1822 file, headers, err := c.ObjectOpen(ctx, container, objectName, checkHash, h)
18221823 if err != nil {
18231824 return
18241825 }
18301831 // ObjectGetBytes returns an object as a []byte.
18311832 //
18321833 // This is a simplified interface which checks the MD5
1833 func (c *Connection) ObjectGetBytes(container string, objectName string) (contents []byte, err error) {
1834 func (c *Connection) ObjectGetBytes(ctx context.Context, container string, objectName string) (contents []byte, err error) {
18341835 var buf bytes.Buffer
1835 _, err = c.ObjectGet(container, objectName, &buf, true, nil)
1836 _, err = c.ObjectGet(ctx, container, objectName, &buf, true, nil)
18361837 contents = buf.Bytes()
18371838 return
18381839 }
18401841 // ObjectGetString returns an object as a string.
18411842 //
18421843 // This is a simplified interface which checks the MD5
1843 func (c *Connection) ObjectGetString(container string, objectName string) (contents string, err error) {
1844 func (c *Connection) ObjectGetString(ctx context.Context, container string, objectName string) (contents string, err error) {
18441845 var buf bytes.Buffer
1845 _, err = c.ObjectGet(container, objectName, &buf, true, nil)
1846 _, err = c.ObjectGet(ctx, container, objectName, &buf, true, nil)
18461847 contents = buf.String()
18471848 return
18481849 }
18501851 // ObjectDelete deletes the object.
18511852 //
18521853 // May return ObjectNotFound if the object isn't found
1853 func (c *Connection) ObjectDelete(container string, objectName string) error {
1854 _, _, err := c.storage(RequestOpts{
1854 func (c *Connection) ObjectDelete(ctx context.Context, container string, objectName string) error {
1855 _, _, err := c.storage(ctx, RequestOpts{
18551856 Container: container,
18561857 ObjectName: objectName,
18571858 Operation: "DELETE",
19081909 Headers Headers // Response HTTP headers.
19091910 }
19101911
1911 func (c *Connection) doBulkDelete(objects []string, h Headers) (result BulkDeleteResult, err error) {
1912 func (c *Connection) doBulkDelete(ctx context.Context, objects []string, h Headers) (result BulkDeleteResult, err error) {
19121913 var buffer bytes.Buffer
19131914 for _, s := range objects {
19141915 u := url.URL{Path: s}
19221923 for key, value := range h {
19231924 extraHeaders[key] = value
19241925 }
1925 resp, headers, err := c.storage(RequestOpts{
1926 resp, headers, err := c.storage(ctx, RequestOpts{
19261927 Operation: "DELETE",
19271928 Parameters: url.Values{"bulk-delete": []string{"1"}},
19281929 Headers: extraHeaders,
19661967 // See also:
19671968 // * http://docs.openstack.org/trunk/openstack-object-storage/admin/content/object-storage-bulk-delete.html
19681969 // * http://docs.rackspace.com/files/api/v1/cf-devguide/content/Bulk_Delete-d1e2338.html
1969 func (c *Connection) BulkDelete(container string, objectNames []string) (result BulkDeleteResult, err error) {
1970 return c.BulkDeleteHeaders(container, objectNames, nil)
1970 func (c *Connection) BulkDelete(ctx context.Context, container string, objectNames []string) (result BulkDeleteResult, err error) {
1971 return c.BulkDeleteHeaders(ctx, container, objectNames, nil)
19711972 }
19721973
19731974 // BulkDeleteHeaders deletes multiple objectNames from container in one operation.
19781979 // See also:
19791980 // * http://docs.openstack.org/trunk/openstack-object-storage/admin/content/object-storage-bulk-delete.html
19801981 // * http://docs.rackspace.com/files/api/v1/cf-devguide/content/Bulk_Delete-d1e2338.html
1981 func (c *Connection) BulkDeleteHeaders(container string, objectNames []string, h Headers) (result BulkDeleteResult, err error) {
1982 func (c *Connection) BulkDeleteHeaders(ctx context.Context, container string, objectNames []string, h Headers) (result BulkDeleteResult, err error) {
19821983 if len(objectNames) == 0 {
19831984 result.Errors = make(map[string]error)
19841985 return
19871988 for i, name := range objectNames {
19881989 fullPaths[i] = fmt.Sprintf("/%s/%s", container, name)
19891990 }
1990 return c.doBulkDelete(fullPaths, h)
1991 return c.doBulkDelete(ctx, fullPaths, h)
19911992 }
19921993
19931994 // BulkUploadResult stores results of BulkUpload().
20202021 // See also:
20212022 // * http://docs.openstack.org/trunk/openstack-object-storage/admin/content/object-storage-extract-archive.html
20222023 // * http://docs.rackspace.com/files/api/v1/cf-devguide/content/Extract_Archive-d1e2338.html
2023 func (c *Connection) BulkUpload(uploadPath string, dataStream io.Reader, format string, h Headers) (result BulkUploadResult, err error) {
2024 func (c *Connection) BulkUpload(ctx context.Context, uploadPath string, dataStream io.Reader, format string, h Headers) (result BulkUploadResult, err error) {
20242025 extraHeaders := Headers{"Accept": "application/json"}
20252026 for key, value := range h {
20262027 extraHeaders[key] = value
20272028 }
20282029 // The following code abuses Container parameter intentionally.
20292030 // The best fix might be to rename Container to UploadPath.
2030 resp, headers, err := c.storage(RequestOpts{
2031 resp, headers, err := c.storage(ctx, RequestOpts{
20312032 Container: uploadPath,
20322033 Operation: "PUT",
20332034 Parameters: url.Values{"extract-archive": []string{format}},
20722073 // May return ObjectNotFound.
20732074 //
20742075 // Use headers.ObjectMetadata() to read the metadata in the Headers.
2075 func (c *Connection) Object(container string, objectName string) (info Object, headers Headers, err error) {
2076 func (c *Connection) Object(ctx context.Context, container string, objectName string) (info Object, headers Headers, err error) {
20762077 err = withLORetry(0, func() (Headers, int64, error) {
2077 info, headers, err = c.objectBase(container, objectName)
2078 info, headers, err = c.objectBase(ctx, container, objectName)
20782079 if err != nil {
20792080 return headers, 0, err
20802081 }
20832084 return
20842085 }
20852086
2086 func (c *Connection) objectBase(container string, objectName string) (info Object, headers Headers, err error) {
2087 func (c *Connection) objectBase(ctx context.Context, container string, objectName string) (info Object, headers Headers, err error) {
20872088 var resp *http.Response
2088 resp, headers, err = c.storage(RequestOpts{
2089 resp, headers, err = c.storage(ctx, RequestOpts{
20892090 Container: container,
20902091 ObjectName: objectName,
20912092 Operation: "HEAD",
21552156 // other headers such as Content-Type or CORS headers.
21562157 //
21572158 // May return ObjectNotFound.
2158 func (c *Connection) ObjectUpdate(container string, objectName string, h Headers) error {
2159 _, _, err := c.storage(RequestOpts{
2159 func (c *Connection) ObjectUpdate(ctx context.Context, container string, objectName string, h Headers) error {
2160 _, _, err := c.storage(ctx, RequestOpts{
21602161 Container: container,
21612162 ObjectName: objectName,
21622163 Operation: "POST",
21852186 //
21862187 // You can use this to copy an object to itself - this is the only way
21872188 // to update the content type of an object.
2188 func (c *Connection) ObjectCopy(srcContainer string, srcObjectName string, dstContainer string, dstObjectName string, h Headers) (headers Headers, err error) {
2189 func (c *Connection) ObjectCopy(ctx context.Context, srcContainer string, srcObjectName string, dstContainer string, dstObjectName string, h Headers) (headers Headers, err error) {
21892190 // Meta stuff
21902191 extraHeaders := map[string]string{
21912192 "Destination": urlPathEscape(dstContainer + "/" + dstObjectName),
21932194 for key, value := range h {
21942195 extraHeaders[key] = value
21952196 }
2196 _, headers, err = c.storage(RequestOpts{
2197 _, headers, err = c.storage(ctx, RequestOpts{
21972198 Container: srcContainer,
21982199 ObjectName: srcObjectName,
21992200 Operation: "COPY",
22112212 // All metadata is preserved.
22122213 //
22132214 // The destination container must exist before the copy.
2214 func (c *Connection) ObjectMove(srcContainer string, srcObjectName string, dstContainer string, dstObjectName string) (err error) {
2215 _, err = c.ObjectCopy(srcContainer, srcObjectName, dstContainer, dstObjectName, nil)
2215 func (c *Connection) ObjectMove(ctx context.Context, srcContainer string, srcObjectName string, dstContainer string, dstObjectName string) (err error) {
2216 _, err = c.ObjectCopy(ctx, srcContainer, srcObjectName, dstContainer, dstObjectName, nil)
22162217 if err != nil {
22172218 return
22182219 }
2219 return c.ObjectDelete(srcContainer, srcObjectName)
2220 return c.ObjectDelete(ctx, srcContainer, srcObjectName)
22202221 }
22212222
22222223 // ObjectUpdateContentType updates the content type of an object
22242225 // This is a convenience method which calls ObjectCopy
22252226 //
22262227 // All other metadata is preserved.
2227 func (c *Connection) ObjectUpdateContentType(container string, objectName string, contentType string) (err error) {
2228 func (c *Connection) ObjectUpdateContentType(ctx context.Context, container string, objectName string, contentType string) (err error) {
22282229 h := Headers{"Content-Type": contentType}
2229 _, err = c.ObjectCopy(container, objectName, container, objectName, h)
2230 _, err = c.ObjectCopy(ctx, container, objectName, container, objectName, h)
22302231 return
22312232 }
22322233
22382239 //
22392240 // If the server doesn't support versioning then it will return
22402241 // Forbidden however it will have created both the containers at that point.
2241 func (c *Connection) VersionContainerCreate(current, version string) error {
2242 if err := c.ContainerCreate(version, nil); err != nil {
2242 func (c *Connection) VersionContainerCreate(ctx context.Context, current, version string) error {
2243 if err := c.ContainerCreate(ctx, version, nil); err != nil {
22432244 return err
22442245 }
2245 if err := c.ContainerCreate(current, nil); err != nil {
2246 if err := c.ContainerCreate(ctx, current, nil); err != nil {
22462247 return err
22472248 }
2248 if err := c.VersionEnable(current, version); err != nil {
2249 if err := c.VersionEnable(ctx, current, version); err != nil {
22492250 return err
22502251 }
22512252 return nil
22542255 // VersionEnable enables versioning on the current container with version as the tracking container.
22552256 //
22562257 // May return Forbidden if this isn't supported by the server
2257 func (c *Connection) VersionEnable(current, version string) error {
2258 func (c *Connection) VersionEnable(ctx context.Context, current, version string) error {
22582259 h := Headers{"X-Versions-Location": version}
2259 if err := c.ContainerUpdate(current, h); err != nil {
2260 if err := c.ContainerUpdate(ctx, current, h); err != nil {
22602261 return err
22612262 }
22622263 // Check to see if the header was set properly
2263 _, headers, err := c.Container(current)
2264 _, headers, err := c.Container(ctx, current)
22642265 if err != nil {
22652266 return err
22662267 }
22722273 }
22732274
22742275 // VersionDisable disables versioning on the current container.
2275 func (c *Connection) VersionDisable(current string) error {
2276 func (c *Connection) VersionDisable(ctx context.Context, current string) error {
22762277 h := Headers{"X-Versions-Location": ""}
2277 if err := c.ContainerUpdate(current, h); err != nil {
2278 if err := c.ContainerUpdate(ctx, current, h); err != nil {
22782279 return err
22792280 }
22802281 return nil
22832284 // VersionObjectList returns a list of older versions of the object.
22842285 //
22852286 // Objects are returned in the format <length><object_name>/<timestamp>
2286 func (c *Connection) VersionObjectList(version, object string) ([]string, error) {
2287 func (c *Connection) VersionObjectList(ctx context.Context, version, object string) ([]string, error) {
22872288 opts := &ObjectsOpts{
22882289 // <3-character zero-padded hexadecimal character length><object name>/
22892290 Prefix: fmt.Sprintf("%03x", len(object)) + object + "/",
22902291 }
2291 return c.ObjectNames(version, opts)
2292 }
2292 return c.ObjectNames(ctx, version, opts)
2293 }
55 package swift
66
77 import (
8 "context"
89 "fmt"
910 "io"
1011 "net"
315316 }).Url("/v1.0")
316317 defer server.Finished()
317318
318 err := c.Authenticate()
319 ctx := context.Background()
320 err := c.Authenticate(ctx)
319321 if err != nil {
320322 t.Fatal(err)
321323 }
335337 server.AddCheck(t).Error(401, "DENIED")
336338 defer server.Finished()
337339 c.UnAuthenticate()
338 err := c.Authenticate()
340 err := c.Authenticate(context.Background())
339341 if err != AuthorizationFailed {
340342 t.Fatal("Expecting AuthorizationFailed", err)
341343 }
350352 "X-Storage-Url": PROXY_URL,
351353 })
352354 defer server.Finished()
353 err := c.Authenticate()
355 ctx := context.Background()
356 err := c.Authenticate(ctx)
354357 checkError(t, err, 0, "Response didn't have storage url and auth token")
355358 if c.Authenticated() {
356359 t.Fatal("Expecting not authenticated")
359362 server.AddCheck(t).Out(Headers{
360363 "X-Auth-Token": AUTH_TOKEN,
361364 })
362 err = c.Authenticate()
365 err = c.Authenticate(ctx)
363366 checkError(t, err, 0, "Response didn't have storage url and auth token")
364367 if c.Authenticated() {
365368 t.Fatal("Expecting not authenticated")
366369 }
367370
368371 server.AddCheck(t)
369 err = c.Authenticate()
372 err = c.Authenticate(ctx)
370373 checkError(t, err, 0, "Response didn't have storage url and auth token")
371374 if c.Authenticated() {
372375 t.Fatal("Expecting not authenticated")
376379 "X-Storage-Url": PROXY_URL,
377380 "X-Auth-Token": AUTH_TOKEN,
378381 })
379 err = c.Authenticate()
382 err = c.Authenticate(ctx)
380383 if err != nil {
381384 t.Fatal(err)
382385 }
390393 "User-Agent": DefaultUserAgent,
391394 "X-Auth-Token": AUTH_TOKEN,
392395 }).Tx(rx).Url("/proxy")
393 containers, err := c.ContainerNames(nil)
396 containers, err := c.ContainerNames(context.Background(), nil)
394397 if err != nil {
395398 t.Fatal(err)
396399 }
419422 "Content-Type": "text/plain",
420423 }).Rx("12345")
421424 defer server.Finished()
422 c.ObjectPutBytes("container", "object", []byte{'1', '2', '3', '4', '5'}, "text/plain")
425 c.ObjectPutBytes(context.Background(), "container", "object", []byte{'1', '2', '3', '4', '5'}, "text/plain")
423426 }
424427
425428 func TestInternalObjectPutString(t *testing.T) {
430433 "Content-Type": "text/plain",
431434 }).Rx("12345")
432435 defer server.Finished()
433 c.ObjectPutString("container", "object", "12345", "text/plain")
436 c.ObjectPutString(context.Background(), "container", "object", "12345", "text/plain")
434437 }
435438
436439 func TestSetFromEnv(t *testing.T) {
1414 import (
1515 "archive/tar"
1616 "bytes"
17 "context"
1718 "crypto/md5"
1819 "crypto/rand"
1920 "crypto/tls"
3233 "testing"
3334 "time"
3435
35 "github.com/ncw/swift"
36 "github.com/ncw/swift/swifttest"
36 "github.com/ncw/swift/v2"
37 "github.com/ncw/swift/v2/swifttest"
3738 )
3839
3940 var (
143144 }
144145
145146 func makeConnectionAuth(t *testing.T) (*swift.Connection, func()) {
147 ctx := context.Background()
146148 c, rollback := makeConnection(t)
147 err := c.Authenticate()
149 err := c.Authenticate(ctx)
148150 if err != nil {
149151 t.Fatal("Auth failed", err)
150152 }
152154 }
153155
154156 func makeConnectionWithContainer(t *testing.T) (*swift.Connection, func()) {
157 ctx := context.Background()
155158 c, rollback := makeConnectionAuth(t)
156 err := c.ContainerCreate(CONTAINER, m1.ContainerHeaders())
159 err := c.ContainerCreate(ctx, CONTAINER, m1.ContainerHeaders())
157160 if err != nil {
158161 t.Fatal(err)
159162 }
160163 return c, func() {
161 c.ContainerDelete(CONTAINER)
164 _ = c.ContainerDelete(ctx, CONTAINER)
162165 rollback()
163166 }
164167 }
165168
166169 func makeConnectionWithObject(t *testing.T) (*swift.Connection, func()) {
170 ctx := context.Background()
167171 c, rollback := makeConnectionWithContainer(t)
168 err := c.ObjectPutString(CONTAINER, OBJECT, CONTENTS, "")
172 err := c.ObjectPutString(ctx, CONTAINER, OBJECT, CONTENTS, "")
169173 if err != nil {
170174 t.Fatal(err)
171175 }
172176 return c, func() {
173 c.ObjectDelete(CONTAINER, OBJECT)
177 _ = c.ObjectDelete(ctx, CONTAINER, OBJECT)
174178 rollback()
175179 }
176180 }
177181
178182 func makeConnectionWithObjectHeaders(t *testing.T) (*swift.Connection, func()) {
183 ctx := context.Background()
179184 c, rollback := makeConnectionWithObject(t)
180 err := c.ObjectUpdate(CONTAINER, OBJECT, m1.ObjectHeaders())
185 err := c.ObjectUpdate(ctx, CONTAINER, OBJECT, m1.ObjectHeaders())
181186 if err != nil {
182187 t.Fatal(err)
183188 }
185190 }
186191
187192 func makeConnectionWithVersionsContainer(t *testing.T) (*swift.Connection, func()) {
193 ctx := context.Background()
188194 c, rollback := makeConnectionAuth(t)
189 err := c.VersionContainerCreate(CURRENT_CONTAINER, VERSIONS_CONTAINER)
195 err := c.VersionContainerCreate(ctx, CURRENT_CONTAINER, VERSIONS_CONTAINER)
190196 newRollback := func() {
191 c.ContainerDelete(CURRENT_CONTAINER)
192 c.ContainerDelete(VERSIONS_CONTAINER)
197 _ = c.ContainerDelete(ctx, CURRENT_CONTAINER)
198 _ = c.ContainerDelete(ctx, VERSIONS_CONTAINER)
193199 rollback()
194200 }
195201 if err != nil {
203209 }
204210
205211 func makeConnectionWithVersionsObject(t *testing.T) (*swift.Connection, func()) {
212 ctx := context.Background()
206213 c, rollback := makeConnectionWithVersionsContainer(t)
207 if err := c.ObjectPutString(CURRENT_CONTAINER, OBJECT, CONTENTS, ""); err != nil {
214 if err := c.ObjectPutString(ctx, CURRENT_CONTAINER, OBJECT, CONTENTS, ""); err != nil {
208215 t.Fatal(err)
209216 }
210217 // Version 2
211 if err := c.ObjectPutString(CURRENT_CONTAINER, OBJECT, CONTENTS2, ""); err != nil {
218 if err := c.ObjectPutString(ctx, CURRENT_CONTAINER, OBJECT, CONTENTS2, ""); err != nil {
212219 t.Fatal(err)
213220 }
214221 // Version 3
215 if err := c.ObjectPutString(CURRENT_CONTAINER, OBJECT, CONTENTS2, ""); err != nil {
222 if err := c.ObjectPutString(ctx, CURRENT_CONTAINER, OBJECT, CONTENTS2, ""); err != nil {
216223 t.Fatal(err)
217224 }
218225 return c, func() {
219226 for i := 0; i < 3; i++ {
220 c.ObjectDelete(CURRENT_CONTAINER, OBJECT)
227 _ = c.ObjectDelete(ctx, CURRENT_CONTAINER, OBJECT)
221228 }
222229 rollback()
223230 }
224231 }
225232
226233 func makeConnectionWithSegmentsContainer(t *testing.T) (*swift.Connection, func()) {
234 ctx := context.Background()
227235 c, rollback := makeConnectionWithContainer(t)
228 err := c.ContainerCreate(SEGMENTS_CONTAINER, swift.Headers{})
236 err := c.ContainerCreate(ctx, SEGMENTS_CONTAINER, swift.Headers{})
229237 if err != nil {
230238 t.Fatal(err)
231239 }
232240 return c, func() {
233 err = c.ContainerDelete(SEGMENTS_CONTAINER)
241 err = c.ContainerDelete(ctx, SEGMENTS_CONTAINER)
234242 if err != nil {
235243 t.Fatal(err)
236244 }
239247 }
240248
241249 func makeConnectionWithDLO(t *testing.T) (*swift.Connection, func()) {
250 ctx := context.Background()
242251 c, rollback := makeConnectionWithSegmentsContainer(t)
243252 opts := swift.LargeObjectOpts{
244253 Container: CONTAINER,
245254 ObjectName: OBJECT,
246255 ContentType: "image/jpeg",
247256 }
248 out, err := c.DynamicLargeObjectCreate(&opts)
257 out, err := c.DynamicLargeObjectCreate(ctx, &opts)
249258 if err != nil {
250259 t.Fatal(err)
251260 }
255264 t.Fatal(err)
256265 }
257266 }
258 err = out.Close()
267 err = out.CloseWithContext(ctx)
259268 if err != nil {
260269 t.Error(err)
261270 }
262271 return c, func() {
263 c.DynamicLargeObjectDelete(CONTAINER, OBJECT)
272 _ = c.DynamicLargeObjectDelete(ctx, CONTAINER, OBJECT)
264273 rollback()
265274 }
266275 }
267276
268277 func makeConnectionWithSLO(t *testing.T) (*swift.Connection, func()) {
278 ctx := context.Background()
269279 c, rollback := makeConnectionWithSegmentsContainer(t)
270280 opts := swift.LargeObjectOpts{
271281 Container: CONTAINER,
272282 ObjectName: OBJECT,
273283 ContentType: "image/jpeg",
274284 }
275 out, err := c.StaticLargeObjectCreate(&opts)
285 out, err := c.StaticLargeObjectCreate(ctx, &opts)
276286 if err != nil {
277287 if err == swift.SLONotSupported {
278288 t.Skip("SLO not supported")
286296 t.Fatal(err)
287297 }
288298 }
289 err = out.Close()
299 err = out.CloseWithContext(ctx)
290300 if err != nil {
291301 t.Error(err)
292302 }
293303 return c, func() {
294 c.StaticLargeObjectDelete(CONTAINER, OBJECT)
304 _ = c.StaticLargeObjectDelete(ctx, CONTAINER, OBJECT)
295305 rollback()
296306 }
297307 }
302312 }
303313
304314 func getSwinftInfo(t *testing.T) (info swift.SwiftInfo, err error) {
315 ctx := context.Background()
305316 c, rollback := makeConnectionAuth(t)
306317 defer rollback()
307 return c.QueryInfo()
318 return c.QueryInfo(ctx)
308319 }
309320
310321 func TestTransport(t *testing.T) {
322 ctx := context.Background()
311323 c, rollback := makeConnection(t)
312324 defer rollback()
313325
325337
326338 c.Transport = tr
327339
328 err := c.Authenticate()
340 err := c.Authenticate(ctx)
329341 if err != nil {
330342 t.Fatal("Auth failed", err)
331343 }
336348
337349 // The following Test functions are run in order - this one must come before the others!
338350 func TestV1V2Authenticate(t *testing.T) {
351 ctx := context.Background()
339352 if isV3Api() {
340353 return
341354 }
342355 c, rollback := makeConnection(t)
343356 defer rollback()
344357
345 err := c.Authenticate()
358 err := c.Authenticate(ctx)
346359 if err != nil {
347360 t.Fatal("Auth failed", err)
348361 }
352365 }
353366
354367 func TestV3AuthenticateWithDomainNameAndTenantId(t *testing.T) {
368 ctx := context.Background()
355369 if !isV3Api() {
356370 return
357371 }
364378 c.TenantId = os.Getenv("SWIFT_TENANT_ID")
365379 c.DomainId = ""
366380
367 err := c.Authenticate()
381 err := c.Authenticate(ctx)
368382 if err != nil {
369383 t.Fatal("Auth failed", err)
370384 }
374388 }
375389
376390 func TestV3TrustWithTrustId(t *testing.T) {
391 ctx := context.Background()
377392 if !isV3Api() {
378393 return
379394 }
383398
384399 c.TrustId = os.Getenv("SWIFT_TRUST_ID")
385400
386 err := c.Authenticate()
401 err := c.Authenticate(ctx)
387402 if err != nil {
388403 t.Fatal("Auth failed", err)
389404 }
393408 }
394409
395410 func TestV3AuthenticateWithDomainIdAndTenantId(t *testing.T) {
411 ctx := context.Background()
396412 if !isV3Api() {
397413 return
398414 }
405421 c.TenantId = os.Getenv("SWIFT_TENANT_ID")
406422 c.DomainId = os.Getenv("SWIFT_API_DOMAIN_ID")
407423
408 err := c.Authenticate()
424 err := c.Authenticate(ctx)
409425 if err != nil {
410426 t.Fatal("Auth failed", err)
411427 }
415431 }
416432
417433 func TestV3AuthenticateWithDomainNameAndTenantName(t *testing.T) {
434 ctx := context.Background()
418435 if !isV3Api() {
419436 return
420437 }
427444 c.TenantId = ""
428445 c.DomainId = ""
429446
430 err := c.Authenticate()
447 err := c.Authenticate(ctx)
431448 if err != nil {
432449 t.Fatal("Auth failed", err)
433450 }
437454 }
438455
439456 func TestV3AuthenticateWithDomainIdAndTenantName(t *testing.T) {
457 ctx := context.Background()
440458 if !isV3Api() {
441459 return
442460 }
449467 c.TenantId = ""
450468 c.DomainId = os.Getenv("SWIFT_API_DOMAIN_ID")
451469
452 err := c.Authenticate()
470 err := c.Authenticate(ctx)
453471 if err != nil {
454472 t.Fatal("Auth failed", err)
455473 }
462480 //
463481 // Run with -race to test
464482 func TestAuthenticateRace(t *testing.T) {
483 ctx := context.Background()
465484 c, rollback := makeConnection(t)
466485 defer rollback()
467486 var wg sync.WaitGroup
469488 wg.Add(1)
470489 go func() {
471490 defer wg.Done()
472 err := c.Authenticate()
491 err := c.Authenticate(ctx)
473492 if err != nil {
474493 t.Fatal("Auth failed", err)
475494 }
483502
484503 // Test a connection can be serialized and unserialized with JSON
485504 func TestSerializeConnectionJson(t *testing.T) {
505 ctx := context.Background()
486506 c, rollback := makeConnectionAuth(t)
487507 defer rollback()
488508 serializedConnection, err := json.Marshal(c)
497517 if !c2.Authenticated() {
498518 t.Fatal("Should be authenticated")
499519 }
500 _, _, err = c2.Account()
520 _, _, err = c2.Account(ctx)
501521 if err != nil {
502522 t.Fatalf("Failed to use unserialized connection: %v", err)
503523 }
505525
506526 // Test a connection can be serialized and unserialized with XML
507527 func TestSerializeConnectionXml(t *testing.T) {
528 ctx := context.Background()
508529 c, rollback := makeConnectionAuth(t)
509530 defer rollback()
510531 serializedConnection, err := xml.Marshal(c)
519540 if !c2.Authenticated() {
520541 t.Fatal("Should be authenticated")
521542 }
522 _, _, err = c2.Account()
543 _, _, err = c2.Account(ctx)
523544 if err != nil {
524545 t.Fatalf("Failed to use unserialized connection: %v", err)
525546 }
527548
528549 // Test the reauthentication logic
529550 func TestOnReAuth(t *testing.T) {
551 ctx := context.Background()
530552 c, rollback := makeConnectionAuth(t)
531553 defer rollback()
532554 c.UnAuthenticate()
533 _, _, err := c.Account()
555 _, _, err := c.Account(ctx)
534556 if err != nil {
535557 t.Fatalf("Failed to reauthenticate: %v", err)
536558 }
537559 }
538560
539561 func TestAccount(t *testing.T) {
562 ctx := context.Background()
540563 c, rollback := makeConnectionAuth(t)
541564 defer rollback()
542 info, headers, err := c.Account()
565 info, headers, err := c.Account(ctx)
543566 if err != nil {
544567 t.Fatal(err)
545568 }
571594 }
572595
573596 func TestAccountUpdate(t *testing.T) {
597 ctx := context.Background()
574598 c, rollback := makeConnectionAuth(t)
575599 defer rollback()
576 err := c.AccountUpdate(m1.AccountHeaders())
577 if err != nil {
578 t.Fatal(err)
579 }
580
581 _, headers, err := c.Account()
600 err := c.AccountUpdate(ctx, m1.AccountHeaders())
601 if err != nil {
602 t.Fatal(err)
603 }
604
605 _, headers, err := c.Account(ctx)
582606 if err != nil {
583607 t.Fatal(err)
584608 }
586610 delete(m, "temp-url-key") // remove X-Account-Meta-Temp-URL-Key if set
587611 compareMaps(t, m, map[string]string{"hello": "1", "potato-salad": "2"})
588612
589 err = c.AccountUpdate(m2.AccountHeaders())
590 if err != nil {
591 t.Fatal(err)
592 }
593
594 _, headers, err = c.Account()
613 err = c.AccountUpdate(ctx, m2.AccountHeaders())
614 if err != nil {
615 t.Fatal(err)
616 }
617
618 _, headers, err = c.Account(ctx)
595619 if err != nil {
596620 t.Fatal(err)
597621 }
601625 }
602626
603627 func TestContainerCreate(t *testing.T) {
628 ctx := context.Background()
604629 c, rollback := makeConnectionAuth(t)
605630 defer rollback()
606 err := c.ContainerCreate(CONTAINER, m1.ContainerHeaders())
607 if err != nil {
608 t.Fatal(err)
609 }
610 err = c.ContainerDelete(CONTAINER)
631 err := c.ContainerCreate(ctx, CONTAINER, m1.ContainerHeaders())
632 if err != nil {
633 t.Fatal(err)
634 }
635 err = c.ContainerDelete(ctx, CONTAINER)
611636 if err != nil {
612637 t.Fatal(err)
613638 }
614639 }
615640
616641 func TestContainer(t *testing.T) {
642 ctx := context.Background()
617643 c, rollback := makeConnectionWithContainer(t)
618644 defer rollback()
619 info, headers, err := c.Container(CONTAINER)
645 info, headers, err := c.Container(ctx, CONTAINER)
620646 if err != nil {
621647 t.Fatal(err)
622648 }
633659 }
634660
635661 func TestContainersAll(t *testing.T) {
662 ctx := context.Background()
636663 c, rollback := makeConnectionWithContainer(t)
637664 defer rollback()
638 containers1, err := c.ContainersAll(nil)
639 if err != nil {
640 t.Fatal(err)
641 }
642 containers2, err := c.Containers(nil)
665 containers1, err := c.ContainersAll(ctx, nil)
666 if err != nil {
667 t.Fatal(err)
668 }
669 containers2, err := c.Containers(ctx, nil)
643670 if err != nil {
644671 t.Fatal(err)
645672 }
654681 }
655682
656683 func TestContainersAllWithLimit(t *testing.T) {
684 ctx := context.Background()
657685 c, rollback := makeConnectionWithContainer(t)
658686 defer rollback()
659 containers1, err := c.ContainersAll(&swift.ContainersOpts{Limit: 1})
660 if err != nil {
661 t.Fatal(err)
662 }
663 containers2, err := c.Containers(nil)
687 containers1, err := c.ContainersAll(ctx, &swift.ContainersOpts{Limit: 1})
688 if err != nil {
689 t.Fatal(err)
690 }
691 containers2, err := c.Containers(ctx, nil)
664692 if err != nil {
665693 t.Fatal(err)
666694 }
675703 }
676704
677705 func TestContainerUpdate(t *testing.T) {
706 ctx := context.Background()
678707 c, rollback := makeConnectionWithContainer(t)
679708 defer rollback()
680 err := c.ContainerUpdate(CONTAINER, m2.ContainerHeaders())
681 if err != nil {
682 t.Fatal(err)
683 }
684 _, headers, err := c.Container(CONTAINER)
709 err := c.ContainerUpdate(ctx, CONTAINER, m2.ContainerHeaders())
710 if err != nil {
711 t.Fatal(err)
712 }
713 _, headers, err := c.Container(ctx, CONTAINER)
685714 if err != nil {
686715 t.Fatal(err)
687716 }
689718 }
690719
691720 func TestContainerNames(t *testing.T) {
721 ctx := context.Background()
692722 c, rollback := makeConnectionWithContainer(t)
693723 defer rollback()
694 containers, err := c.ContainerNames(nil)
724 containers, err := c.ContainerNames(ctx, nil)
695725 if err != nil {
696726 t.Fatal(err)
697727 }
708738 }
709739
710740 func TestContainerNamesAll(t *testing.T) {
741 ctx := context.Background()
711742 c, rollback := makeConnectionWithContainer(t)
712743 defer rollback()
713 containers1, err := c.ContainerNamesAll(nil)
714 if err != nil {
715 t.Fatal(err)
716 }
717 containers2, err := c.ContainerNames(nil)
744 containers1, err := c.ContainerNamesAll(ctx, nil)
745 if err != nil {
746 t.Fatal(err)
747 }
748 containers2, err := c.ContainerNames(ctx, nil)
718749 if err != nil {
719750 t.Fatal(err)
720751 }
729760 }
730761
731762 func TestContainerNamesAllWithLimit(t *testing.T) {
763 ctx := context.Background()
732764 c, rollback := makeConnectionWithContainer(t)
733765 defer rollback()
734 containers1, err := c.ContainerNamesAll(&swift.ContainersOpts{Limit: 1})
735 if err != nil {
736 t.Fatal(err)
737 }
738 containers2, err := c.ContainerNames(nil)
766 containers1, err := c.ContainerNamesAll(ctx, &swift.ContainersOpts{Limit: 1})
767 if err != nil {
768 t.Fatal(err)
769 }
770 containers2, err := c.ContainerNames(ctx, nil)
739771 if err != nil {
740772 t.Fatal(err)
741773 }
750782 }
751783
752784 func TestObjectPutString(t *testing.T) {
785 ctx := context.Background()
753786 c, rollback := makeConnectionWithContainer(t)
754787 defer rollback()
755 err := c.ObjectPutString(CONTAINER, OBJECT, CONTENTS, "")
788 err := c.ObjectPutString(ctx, CONTAINER, OBJECT, CONTENTS, "")
756789 if err != nil {
757790 t.Fatal(err)
758791 }
759792 defer func() {
760 err = c.ObjectDelete(CONTAINER, OBJECT)
793 err = c.ObjectDelete(ctx, CONTAINER, OBJECT)
761794 if err != nil {
762795 t.Fatal(err)
763796 }
764797 }()
765798
766 info, _, err := c.Object(CONTAINER, OBJECT)
799 info, _, err := c.Object(ctx, CONTAINER, OBJECT)
767800 if err != nil {
768801 t.Error(err)
769802 }
779812 }
780813
781814 func TestObjectPut(t *testing.T) {
815 ctx := context.Background()
782816 c, rollback := makeConnectionWithContainer(t)
783817 defer rollback()
784818
787821 // Set content size incorrectly - should produce an error
788822 headers["Content-Length"] = strconv.FormatInt(CONTENT_SIZE-1, 10)
789823 contents := bytes.NewBufferString(CONTENTS)
790 h, err := c.ObjectPut(CONTAINER, OBJECT, contents, true, CONTENT_MD5, "text/plain", headers)
824 h, err := c.ObjectPut(ctx, CONTAINER, OBJECT, contents, true, CONTENT_MD5, "text/plain", headers)
791825 if err == nil {
792826 t.Fatal("Expecting error but didn't get one")
793827 }
795829 // Now set content size correctly
796830 contents = bytes.NewBufferString(CONTENTS)
797831 headers["Content-Length"] = strconv.FormatInt(CONTENT_SIZE, 10)
798 h, err = c.ObjectPut(CONTAINER, OBJECT, contents, true, CONTENT_MD5, "text/plain", headers)
832 h, err = c.ObjectPut(ctx, CONTAINER, OBJECT, contents, true, CONTENT_MD5, "text/plain", headers)
799833 if err != nil {
800834 t.Fatal(err)
801835 }
802836 defer func() {
803 err = c.ObjectDelete(CONTAINER, OBJECT)
837 err = c.ObjectDelete(ctx, CONTAINER, OBJECT)
804838 if err != nil {
805839 t.Fatal(err)
806840 }
811845 }
812846
813847 // Fetch object info and compare
814 info, _, err := c.Object(CONTAINER, OBJECT)
848 info, _, err := c.Object(ctx, CONTAINER, OBJECT)
815849 if err != nil {
816850 t.Error(err)
817851 }
827861 }
828862
829863 func TestObjectPutWithReauth(t *testing.T) {
864 ctx := context.Background()
830865 if !swift.IS_AT_LEAST_GO_16 {
831866 return
832867 }
837872 c.AuthToken = "expiredtoken"
838873
839874 r := strings.NewReader(CONTENTS)
840 _, err := c.ObjectPut(CONTAINER, OBJECT, r, true, "", "text/plain", nil)
841 if err != nil {
842 t.Fatal(err)
843 }
844
845 info, _, err := c.Object(CONTAINER, OBJECT)
875 _, err := c.ObjectPut(ctx, CONTAINER, OBJECT, r, true, "", "text/plain", nil)
876 if err != nil {
877 t.Fatal(err)
878 }
879
880 info, _, err := c.Object(ctx, CONTAINER, OBJECT)
846881 if err != nil {
847882 t.Error(err)
848883 }
858893 }
859894
860895 func TestObjectPutStringWithReauth(t *testing.T) {
896 ctx := context.Background()
861897 if !swift.IS_AT_LEAST_GO_16 {
862898 return
863899 }
867903 // Simulate that our auth token expired
868904 c.AuthToken = "expiredtoken"
869905
870 err := c.ObjectPutString(CONTAINER, OBJECT, CONTENTS, "")
871 if err != nil {
872 t.Fatal(err)
873 }
874
875 info, _, err := c.Object(CONTAINER, OBJECT)
906 err := c.ObjectPutString(ctx, CONTAINER, OBJECT, CONTENTS, "")
907 if err != nil {
908 t.Fatal(err)
909 }
910
911 info, _, err := c.Object(ctx, CONTAINER, OBJECT)
876912 if err != nil {
877913 t.Error(err)
878914 }
888924 }
889925
890926 func TestObjectEmpty(t *testing.T) {
927 ctx := context.Background()
891928 c, rollback := makeConnectionWithContainer(t)
892929 defer rollback()
893 err := c.ObjectPutString(CONTAINER, EMPTYOBJECT, "", "")
930 err := c.ObjectPutString(ctx, CONTAINER, EMPTYOBJECT, "", "")
894931 if err != nil {
895932 t.Fatal(err)
896933 }
897934 defer func() {
898 err = c.ObjectDelete(CONTAINER, EMPTYOBJECT)
935 err = c.ObjectDelete(ctx, CONTAINER, EMPTYOBJECT)
899936 if err != nil {
900937 t.Error(err)
901938 }
902939 }()
903940
904 info, _, err := c.Object(CONTAINER, EMPTYOBJECT)
941 info, _, err := c.Object(ctx, CONTAINER, EMPTYOBJECT)
905942 if err != nil {
906943 t.Error(err)
907944 }
917954 }
918955
919956 func TestSymlinkObject(t *testing.T) {
957 ctx := context.Background()
920958 info, err := getSwinftInfo(t)
921959 if err != nil {
922960 t.Fatal(err)
930968 defer rollback()
931969
932970 // write target objects
933 err = c.ObjectPutBytes(CONTAINER, OBJECT, []byte(CONTENTS), "text/potato")
971 err = c.ObjectPutBytes(ctx, CONTAINER, OBJECT, []byte(CONTENTS), "text/potato")
934972 if err != nil {
935973 t.Fatal(err)
936974 }
937975 defer func() {
938 err = c.ObjectDelete(CONTAINER, OBJECT)
976 err = c.ObjectDelete(ctx, CONTAINER, OBJECT)
939977 if err != nil {
940978 t.Error(err)
941979 }
942980 }()
943981
944982 // test dynamic link
945 _, err = c.ObjectSymlinkCreate(CONTAINER, SYMLINK_OBJECT, "", CONTAINER, OBJECT, "")
983 _, err = c.ObjectSymlinkCreate(ctx, CONTAINER, SYMLINK_OBJECT, "", CONTAINER, OBJECT, "")
946984 if err != nil {
947985 t.Fatal(err)
948986 }
949987 defer func() {
950 err = c.ObjectDelete(CONTAINER, SYMLINK_OBJECT)
988 err = c.ObjectDelete(ctx, CONTAINER, SYMLINK_OBJECT)
951989 if err != nil {
952990 t.Error(err)
953991 }
954992 }()
955993
956 md, _, err := c.Object(CONTAINER, SYMLINK_OBJECT)
994 md, _, err := c.Object(ctx, CONTAINER, SYMLINK_OBJECT)
957995 if err != nil {
958996 t.Error(err)
959997 }
9701008 }
9711009
9721010 func TestStaticSymlinkObject(t *testing.T) {
1011 ctx := context.Background()
9731012 info, err := getSwinftInfo(t)
9741013 if err != nil {
9751014 t.Fatal(err)
9881027 defer rollback()
9891028
9901029 // write target objects
991 err = c.ObjectPutBytes(CONTAINER, OBJECT2, []byte(CONTENTS2), "text/tomato")
1030 err = c.ObjectPutBytes(ctx, CONTAINER, OBJECT2, []byte(CONTENTS2), "text/tomato")
9921031 if err != nil {
9931032 t.Fatal(err)
9941033 }
9951034 defer func() {
996 err = c.ObjectDelete(CONTAINER, OBJECT2)
1035 err = c.ObjectDelete(ctx, CONTAINER, OBJECT2)
9971036 if err != nil {
9981037 t.Error(err)
9991038 }
10011040
10021041 // test static link
10031042 // first with the wrong target etag
1004 _, err = c.ObjectSymlinkCreate(CONTAINER, SYMLINK_OBJECT2, "", CONTAINER, OBJECT2, CONTENT_MD5)
1043 _, err = c.ObjectSymlinkCreate(ctx, CONTAINER, SYMLINK_OBJECT2, "", CONTAINER, OBJECT2, CONTENT_MD5)
10051044 if err == nil {
10061045 t.Error("Symlink with wrong target etag should have failed")
10071046 }
10081047
1009 _, err = c.ObjectSymlinkCreate(CONTAINER, SYMLINK_OBJECT2, "", CONTAINER, OBJECT2, CONTENT2_MD5)
1048 _, err = c.ObjectSymlinkCreate(ctx, CONTAINER, SYMLINK_OBJECT2, "", CONTAINER, OBJECT2, CONTENT2_MD5)
10101049 if err != nil {
10111050 t.Fatal(err)
10121051 }
10131052 defer func() {
1014 err = c.ObjectDelete(CONTAINER, SYMLINK_OBJECT2)
1053 err = c.ObjectDelete(ctx, CONTAINER, SYMLINK_OBJECT2)
10151054 if err != nil {
10161055 t.Error(err)
10171056 }
10181057 }()
10191058
1020 md, _, err := c.Object(CONTAINER, SYMLINK_OBJECT2)
1059 md, _, err := c.Object(ctx, CONTAINER, SYMLINK_OBJECT2)
10211060 if err != nil {
10221061 t.Error(err)
10231062 }
10331072 }
10341073
10351074 func TestObjectPutBytes(t *testing.T) {
1075 ctx := context.Background()
10361076 c, rollback := makeConnectionWithContainer(t)
10371077 defer rollback()
1038 err := c.ObjectPutBytes(CONTAINER, OBJECT, []byte(CONTENTS), "")
1078 err := c.ObjectPutBytes(ctx, CONTAINER, OBJECT, []byte(CONTENTS), "")
10391079 if err != nil {
10401080 t.Fatal(err)
10411081 }
10421082 defer func() {
1043 err = c.ObjectDelete(CONTAINER, OBJECT)
1083 err = c.ObjectDelete(ctx, CONTAINER, OBJECT)
10441084 if err != nil {
10451085 t.Error(err)
10461086 }
10471087 }()
10481088
1049 info, _, err := c.Object(CONTAINER, OBJECT)
1089 info, _, err := c.Object(ctx, CONTAINER, OBJECT)
10501090 if err != nil {
10511091 t.Error(err)
10521092 }
10621102 }
10631103
10641104 func TestObjectPutMimeType(t *testing.T) {
1105 ctx := context.Background()
10651106 c, rollback := makeConnectionWithContainer(t)
10661107 defer rollback()
1067 err := c.ObjectPutString(CONTAINER, "test.jpg", CONTENTS, "")
1108 err := c.ObjectPutString(ctx, CONTAINER, "test.jpg", CONTENTS, "")
10681109 if err != nil {
10691110 t.Fatal(err)
10701111 }
10711112 defer func() {
1072 err = c.ObjectDelete(CONTAINER, "test.jpg")
1113 err = c.ObjectDelete(ctx, CONTAINER, "test.jpg")
10731114 if err != nil {
10741115 t.Error(err)
10751116 }
10761117 }()
10771118
1078 info, _, err := c.Object(CONTAINER, "test.jpg")
1119 info, _, err := c.Object(ctx, CONTAINER, "test.jpg")
10791120 if err != nil {
10801121 t.Error(err)
10811122 }
10851126 }
10861127
10871128 func TestObjectCreate(t *testing.T) {
1129 ctx := context.Background()
10881130 c, rollback := makeConnectionWithContainer(t)
10891131 defer rollback()
1090 out, err := c.ObjectCreate(CONTAINER, OBJECT2, true, "", "", nil)
1132 out, err := c.ObjectCreate(ctx, CONTAINER, OBJECT2, true, "", "", nil)
10911133 if err != nil {
10921134 t.Fatal(err)
10931135 }
10941136 defer func() {
1095 err = c.ObjectDelete(CONTAINER, OBJECT2)
1137 err = c.ObjectDelete(ctx, CONTAINER, OBJECT2)
10961138 if err != nil {
10971139 t.Error(err)
10981140 }
11011143 hash := md5.New()
11021144 out2 := io.MultiWriter(out, buf, hash)
11031145 for i := 0; i < 100; i++ {
1104 fmt.Fprintf(out2, "%d %s\n", i, CONTENTS)
1146 _, _ = fmt.Fprintf(out2, "%d %s\n", i, CONTENTS)
11051147 }
11061148 // Ensure Headers fails if called prematurely
11071149 _, err = out.Headers()
11131155 t.Error(err)
11141156 }
11151157 expected := buf.String()
1116 contents, err := c.ObjectGetString(CONTAINER, OBJECT2)
1158 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT2)
11171159 if err != nil {
11181160 t.Error(err)
11191161 }
11371179 }
11381180
11391181 // Now with hash instead
1140 out, err = c.ObjectCreate(CONTAINER, OBJECT2, false, fmt.Sprintf("%x", hash.Sum(nil)), "", nil)
1182 out, err = c.ObjectCreate(ctx, CONTAINER, OBJECT2, false, fmt.Sprintf("%x", hash.Sum(nil)), "", nil)
11411183 if err != nil {
11421184 t.Fatal(err)
11431185 }
11491191 if err != nil {
11501192 t.Error(err)
11511193 }
1152 contents, err = c.ObjectGetString(CONTAINER, OBJECT2)
1194 contents, err = c.ObjectGetString(ctx, CONTAINER, OBJECT2)
11531195 if err != nil {
11541196 t.Error(err)
11551197 }
11581200 }
11591201
11601202 // Now with bad hash
1161 out, err = c.ObjectCreate(CONTAINER, OBJECT2, false, CONTENT_MD5, "", nil)
1203 out, err = c.ObjectCreate(ctx, CONTAINER, OBJECT2, false, CONTENT_MD5, "", nil)
11621204 if err != nil {
11631205 t.Fatal(err)
11641206 }
11651207 // FIXME: work around bug which produces 503 not 422 for empty corrupted files
1166 fmt.Fprintf(out, "Sausage")
1208 _, _ = fmt.Fprintf(out, "Sausage")
11671209 err = out.Close()
11681210 if err != swift.ObjectCorrupted {
11691211 t.Error("Expecting object corrupted not", err)
11711213 }
11721214
11731215 func TestObjectCreateAbort(t *testing.T) {
1216 ctx := context.Background()
11741217 c, rollback := makeConnectionWithContainer(t)
11751218 defer rollback()
11761219
1177 out, err := c.ObjectCreate(CONTAINER, OBJECT2, true, "", "", nil)
1220 out, err := c.ObjectCreate(ctx, CONTAINER, OBJECT2, true, "", "", nil)
11781221 if err != nil {
11791222 t.Fatal(err)
11801223 }
11811224 defer func() {
1182 _ = c.ObjectDelete(CONTAINER, OBJECT2) // Ignore error
1225 _ = c.ObjectDelete(ctx, CONTAINER, OBJECT2) // Ignore error
11831226 }()
11841227
11851228 expectedContents := "foo"
11941237 t.Errorf("Unexpected error %#v", err)
11951238 }
11961239
1197 _, err = c.ObjectGetString(CONTAINER, OBJECT2)
1240 _, err = c.ObjectGetString(ctx, CONTAINER, OBJECT2)
11981241 if err != swift.ObjectNotFound {
11991242 t.Errorf("Unexpected error: %#v", err)
12001243 }
12011244 }
12021245
12031246 func TestObjectGetString(t *testing.T) {
1247 ctx := context.Background()
12041248 c, rollback := makeConnectionWithObject(t)
12051249 defer rollback()
1206 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
1250 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
12071251 if err != nil {
12081252 t.Fatal(err)
12091253 }
12131257 }
12141258
12151259 func TestObjectGetBytes(t *testing.T) {
1260 ctx := context.Background()
12161261 c, rollback := makeConnectionWithObject(t)
12171262 defer rollback()
1218 contents, err := c.ObjectGetBytes(CONTAINER, OBJECT)
1263 contents, err := c.ObjectGetBytes(ctx, CONTAINER, OBJECT)
12191264 if err != nil {
12201265 t.Fatal(err)
12211266 }
12251270 }
12261271
12271272 func TestObjectOpen(t *testing.T) {
1273 ctx := context.Background()
12281274 c, rollback := makeConnectionWithObject(t)
12291275 defer rollback()
1230 file, _, err := c.ObjectOpen(CONTAINER, OBJECT, true, nil)
1276 file, _, err := c.ObjectOpen(ctx, CONTAINER, OBJECT, true, nil)
12311277 if err != nil {
12321278 t.Fatal(err)
12331279 }
12491295 }
12501296
12511297 func TestObjectOpenPartial(t *testing.T) {
1298 ctx := context.Background()
12521299 c, rollback := makeConnectionWithObject(t)
12531300 defer rollback()
1254 file, _, err := c.ObjectOpen(CONTAINER, OBJECT, true, nil)
1301 file, _, err := c.ObjectOpen(ctx, CONTAINER, OBJECT, true, nil)
12551302 if err != nil {
12561303 t.Fatal(err)
12571304 }
12731320 }
12741321
12751322 func TestObjectOpenLength(t *testing.T) {
1323 ctx := context.Background()
12761324 c, rollback := makeConnectionWithObject(t)
12771325 defer rollback()
1278 file, _, err := c.ObjectOpen(CONTAINER, OBJECT, true, nil)
1326 file, _, err := c.ObjectOpen(ctx, CONTAINER, OBJECT, true, nil)
12791327 if err != nil {
12801328 t.Fatal(err)
12811329 }
12821330 // FIXME ideally this would check both branches of the Length() code
1283 n, err := file.Length()
1331 n, err := file.Length(ctx)
12841332 if err != nil {
12851333 t.Fatal(err)
12861334 }
12941342 }
12951343
12961344 func TestObjectOpenNotModified(t *testing.T) {
1345 ctx := context.Background()
12971346 c, rollback := makeConnectionWithObject(t)
12981347 defer rollback()
1299 _, _, err := c.ObjectOpen(CONTAINER, OBJECT, true, swift.Headers{
1348 _, _, err := c.ObjectOpen(ctx, CONTAINER, OBJECT, true, swift.Headers{
13001349 "If-None-Match": CONTENT_MD5,
13011350 })
13021351 if err != swift.NotModified {
13051354 }
13061355
13071356 func TestObjectOpenSeek(t *testing.T) {
1357 ctx := context.Background()
13081358 c, rollback := makeConnectionWithObject(t)
13091359 defer rollback()
13101360
13301380 {2, -4, 1},
13311381 }
13321382
1333 file, _, err := c.ObjectOpen(CONTAINER, OBJECT, true, nil)
1383 file, _, err := c.ObjectOpen(ctx, CONTAINER, OBJECT, true, nil)
13341384 if err != nil {
13351385 t.Fatal(err)
13361386 }
13381388 for _, p := range plan {
13391389 if p.whence >= 0 {
13401390 var result int64
1341 result, err = file.Seek(p.offset, p.whence)
1391 result, err = file.Seek(ctx, p.offset, p.whence)
13421392 if err != nil {
13431393 t.Fatal(err, p)
13441394 }
13711421
13721422 // Test seeking to the end to find the file size
13731423 func TestObjectOpenSeekEnd(t *testing.T) {
1424 ctx := context.Background()
13741425 c, rollback := makeConnectionWithObject(t)
13751426 defer rollback()
1376 file, _, err := c.ObjectOpen(CONTAINER, OBJECT, true, nil)
1377 if err != nil {
1378 t.Fatal(err)
1379 }
1380 n, err := file.Seek(0, 2) // seek to end
1427 file, _, err := c.ObjectOpen(ctx, CONTAINER, OBJECT, true, nil)
1428 if err != nil {
1429 t.Fatal(err)
1430 }
1431 n, err := file.Seek(ctx, 0, 2) // seek to end
13811432 if err != nil {
13821433 t.Fatal(err)
13831434 }
13961447 }
13971448
13981449 // Now seek back to start and check we can read the file
1399 n, err = file.Seek(0, 0) // seek to start
1450 n, err = file.Seek(ctx, 0, 0) // seek to start
14001451 if err != nil {
14011452 t.Fatal(err)
14021453 }
14151466 }
14161467
14171468 func TestObjectUpdate(t *testing.T) {
1469 ctx := context.Background()
14181470 c, rollback := makeConnectionWithObject(t)
14191471 defer rollback()
1420 err := c.ObjectUpdate(CONTAINER, OBJECT, m1.ObjectHeaders())
1472 err := c.ObjectUpdate(ctx, CONTAINER, OBJECT, m1.ObjectHeaders())
14211473 if err != nil {
14221474 t.Fatal(err)
14231475 }
14311483 }
14321484
14331485 func TestObject(t *testing.T) {
1486 ctx := context.Background()
14341487 c, rollback := makeConnectionWithObjectHeaders(t)
14351488 defer rollback()
1436 object, headers, err := c.Object(CONTAINER, OBJECT)
1489 object, headers, err := c.Object(ctx, CONTAINER, OBJECT)
14371490 if err != nil {
14381491 t.Fatal(err)
14391492 }
14451498 }
14461499
14471500 func TestObjectUpdate2(t *testing.T) {
1501 ctx := context.Background()
14481502 c, rollback := makeConnectionWithObjectHeaders(t)
14491503 defer rollback()
1450 err := c.ObjectUpdate(CONTAINER, OBJECT, m2.ObjectHeaders())
1451 if err != nil {
1452 t.Fatal(err)
1453 }
1454 _, headers, err := c.Object(CONTAINER, OBJECT)
1504 err := c.ObjectUpdate(ctx, CONTAINER, OBJECT, m2.ObjectHeaders())
1505 if err != nil {
1506 t.Fatal(err)
1507 }
1508 _, headers, err := c.Object(ctx, CONTAINER, OBJECT)
14551509 if err != nil {
14561510 t.Fatal(err)
14571511 }
14591513 }
14601514
14611515 func TestContainers(t *testing.T) {
1516 ctx := context.Background()
14621517 c, rollback := makeConnectionWithObjectHeaders(t)
14631518 defer rollback()
1464 containers, err := c.Containers(nil)
1519 containers, err := c.Containers(ctx, nil)
14651520 if err != nil {
14661521 t.Fatal(err)
14671522 }
14871542 }
14881543
14891544 func TestObjectNames(t *testing.T) {
1545 ctx := context.Background()
14901546 c, rollback := makeConnectionWithObjectHeaders(t)
14911547 defer rollback()
1492 objects, err := c.ObjectNames(CONTAINER, nil)
1548 objects, err := c.ObjectNames(ctx, CONTAINER, nil)
14931549 if err != nil {
14941550 t.Fatal(err)
14951551 }
14991555 }
15001556
15011557 func TestObjectNamesAll(t *testing.T) {
1558 ctx := context.Background()
15021559 c, rollback := makeConnectionWithObjectHeaders(t)
15031560 defer rollback()
1504 objects, err := c.ObjectNamesAll(CONTAINER, nil)
1561 objects, err := c.ObjectNamesAll(ctx, CONTAINER, nil)
15051562 if err != nil {
15061563 t.Fatal(err)
15071564 }
15111568 }
15121569
15131570 func TestObjectNamesAllWithLimit(t *testing.T) {
1571 ctx := context.Background()
15141572 c, rollback := makeConnectionWithObjectHeaders(t)
15151573 defer rollback()
1516 objects, err := c.ObjectNamesAll(CONTAINER, &swift.ObjectsOpts{Limit: 1})
1574 objects, err := c.ObjectNamesAll(ctx, CONTAINER, &swift.ObjectsOpts{Limit: 1})
15171575 if err != nil {
15181576 t.Fatal(err)
15191577 }
15231581 }
15241582
15251583 func TestObjectsWalk(t *testing.T) {
1584 ctx := context.Background()
15261585 c, rollback := makeConnectionWithObjectHeaders(t)
15271586 defer rollback()
15281587 objects := make([]string, 0)
1529 err := c.ObjectsWalk(container, nil, func(opts *swift.ObjectsOpts) (interface{}, error) {
1530 newObjects, err := c.ObjectNames(CONTAINER, opts)
1588 err := c.ObjectsWalk(ctx, container, nil, func(ctx context.Context, opts *swift.ObjectsOpts) (interface{}, error) {
1589 newObjects, err := c.ObjectNames(ctx, CONTAINER, opts)
15311590 if err == nil {
15321591 objects = append(objects, newObjects...)
15331592 }
15421601 }
15431602
15441603 func TestObjects(t *testing.T) {
1604 ctx := context.Background()
15451605 c, rollback := makeConnectionWithObjectHeaders(t)
15461606 defer rollback()
1547 objects, err := c.Objects(CONTAINER, &swift.ObjectsOpts{Delimiter: '/'})
1607 objects, err := c.Objects(ctx, CONTAINER, &swift.ObjectsOpts{Delimiter: '/'})
15481608 if err != nil {
15491609 t.Fatal(err)
15501610 }
15591619 }
15601620
15611621 func TestObjectsDirectory(t *testing.T) {
1622 ctx := context.Background()
15621623 c, rollback := makeConnectionWithObjectHeaders(t)
15631624 defer rollback()
1564 err := c.ObjectPutString(CONTAINER, "directory", "", "application/directory")
1565 if err != nil {
1566 t.Fatal(err)
1567 }
1568 defer c.ObjectDelete(CONTAINER, "directory")
1625 err := c.ObjectPutString(ctx, CONTAINER, "directory", "", "application/directory")
1626 if err != nil {
1627 t.Fatal(err)
1628 }
1629 defer c.ObjectDelete(ctx, CONTAINER, "directory")
15691630
15701631 // Look for the directory object and check we aren't confusing
15711632 // it with a pseudo directory object
1572 objects, err := c.Objects(CONTAINER, &swift.ObjectsOpts{Delimiter: '/'})
1633 objects, err := c.Objects(ctx, CONTAINER, &swift.ObjectsOpts{Delimiter: '/'})
15731634 if err != nil {
15741635 t.Fatal(err)
15751636 }
15931654 }
15941655
15951656 func TestObjectsPseudoDirectory(t *testing.T) {
1657 ctx := context.Background()
15961658 c, rollback := makeConnectionWithObjectHeaders(t)
15971659 defer rollback()
1598 err := c.ObjectPutString(CONTAINER, "directory/puppy.jpg", "cute puppy", "")
1599 if err != nil {
1600 t.Fatal(err)
1601 }
1602 defer c.ObjectDelete(CONTAINER, "directory/puppy.jpg")
1660 err := c.ObjectPutString(ctx, CONTAINER, "directory/puppy.jpg", "cute puppy", "")
1661 if err != nil {
1662 t.Fatal(err)
1663 }
1664 defer c.ObjectDelete(ctx, CONTAINER, "directory/puppy.jpg")
16031665
16041666 // Look for the pseudo directory
1605 objects, err := c.Objects(CONTAINER, &swift.ObjectsOpts{Delimiter: '/'})
1667 objects, err := c.Objects(ctx, CONTAINER, &swift.ObjectsOpts{Delimiter: '/'})
16061668 if err != nil {
16071669 t.Fatal(err)
16081670 }
16241686 }
16251687
16261688 // Look in the pseudo directory now
1627 objects, err = c.Objects(CONTAINER, &swift.ObjectsOpts{Delimiter: '/', Path: "directory/"})
1689 objects, err = c.Objects(ctx, CONTAINER, &swift.ObjectsOpts{Delimiter: '/', Path: "directory/"})
16281690 if err != nil {
16291691 t.Fatal(err)
16301692 }
16391701 }
16401702
16411703 func TestObjectsAll(t *testing.T) {
1704 ctx := context.Background()
16421705 c, rollback := makeConnectionWithObjectHeaders(t)
16431706 defer rollback()
1644 objects, err := c.ObjectsAll(CONTAINER, nil)
1707 objects, err := c.ObjectsAll(ctx, CONTAINER, nil)
16451708 if err != nil {
16461709 t.Fatal(err)
16471710 }
16511714 }
16521715
16531716 func TestObjectsAllWithLimit(t *testing.T) {
1717 ctx := context.Background()
16541718 c, rollback := makeConnectionWithObjectHeaders(t)
16551719 defer rollback()
1656 objects, err := c.ObjectsAll(CONTAINER, &swift.ObjectsOpts{Limit: 1})
1720 objects, err := c.ObjectsAll(ctx, CONTAINER, &swift.ObjectsOpts{Limit: 1})
16571721 if err != nil {
16581722 t.Fatal(err)
16591723 }
16631727 }
16641728
16651729 func TestObjectNamesWithPath(t *testing.T) {
1730 ctx := context.Background()
16661731 c, rollback := makeConnectionWithObjectHeaders(t)
16671732 defer rollback()
1668 objects, err := c.ObjectNames(CONTAINER, &swift.ObjectsOpts{Delimiter: '/', Path: ""})
1733 objects, err := c.ObjectNames(ctx, CONTAINER, &swift.ObjectsOpts{Delimiter: '/', Path: ""})
16691734 if err != nil {
16701735 t.Fatal(err)
16711736 }
16731738 t.Error("Bad listing with path", objects)
16741739 }
16751740 // fmt.Println(objects)
1676 objects, err = c.ObjectNames(CONTAINER, &swift.ObjectsOpts{Delimiter: '/', Path: "Downloads/"})
1741 objects, err = c.ObjectNames(ctx, CONTAINER, &swift.ObjectsOpts{Delimiter: '/', Path: "Downloads/"})
16771742 if err != nil {
16781743 t.Fatal(err)
16791744 }
16831748 }
16841749
16851750 func TestObjectCopy(t *testing.T) {
1751 ctx := context.Background()
16861752 c, rollback := makeConnectionWithObjectHeaders(t)
16871753 defer rollback()
1688 _, err := c.ObjectCopy(CONTAINER, OBJECT, CONTAINER, OBJECT2, nil)
1689 if err != nil {
1690 t.Fatal(err)
1691 }
1692 err = c.ObjectDelete(CONTAINER, OBJECT2)
1754 _, err := c.ObjectCopy(ctx, CONTAINER, OBJECT, CONTAINER, OBJECT2, nil)
1755 if err != nil {
1756 t.Fatal(err)
1757 }
1758 err = c.ObjectDelete(ctx, CONTAINER, OBJECT2)
16931759 if err != nil {
16941760 t.Fatal(err)
16951761 }
16961762 }
16971763
16981764 func TestObjectCopyDifficultName(t *testing.T) {
1765 ctx := context.Background()
16991766 c, rollback := makeConnectionWithObjectHeaders(t)
17001767 defer rollback()
17011768 const dest = OBJECT + "?param %30%31%32 £100"
1702 _, err := c.ObjectCopy(CONTAINER, OBJECT, CONTAINER, dest, nil)
1703 if err != nil {
1704 t.Fatal(err)
1705 }
1706 err = c.ObjectDelete(CONTAINER, dest)
1769 _, err := c.ObjectCopy(ctx, CONTAINER, OBJECT, CONTAINER, dest, nil)
1770 if err != nil {
1771 t.Fatal(err)
1772 }
1773 err = c.ObjectDelete(ctx, CONTAINER, dest)
17071774 if err != nil {
17081775 t.Fatal(err)
17091776 }
17101777 }
17111778
17121779 func TestObjectCopyWithMetadata(t *testing.T) {
1780 ctx := context.Background()
17131781 c, rollback := makeConnectionWithObjectHeaders(t)
17141782 defer rollback()
17151783 m := swift.Metadata{}
17171785 m["hello"] = "9"
17181786 h := m.ObjectHeaders()
17191787 h["Content-Type"] = "image/jpeg"
1720 _, err := c.ObjectCopy(CONTAINER, OBJECT, CONTAINER, OBJECT2, h)
1788 _, err := c.ObjectCopy(ctx, CONTAINER, OBJECT, CONTAINER, OBJECT2, h)
17211789 if err != nil {
17221790 t.Fatal(err)
17231791 }
17241792 defer func() {
1725 err = c.ObjectDelete(CONTAINER, OBJECT2)
1793 err = c.ObjectDelete(ctx, CONTAINER, OBJECT2)
17261794 if err != nil {
17271795 t.Fatal(err)
17281796 }
17291797 }()
17301798 // Re-read the metadata to see if it is correct
1731 _, headers, err := c.Object(CONTAINER, OBJECT2)
1799 _, headers, err := c.Object(ctx, CONTAINER, OBJECT2)
17321800 if err != nil {
17331801 t.Fatal(err)
17341802 }
17391807 }
17401808
17411809 func TestObjectMove(t *testing.T) {
1810 ctx := context.Background()
17421811 c, rollback := makeConnectionWithObjectHeaders(t)
17431812 defer rollback()
1744 err := c.ObjectMove(CONTAINER, OBJECT, CONTAINER, OBJECT2)
1813 err := c.ObjectMove(ctx, CONTAINER, OBJECT, CONTAINER, OBJECT2)
17451814 if err != nil {
17461815 t.Fatal(err)
17471816 }
17481817 testExistenceAfterDelete(t, c, CONTAINER, OBJECT)
1749 _, _, err = c.Object(CONTAINER, OBJECT2)
1750 if err != nil {
1751 t.Fatal(err)
1752 }
1753
1754 err = c.ObjectMove(CONTAINER, OBJECT2, CONTAINER, OBJECT)
1818 _, _, err = c.Object(ctx, CONTAINER, OBJECT2)
1819 if err != nil {
1820 t.Fatal(err)
1821 }
1822
1823 err = c.ObjectMove(ctx, CONTAINER, OBJECT2, CONTAINER, OBJECT)
17551824 if err != nil {
17561825 t.Fatal(err)
17571826 }
17581827 testExistenceAfterDelete(t, c, CONTAINER, OBJECT2)
1759 _, headers, err := c.Object(CONTAINER, OBJECT)
1828 _, headers, err := c.Object(ctx, CONTAINER, OBJECT)
17601829 if err != nil {
17611830 t.Fatal(err)
17621831 }
17641833 }
17651834
17661835 func TestObjectUpdateContentType(t *testing.T) {
1836 ctx := context.Background()
17671837 c, rollback := makeConnectionWithObjectHeaders(t)
17681838 defer rollback()
1769 err := c.ObjectUpdateContentType(CONTAINER, OBJECT, "text/potato")
1839 err := c.ObjectUpdateContentType(ctx, CONTAINER, OBJECT, "text/potato")
17701840 if err != nil {
17711841 t.Fatal(err)
17721842 }
17731843 // Re-read the metadata to see if it is correct
1774 _, headers, err := c.Object(CONTAINER, OBJECT)
1844 _, headers, err := c.Object(ctx, CONTAINER, OBJECT)
17751845 if err != nil {
17761846 t.Fatal(err)
17771847 }
17821852 }
17831853
17841854 func TestVersionContainerCreate(t *testing.T) {
1855 ctx := context.Background()
17851856 c, rollback := makeConnectionAuth(t)
17861857 defer rollback()
1787 err := c.VersionContainerCreate(CURRENT_CONTAINER, VERSIONS_CONTAINER)
1858 err := c.VersionContainerCreate(ctx, CURRENT_CONTAINER, VERSIONS_CONTAINER)
17881859 defer func() {
1789 c.ContainerDelete(CURRENT_CONTAINER)
1790 c.ContainerDelete(VERSIONS_CONTAINER)
1860 _ = c.ContainerDelete(ctx, CURRENT_CONTAINER)
1861 _ = c.ContainerDelete(ctx, VERSIONS_CONTAINER)
17911862 }()
17921863 if err != nil {
17931864 if err == swift.Forbidden {
17991870 }
18001871
18011872 func TestVersionObjectAdd(t *testing.T) {
1873 ctx := context.Background()
18021874 c, rollback := makeConnectionWithVersionsContainer(t)
18031875 defer rollback()
18041876 if skipVersionTests {
18061878 return
18071879 }
18081880 // Version 1
1809 if err := c.ObjectPutString(CURRENT_CONTAINER, OBJECT, CONTENTS, ""); err != nil {
1881 if err := c.ObjectPutString(ctx, CURRENT_CONTAINER, OBJECT, CONTENTS, ""); err != nil {
18101882 t.Fatal(err)
18111883 }
18121884 defer func() {
1813 err := c.ObjectDelete(CURRENT_CONTAINER, OBJECT)
1885 err := c.ObjectDelete(ctx, CURRENT_CONTAINER, OBJECT)
18141886 if err != nil {
18151887 t.Fatal(err)
18161888 }
18171889 }()
1818 if contents, err := c.ObjectGetString(CURRENT_CONTAINER, OBJECT); err != nil {
1890 if contents, err := c.ObjectGetString(ctx, CURRENT_CONTAINER, OBJECT); err != nil {
18191891 t.Fatal(err)
18201892 } else if contents != CONTENTS {
18211893 t.Error("Contents wrong")
18221894 }
18231895
18241896 // Version 2
1825 if err := c.ObjectPutString(CURRENT_CONTAINER, OBJECT, CONTENTS2, ""); err != nil {
1897 if err := c.ObjectPutString(ctx, CURRENT_CONTAINER, OBJECT, CONTENTS2, ""); err != nil {
18261898 t.Fatal(err)
18271899 }
18281900 defer func() {
1829 err := c.ObjectDelete(CURRENT_CONTAINER, OBJECT)
1901 err := c.ObjectDelete(ctx, CURRENT_CONTAINER, OBJECT)
18301902 if err != nil {
18311903 t.Fatal(err)
18321904 }
18331905 }()
1834 if contents, err := c.ObjectGetString(CURRENT_CONTAINER, OBJECT); err != nil {
1906 if contents, err := c.ObjectGetString(ctx, CURRENT_CONTAINER, OBJECT); err != nil {
18351907 t.Fatal(err)
18361908 } else if contents != CONTENTS2 {
18371909 t.Error("Contents wrong")
18381910 }
18391911
18401912 // Version 3
1841 if err := c.ObjectPutString(CURRENT_CONTAINER, OBJECT, CONTENTS2, ""); err != nil {
1913 if err := c.ObjectPutString(ctx, CURRENT_CONTAINER, OBJECT, CONTENTS2, ""); err != nil {
18421914 t.Fatal(err)
18431915 }
18441916 defer func() {
1845 err := c.ObjectDelete(CURRENT_CONTAINER, OBJECT)
1917 err := c.ObjectDelete(ctx, CURRENT_CONTAINER, OBJECT)
18461918 if err != nil {
18471919 t.Fatal(err)
18481920 }
18501922 }
18511923
18521924 func TestVersionObjectList(t *testing.T) {
1925 ctx := context.Background()
18531926 c, rollback := makeConnectionWithVersionsObject(t)
18541927 defer rollback()
18551928 if skipVersionTests {
18561929 t.Log("Server doesn't support Versions - skipping test")
18571930 return
18581931 }
1859 list, err := c.VersionObjectList(VERSIONS_CONTAINER, OBJECT)
1932 list, err := c.VersionObjectList(ctx, VERSIONS_CONTAINER, OBJECT)
18601933 if err != nil {
18611934 t.Fatal(err)
18621935 }
18671940 }
18681941
18691942 func TestVersionObjectDelete(t *testing.T) {
1943 ctx := context.Background()
18701944 c, rollback := makeConnectionWithVersionsObject(t)
18711945 defer rollback()
18721946 if skipVersionTests {
18741948 return
18751949 }
18761950 // Delete Version 3
1877 if err := c.ObjectDelete(CURRENT_CONTAINER, OBJECT); err != nil {
1951 if err := c.ObjectDelete(ctx, CURRENT_CONTAINER, OBJECT); err != nil {
18781952 t.Fatal(err)
18791953 }
18801954
18811955 // Delete Version 2
1882 if err := c.ObjectDelete(CURRENT_CONTAINER, OBJECT); err != nil {
1956 if err := c.ObjectDelete(ctx, CURRENT_CONTAINER, OBJECT); err != nil {
18831957 t.Fatal(err)
18841958 }
18851959
18861960 // Contents should be reverted to Version 1
1887 if contents, err := c.ObjectGetString(CURRENT_CONTAINER, OBJECT); err != nil {
1961 if contents, err := c.ObjectGetString(ctx, CURRENT_CONTAINER, OBJECT); err != nil {
18881962 t.Fatal(err)
18891963 } else if contents != CONTENTS {
18901964 t.Error("Contents wrong")
18921966 }
18931967
18941968 func TestVersionDeleteContent(t *testing.T) {
1969 ctx := context.Background()
18951970 c, rollback := makeConnectionWithVersionsObject(t)
18961971 defer rollback()
18971972 if skipVersionTests {
18991974 return
19001975 }
19011976 // Delete Version 3
1902 if err := c.ObjectDelete(CURRENT_CONTAINER, OBJECT); err != nil {
1977 if err := c.ObjectDelete(ctx, CURRENT_CONTAINER, OBJECT); err != nil {
19031978 t.Fatal(err)
19041979 }
19051980 // Delete Version 2
1906 if err := c.ObjectDelete(CURRENT_CONTAINER, OBJECT); err != nil {
1981 if err := c.ObjectDelete(ctx, CURRENT_CONTAINER, OBJECT); err != nil {
19071982 t.Fatal(err)
19081983 }
19091984 // Delete Version 1
1910 if err := c.ObjectDelete(CURRENT_CONTAINER, OBJECT); err != nil {
1911 t.Fatal(err)
1912 }
1913 if err := c.ObjectDelete(CURRENT_CONTAINER, OBJECT); err != swift.ObjectNotFound {
1985 if err := c.ObjectDelete(ctx, CURRENT_CONTAINER, OBJECT); err != nil {
1986 t.Fatal(err)
1987 }
1988 if err := c.ObjectDelete(ctx, CURRENT_CONTAINER, OBJECT); err != swift.ObjectNotFound {
19141989 t.Fatalf("Expecting Object not found error, got: %v", err)
19151990 }
19161991 }
19181993 // Check for non existence after delete
19191994 // May have to do it a few times to wait for swift to be consistent.
19201995 func testExistenceAfterDelete(t *testing.T, c *swift.Connection, container, object string) {
1996 ctx := context.Background()
19211997 for i := 10; i <= 0; i-- {
1922 _, _, err := c.Object(container, object)
1998 _, _, err := c.Object(ctx, container, object)
19231999 if err == swift.ObjectNotFound {
19242000 break
19252001 }
19312007 }
19322008
19332009 func TestObjectDelete(t *testing.T) {
2010 ctx := context.Background()
19342011 c, rollback := makeConnectionWithObject(t)
19352012 defer rollback()
1936 err := c.ObjectDelete(CONTAINER, OBJECT)
2013 err := c.ObjectDelete(ctx, CONTAINER, OBJECT)
19372014 if err != nil {
19382015 t.Fatal(err)
19392016 }
19402017 testExistenceAfterDelete(t, c, CONTAINER, OBJECT)
1941 err = c.ObjectDelete(CONTAINER, OBJECT)
2018 err = c.ObjectDelete(ctx, CONTAINER, OBJECT)
19422019 if err != swift.ObjectNotFound {
19432020 t.Fatal("Expecting Object not found", err)
19442021 }
19452022 }
19462023
19472024 func TestBulkDelete(t *testing.T) {
2025 ctx := context.Background()
19482026 c, rollback := makeConnectionWithContainer(t)
19492027 defer rollback()
1950 result, err := c.BulkDelete(CONTAINER, []string{OBJECT})
2028 result, err := c.BulkDelete(ctx, CONTAINER, []string{OBJECT})
19512029 if err == swift.Forbidden {
19522030 t.Log("Server doesn't support BulkDelete - skipping test")
19532031 return
19612039 if result.NumberDeleted != 0 {
19622040 t.Error("Expected 0, actual:", result.NumberDeleted)
19632041 }
1964 err = c.ObjectPutString(CONTAINER, OBJECT, CONTENTS, "")
1965 if err != nil {
1966 t.Fatal(err)
1967 }
1968 result, err = c.BulkDelete(CONTAINER, []string{OBJECT2, OBJECT})
2042 err = c.ObjectPutString(ctx, CONTAINER, OBJECT, CONTENTS, "")
2043 if err != nil {
2044 t.Fatal(err)
2045 }
2046 result, err = c.BulkDelete(ctx, CONTAINER, []string{OBJECT2, OBJECT})
19692047 if err != nil {
19702048 t.Fatal(err)
19712049 }
19792057 }
19802058
19812059 func TestBulkUpload(t *testing.T) {
2060 ctx := context.Background()
19822061 c, rollback := makeConnectionWithContainer(t)
19832062 defer rollback()
19842063 buffer := new(bytes.Buffer)
20032082 t.Fatal(err)
20042083 }
20052084
2006 result, err := c.BulkUpload(CONTAINER, buffer, swift.UploadTar, nil)
2085 result, err := c.BulkUpload(ctx, CONTAINER, buffer, swift.UploadTar, nil)
20072086 if err == swift.Forbidden {
20082087 t.Log("Server doesn't support BulkUpload - skipping test")
20092088 return
20122091 t.Fatal(err)
20132092 }
20142093 defer func() {
2015 err = c.ObjectDelete(CONTAINER, OBJECT)
2016 if err != nil {
2017 t.Fatal(err)
2018 }
2019 err = c.ObjectDelete(CONTAINER, OBJECT2)
2094 err = c.ObjectDelete(ctx, CONTAINER, OBJECT)
2095 if err != nil {
2096 t.Fatal(err)
2097 }
2098 err = c.ObjectDelete(ctx, CONTAINER, OBJECT2)
20202099 if err != nil {
20212100 t.Fatal(err)
20222101 }
20262105 }
20272106 t.Log("Errors:", result.Errors)
20282107
2029 _, _, err = c.Object(CONTAINER, OBJECT)
2108 _, _, err = c.Object(ctx, CONTAINER, OBJECT)
20302109 if err != nil {
20312110 t.Error("Expecting object to be found")
20322111 }
2033 _, _, err = c.Object(CONTAINER, OBJECT2)
2112 _, _, err = c.Object(ctx, CONTAINER, OBJECT2)
20342113 if err != nil {
20352114 t.Error("Expecting object to be found")
20362115 }
20372116 }
20382117
20392118 func TestObjectDifficultName(t *testing.T) {
2119 ctx := context.Background()
20402120 c, rollback := makeConnectionWithContainer(t)
20412121 defer rollback()
20422122 const name = `hello? sausage/êé/Hello, 世界/ " ' @ < > & ?/`
2043 err := c.ObjectPutString(CONTAINER, name, CONTENTS, "")
2123 err := c.ObjectPutString(ctx, CONTAINER, name, CONTENTS, "")
20442124 if err != nil {
20452125 t.Fatal(err)
20462126 }
20472127 defer func() {
2048 err = c.ObjectDelete(CONTAINER, name)
2128 err = c.ObjectDelete(ctx, CONTAINER, name)
20492129 if err != nil {
20502130 t.Fatal(err)
20512131 }
20522132 }()
2053 objects, err := c.ObjectNamesAll(CONTAINER, nil)
2133 objects, err := c.ObjectNamesAll(ctx, CONTAINER, nil)
20542134 if err != nil {
20552135 t.Error(err)
20562136 }
20672147 }
20682148
20692149 func TestTempUrl(t *testing.T) {
2150 ctx := context.Background()
20702151 c, rollback := makeConnectionWithContainer(t)
20712152 defer rollback()
2072 err := c.ObjectPutBytes(CONTAINER, OBJECT, []byte(CONTENTS), "")
2153 err := c.ObjectPutBytes(ctx, CONTAINER, OBJECT, []byte(CONTENTS), "")
20732154 if err != nil {
20742155 t.Fatal(err)
20752156 }
20762157 defer func() {
2077 err = c.ObjectDelete(CONTAINER, OBJECT)
2158 err = c.ObjectDelete(ctx, CONTAINER, OBJECT)
20782159 if err != nil {
20792160 t.Fatal(err)
20802161 }
20822163
20832164 m := swift.Metadata{}
20842165 m["temp-url-key"] = SECRET_KEY
2085 err = c.AccountUpdate(m.AccountHeaders())
2166 err = c.AccountUpdate(ctx, m.AccountHeaders())
20862167 if err != nil {
20872168 t.Fatal(err)
20882169 }
21162197 }
21172198
21182199 func TestQueryInfo(t *testing.T) {
2200 ctx := context.Background()
21192201 c, rollback := makeConnectionAuth(t)
21202202 defer rollback()
2121 infos, err := c.QueryInfo()
2203 infos, err := c.QueryInfo(ctx)
21222204 if err != nil {
21232205 t.Log("Server doesn't support querying info")
21242206 return
21292211 }
21302212
21312213 func TestDLOCreate(t *testing.T) {
2214 ctx := context.Background()
21322215 c, rollback := makeConnectionWithSegmentsContainer(t)
21332216 defer rollback()
21342217
21372220 ObjectName: OBJECT,
21382221 ContentType: "image/jpeg",
21392222 }
2140 out, err := c.DynamicLargeObjectCreate(&opts)
2223 out, err := c.DynamicLargeObjectCreate(ctx, &opts)
21412224 if err != nil {
21422225 t.Fatal(err)
21432226 }
21442227 defer func() {
2145 err = c.DynamicLargeObjectDelete(CONTAINER, OBJECT)
2228 err = c.DynamicLargeObjectDelete(ctx, CONTAINER, OBJECT)
21462229 if err != nil {
21472230 t.Fatal(err)
21482231 }
21562239 t.Fatal(err)
21572240 }
21582241 }
2159 err = out.Close()
2242 err = out.CloseWithContext(ctx)
21602243 if err != nil {
21612244 t.Error(err)
21622245 }
21632246 expected := buf.String()
2164 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
2247 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
21652248 if err != nil {
21662249 t.Error(err)
21672250 }
21682251 if contents != expected {
21692252 t.Errorf("Contents wrong, expected %q, got: %q", expected, contents)
21702253 }
2171 info, _, err := c.Object(CONTAINER, OBJECT)
2254 info, _, err := c.Object(ctx, CONTAINER, OBJECT)
21722255 if err != nil {
21732256 t.Fatal(err)
21742257 }
21812264 }
21822265
21832266 func TestDLOInsert(t *testing.T) {
2267 ctx := context.Background()
21842268 c, rollback := makeConnectionWithDLO(t)
21852269 defer rollback()
21862270 opts := swift.LargeObjectOpts{
21892273 CheckHash: true,
21902274 ContentType: "image/jpeg",
21912275 }
2192 out, err := c.DynamicLargeObjectCreateFile(&opts)
2276 out, err := c.DynamicLargeObjectCreateFile(ctx, &opts)
21932277 if err != nil {
21942278 t.Fatal(err)
21952279 }
22002284 if err != nil {
22012285 t.Fatal(err)
22022286 }
2203 fmt.Fprintf(buf, "\n%d %s\n", 1, CONTENTS)
2204 err = out.Close()
2287 _, _ = fmt.Fprintf(buf, "\n%d %s\n", 1, CONTENTS)
2288 err = out.CloseWithContext(ctx)
22052289 if err != nil {
22062290 t.Error(err)
22072291 }
22082292 expected := buf.String()
2209 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
2293 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
22102294 if err != nil {
22112295 t.Error(err)
22122296 }
22162300 }
22172301
22182302 func TestDLOAppend(t *testing.T) {
2303 ctx := context.Background()
22192304 c, rollback := makeConnectionWithDLO(t)
22202305 defer rollback()
22212306 opts := swift.LargeObjectOpts{
22252310 CheckHash: true,
22262311 ContentType: "image/jpeg",
22272312 }
2228 out, err := c.DynamicLargeObjectCreateFile(&opts)
2229 if err != nil {
2230 t.Fatal(err)
2231 }
2232
2233 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
2313 out, err := c.DynamicLargeObjectCreateFile(ctx, &opts)
2314 if err != nil {
2315 t.Fatal(err)
2316 }
2317
2318 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
22342319 buf := bytes.NewBuffer([]byte(contents))
22352320 multi := io.MultiWriter(buf, out)
22362321 for i := 0; i < 2; i++ {
22392324 t.Fatal(err)
22402325 }
22412326 }
2242 err = out.Close()
2327 err = out.CloseWithContext(ctx)
22432328 if err != nil {
22442329 t.Error(err)
22452330 }
22462331 expected := buf.String()
2247 contents, err = c.ObjectGetString(CONTAINER, OBJECT)
2332 contents, err = c.ObjectGetString(ctx, CONTAINER, OBJECT)
22482333 if err != nil {
22492334 t.Error(err)
22502335 }
22542339 }
22552340
22562341 func TestDLOTruncate(t *testing.T) {
2342 ctx := context.Background()
22572343 c, rollback := makeConnectionWithDLO(t)
22582344 defer rollback()
22592345 opts := swift.LargeObjectOpts{
22632349 CheckHash: true,
22642350 ContentType: "image/jpeg",
22652351 }
2266 out, err := c.DynamicLargeObjectCreateFile(&opts)
2352 out, err := c.DynamicLargeObjectCreateFile(ctx, &opts)
22672353 if err != nil {
22682354 t.Fatal(err)
22692355 }
22742360 if err != nil {
22752361 t.Fatal(err)
22762362 }
2277 err = out.Close()
2363 err = out.CloseWithContext(ctx)
22782364 if err != nil {
22792365 t.Error(err)
22802366 }
22812367 expected := buf.String()
2282 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
2368 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
22832369 if err != nil {
22842370 t.Error(err)
22852371 }
22892375 }
22902376
22912377 func TestDLOMove(t *testing.T) {
2378 ctx := context.Background()
22922379 c, rollback := makeConnectionWithDLO(t)
22932380 defer rollback()
2294 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
2295 if err != nil {
2296 t.Fatal(err)
2297 }
2298
2299 err = c.DynamicLargeObjectMove(CONTAINER, OBJECT, CONTAINER, OBJECT2)
2381 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
2382 if err != nil {
2383 t.Fatal(err)
2384 }
2385
2386 err = c.DynamicLargeObjectMove(ctx, CONTAINER, OBJECT, CONTAINER, OBJECT2)
23002387 if err != nil {
23012388 t.Fatal(err)
23022389 }
23032390 defer func() {
2304 err = c.DynamicLargeObjectDelete(CONTAINER, OBJECT2)
2391 err = c.DynamicLargeObjectDelete(ctx, CONTAINER, OBJECT2)
23052392 if err != nil {
23062393 t.Fatal(err)
23072394 }
23082395 }()
23092396
2310 contents2, err := c.ObjectGetString(CONTAINER, OBJECT2)
2397 contents2, err := c.ObjectGetString(ctx, CONTAINER, OBJECT2)
23112398 if err != nil {
23122399 t.Fatal(err)
23132400 }
23182405 }
23192406
23202407 func TestDLONoSegmentContainer(t *testing.T) {
2408 ctx := context.Background()
23212409 c, rollback := makeConnectionWithDLO(t)
23222410 defer rollback()
23232411 opts := swift.LargeObjectOpts{
23262414 ContentType: "image/jpeg",
23272415 SegmentContainer: CONTAINER,
23282416 }
2329 out, err := c.DynamicLargeObjectCreate(&opts)
2417 out, err := c.DynamicLargeObjectCreate(ctx, &opts)
23302418 if err != nil {
23312419 t.Fatal(err)
23322420 }
23392427 t.Fatal(err)
23402428 }
23412429 }
2342 err = out.Close()
2430 err = out.CloseWithContext(ctx)
23432431 if err != nil {
23442432 t.Error(err)
23452433 }
23462434 expected := buf.String()
2347 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
2435 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
23482436 if err != nil {
23492437 t.Error(err)
23502438 }
23542442 }
23552443
23562444 func TestDLOCreateMissingSegmentsInList(t *testing.T) {
2445 ctx := context.Background()
23572446 c, rollback := makeConnectionWithContainer(t)
23582447 defer rollback()
23592448
23682457 w.Header().Set(k, v[0])
23692458 }
23702459 w.WriteHeader(recorder.Code)
2371 w.Write([]byte("null\n"))
2460 _, _ = w.Write([]byte("null\n"))
23722461 })
23732462 defer srv.UnsetOverride(listURL)
23742463
23752464 headers := swift.Headers{}
2376 err := c.ContainerCreate(SEGMENTS_CONTAINER, headers)
2465 err := c.ContainerCreate(ctx, SEGMENTS_CONTAINER, headers)
23772466 if err != nil {
23782467 t.Fatal(err)
23792468 }
23802469 defer func() {
2381 err = c.ContainerDelete(SEGMENTS_CONTAINER)
2470 err = c.ContainerDelete(ctx, SEGMENTS_CONTAINER)
23822471 if err != nil {
23832472 t.Fatal(err)
23842473 }
23892478 ObjectName: OBJECT,
23902479 ContentType: "image/jpeg",
23912480 }
2392 out, err := c.DynamicLargeObjectCreate(&opts)
2481 out, err := c.DynamicLargeObjectCreate(ctx, &opts)
23932482 if err != nil {
23942483 t.Fatal(err)
23952484 }
23962485 defer func() {
2397 err = c.DynamicLargeObjectDelete(CONTAINER, OBJECT)
2486 err = c.DynamicLargeObjectDelete(ctx, CONTAINER, OBJECT)
23982487 if err != nil {
23992488 t.Fatal(err)
24002489 }
24082497 t.Fatal(err)
24092498 }
24102499 }
2411 err = out.Close()
2500 err = out.CloseWithContext(ctx)
24122501 if err != nil {
24132502 t.Error(err)
24142503 }
24152504 expected := buf.String()
2416 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
2505 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
24172506 if err != nil {
24182507 t.Error(err)
24192508 }
24232512 }
24242513
24252514 func TestDLOCreateIncorrectSize(t *testing.T) {
2515 ctx := context.Background()
24262516 c, rollback := makeConnectionWithContainer(t)
24272517 defer rollback()
24282518
24452535 }
24462536 }
24472537 w.WriteHeader(recorder.Code)
2448 w.Write(recorder.Body.Bytes())
2538 _, _ = w.Write(recorder.Body.Bytes())
24492539 })
24502540 defer srv.UnsetOverride(listURL)
24512541
24522542 headers := swift.Headers{}
2453 err := c.ContainerCreate(SEGMENTS_CONTAINER, headers)
2543 err := c.ContainerCreate(ctx, SEGMENTS_CONTAINER, headers)
24542544 if err != nil {
24552545 t.Fatal(err)
24562546 }
24572547 defer func() {
2458 err = c.ContainerDelete(SEGMENTS_CONTAINER)
2548 err = c.ContainerDelete(ctx, SEGMENTS_CONTAINER)
24592549 if err != nil {
24602550 t.Fatal(err)
24612551 }
24662556 ObjectName: OBJECT,
24672557 ContentType: "image/jpeg",
24682558 }
2469 out, err := c.DynamicLargeObjectCreate(&opts)
2559 out, err := c.DynamicLargeObjectCreate(ctx, &opts)
24702560 if err != nil {
24712561 t.Fatal(err)
24722562 }
24732563 defer func() {
2474 err = c.DynamicLargeObjectDelete(CONTAINER, OBJECT)
2564 err = c.DynamicLargeObjectDelete(ctx, CONTAINER, OBJECT)
24752565 if err != nil {
24762566 t.Fatal(err)
24772567 }
24842574 t.Fatal(err)
24852575 }
24862576 }
2487 err = out.Close()
2577 err = out.CloseWithContext(ctx)
24882578 if err != nil {
24892579 t.Error(err)
24902580 }
24922582 t.Errorf("Unexpected HEAD requests count, expected %d, got: %d", expectedHeadCount, headCount)
24932583 }
24942584 expected := buf.String()
2495 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
2585 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
24962586 if err != nil {
24972587 t.Error(err)
24982588 }
25022592 }
25032593
25042594 func TestDLOConcurrentWrite(t *testing.T) {
2595 ctx := context.Background()
25052596 c, rollback := makeConnectionWithSegmentsContainer(t)
25062597 defer rollback()
25072598
25162607 ObjectName: objName,
25172608 ContentType: "image/jpeg",
25182609 }
2519 out, err := c.DynamicLargeObjectCreate(&opts)
2610 out, err := c.DynamicLargeObjectCreate(ctx, &opts)
25202611 if err != nil {
25212612 t.Fatal(err)
25222613 }
25232614 defer func() {
2524 err = c.DynamicLargeObjectDelete(CONTAINER, objName)
2615 err = c.DynamicLargeObjectDelete(ctx, CONTAINER, objName)
25252616 if err != nil {
25262617 t.Fatal(err)
25272618 }
25432634 t.Fatalf("expected to write %d, got: %d", chunkSize, n)
25442635 }
25452636 }
2546 err = out.Close()
2637 err = out.CloseWithContext(ctx)
25472638 if err != nil {
25482639 t.Error(err)
25492640 }
25502641 expected := buf.String()
2551 contents, err := c.ObjectGetString(CONTAINER, objName)
2642 contents, err := c.ObjectGetString(ctx, CONTAINER, objName)
25522643 if err != nil {
25532644 t.Error(err)
25542645 }
25692660 }
25702661
25712662 func TestDLOSegmentation(t *testing.T) {
2663 ctx := context.Background()
25722664 c, rollback := makeConnectionWithSegmentsContainer(t)
25732665 defer rollback()
25742666
25812673 }
25822674
25832675 testSegmentation(t, c, func() swift.LargeObjectFile {
2584 out, err := c.DynamicLargeObjectCreate(&opts)
2676 out, err := c.DynamicLargeObjectCreate(ctx, &opts)
25852677 if err != nil {
25862678 t.Fatal(err)
25872679 }
26242716 }
26252717
26262718 func TestDLOSegmentationBuffered(t *testing.T) {
2719 ctx := context.Background()
26272720 c, rollback := makeConnectionWithSegmentsContainer(t)
26282721 defer rollback()
26292722
26352728 }
26362729
26372730 testSegmentation(t, c, func() swift.LargeObjectFile {
2638 out, err := c.DynamicLargeObjectCreate(&opts)
2731 out, err := c.DynamicLargeObjectCreate(ctx, &opts)
26392732 if err != nil {
26402733 t.Fatal(err)
26412734 }
26782771 }
26792772
26802773 func TestSLOCreate(t *testing.T) {
2774 ctx := context.Background()
26812775 c, rollback := makeConnectionWithSegmentsContainer(t)
26822776 defer rollback()
26832777
26862780 ObjectName: OBJECT,
26872781 ContentType: "image/jpeg",
26882782 }
2689 out, err := c.StaticLargeObjectCreate(&opts)
2783 out, err := c.StaticLargeObjectCreate(ctx, &opts)
26902784 if err != nil {
26912785 if err == swift.SLONotSupported {
26922786 t.Skip("SLO not supported")
26952789 t.Fatal(err)
26962790 }
26972791 defer func() {
2698 err = c.StaticLargeObjectDelete(CONTAINER, OBJECT)
2792 err = c.StaticLargeObjectDelete(ctx, CONTAINER, OBJECT)
26992793 if err != nil {
27002794 t.Fatal(err)
27012795 }
27092803 t.Fatal(err)
27102804 }
27112805 }
2712 err = out.Close()
2806 err = out.CloseWithContext(ctx)
27132807 if err != nil {
27142808 t.Error(err)
27152809 }
27162810 expected := buf.String()
2717 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
2811 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
27182812 if err != nil {
27192813 t.Error(err)
27202814 }
27212815 if contents != expected {
27222816 t.Errorf("Contents wrong, expected %q, got: %q", expected, contents)
27232817 }
2724 info, _, err := c.Object(CONTAINER, OBJECT)
2818 info, _, err := c.Object(ctx, CONTAINER, OBJECT)
27252819 if err != nil {
27262820 t.Fatal(err)
27272821 }
27342828 }
27352829
27362830 func TestSLOInsert(t *testing.T) {
2831 ctx := context.Background()
27372832 c, rollback := makeConnectionWithSLO(t)
27382833 defer rollback()
27392834 opts := swift.LargeObjectOpts{
27412836 ObjectName: OBJECT,
27422837 ContentType: "image/jpeg",
27432838 }
2744 out, err := c.StaticLargeObjectCreateFile(&opts)
2839 out, err := c.StaticLargeObjectCreateFile(ctx, &opts)
27452840 if err != nil {
27462841 t.Fatal(err)
27472842 }
27522847 if err != nil {
27532848 t.Fatal(err)
27542849 }
2755 fmt.Fprintf(buf, "\n%d %s\n", 1, CONTENTS)
2756 err = out.Close()
2850 _, _ = fmt.Fprintf(buf, "\n%d %s\n", 1, CONTENTS)
2851 err = out.CloseWithContext(ctx)
27572852 if err != nil {
27582853 t.Error(err)
27592854 }
27602855 expected := buf.String()
2761 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
2856 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
27622857 if err != nil {
27632858 t.Error(err)
27642859 }
27682863 }
27692864
27702865 func TestSLOAppend(t *testing.T) {
2866 ctx := context.Background()
27712867 c, rollback := makeConnectionWithSLO(t)
27722868 defer rollback()
27732869 opts := swift.LargeObjectOpts{
27772873 CheckHash: true,
27782874 ContentType: "image/jpeg",
27792875 }
2780 out, err := c.StaticLargeObjectCreateFile(&opts)
2781 if err != nil {
2782 t.Fatal(err)
2783 }
2784
2785 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
2876 out, err := c.StaticLargeObjectCreateFile(ctx, &opts)
2877 if err != nil {
2878 t.Fatal(err)
2879 }
2880
2881 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
27862882 buf := bytes.NewBuffer([]byte(contents))
27872883 multi := io.MultiWriter(buf, out)
27882884 for i := 0; i < 2; i++ {
27912887 t.Fatal(err)
27922888 }
27932889 }
2794 err = out.Close()
2890 err = out.CloseWithContext(ctx)
27952891 if err != nil {
27962892 t.Error(err)
27972893 }
27982894 expected := buf.String()
2799 contents, err = c.ObjectGetString(CONTAINER, OBJECT)
2895 contents, err = c.ObjectGetString(ctx, CONTAINER, OBJECT)
28002896 if err != nil {
28012897 t.Error(err)
28022898 }
28062902 }
28072903
28082904 func TestSLOMove(t *testing.T) {
2905 ctx := context.Background()
28092906 c, rollback := makeConnectionWithSLO(t)
28102907 defer rollback()
2811 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
2812 if err != nil {
2813 t.Fatal(err)
2814 }
2815
2816 err = c.StaticLargeObjectMove(CONTAINER, OBJECT, CONTAINER, OBJECT2)
2908 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
2909 if err != nil {
2910 t.Fatal(err)
2911 }
2912
2913 err = c.StaticLargeObjectMove(ctx, CONTAINER, OBJECT, CONTAINER, OBJECT2)
28172914 if err != nil {
28182915 t.Fatal(err)
28192916 }
28202917 defer func() {
2821 err = c.StaticLargeObjectDelete(CONTAINER, OBJECT2)
2918 err = c.StaticLargeObjectDelete(ctx, CONTAINER, OBJECT2)
28222919 if err != nil {
28232920 t.Fatal(err)
28242921 }
28252922 }()
28262923
2827 contents2, err := c.ObjectGetString(CONTAINER, OBJECT2)
2924 contents2, err := c.ObjectGetString(ctx, CONTAINER, OBJECT2)
28282925 if err != nil {
28292926 t.Fatal(err)
28302927 }
28352932 }
28362933
28372934 func TestSLONoSegmentContainer(t *testing.T) {
2935 ctx := context.Background()
28382936 c, rollback := makeConnectionWithSLO(t)
28392937 defer rollback()
28402938
28442942 ContentType: "image/jpeg",
28452943 SegmentContainer: CONTAINER,
28462944 }
2847 out, err := c.StaticLargeObjectCreate(&opts)
2945 out, err := c.StaticLargeObjectCreate(ctx, &opts)
28482946 if err != nil {
28492947 t.Fatal(err)
28502948 }
28572955 t.Fatal(err)
28582956 }
28592957 }
2860 err = out.Close()
2958 err = out.CloseWithContext(ctx)
28612959 if err != nil {
28622960 t.Error(err)
28632961 }
28642962 expected := buf.String()
2865 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
2963 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
28662964 if err != nil {
28672965 t.Error(err)
28682966 }
28702968 t.Errorf("Contents wrong, expected %q, got: %q", expected, contents)
28712969 }
28722970
2873 err = c.StaticLargeObjectDelete(CONTAINER, OBJECT)
2971 err = c.StaticLargeObjectDelete(ctx, CONTAINER, OBJECT)
28742972 if err != nil {
28752973 t.Fatal(err)
28762974 }
28772975 }
28782976
28792977 func TestSLOMinChunkSize(t *testing.T) {
2978 ctx := context.Background()
28802979 c, rollback := makeConnectionWithSegmentsContainer(t)
28812980 defer rollback()
28822981 if srv == nil {
28852984 }
28862985
28872986 srv.SetOverride("/info", func(w http.ResponseWriter, r *http.Request, recorder *httptest.ResponseRecorder) {
2888 w.Write([]byte(`{"slo": {"min_segment_size": 4}}`))
2987 _, _ = w.Write([]byte(`{"slo": {"min_segment_size": 4}}`))
28892988 })
28902989 defer srv.UnsetOverride("/info")
2891 c.QueryInfo()
2990 _, _ = c.QueryInfo(ctx)
28922991
28932992 opts := swift.LargeObjectOpts{
28942993 Container: CONTAINER,
29002999 }
29013000
29023001 testSLOSegmentation(t, c, func() swift.LargeObjectFile {
2903 out, err := c.StaticLargeObjectCreate(&opts)
3002 out, err := c.StaticLargeObjectCreate(ctx, &opts)
29043003 if err != nil {
29053004 t.Fatal(err)
29063005 }
29093008 }
29103009
29113010 func TestSLOSegmentation(t *testing.T) {
3011 ctx := context.Background()
29123012 c, rollback := makeConnectionWithSegmentsContainer(t)
29133013 defer rollback()
29143014 opts := swift.LargeObjectOpts{
29203020 NoBuffer: true,
29213021 }
29223022 testSLOSegmentation(t, c, func() swift.LargeObjectFile {
2923 out, err := c.StaticLargeObjectCreate(&opts)
3023 out, err := c.StaticLargeObjectCreate(ctx, &opts)
29243024 if err != nil {
29253025 if err == swift.SLONotSupported {
29263026 t.Skip("SLO not supported")
29323032 }
29333033
29343034 func TestSLOSegmentationBuffered(t *testing.T) {
3035 ctx := context.Background()
29353036 c, rollback := makeConnectionWithSegmentsContainer(t)
29363037 defer rollback()
29373038 opts := swift.LargeObjectOpts{
29423043 MinChunkSize: 4,
29433044 }
29443045 testSegmentation(t, c, func() swift.LargeObjectFile {
2945 out, err := c.StaticLargeObjectCreate(&opts)
3046 out, err := c.StaticLargeObjectCreate(ctx, &opts)
29463047 if err != nil {
29473048 if err == swift.SLONotSupported {
29483049 t.Skip("SLO not supported")
30343135 }
30353136
30363137 func testSegmentation(t *testing.T, c *swift.Connection, createObj func() swift.LargeObjectFile, testCases []segmentTest) {
3138 ctx := context.Background()
30373139 var err error
30383140 runTestCase := func(tCase segmentTest) {
30393141 out := createObj()
30403142 defer func() {
3041 err = c.LargeObjectDelete(CONTAINER, OBJECT)
3143 err = c.LargeObjectDelete(ctx, CONTAINER, OBJECT)
30423144 if err != nil {
30433145 t.Fatal(err)
30443146 }
30553157 }
30563158 }
30573159 }
3058 err = out.Close()
3160 err = out.CloseWithContext(ctx)
30593161 if err != nil {
30603162 t.Error(err)
30613163 }
3062 contents, err := c.ObjectGetString(CONTAINER, OBJECT)
3164 contents, err := c.ObjectGetString(ctx, CONTAINER, OBJECT)
30633165 if err != nil {
30643166 t.Error(err)
30653167 }
30663168 if contents != tCase.expectedValue {
30673169 t.Errorf("Contents wrong, expected %q, got: %q", tCase.expectedValue, contents)
30683170 }
3069 container, objects, err := c.LargeObjectGetSegments(CONTAINER, OBJECT)
3171 container, objects, err := c.LargeObjectGetSegments(ctx, CONTAINER, OBJECT)
30703172 if err != nil {
30713173 t.Error(err)
30723174 }
30733175 if container != SEGMENTS_CONTAINER {
30743176 t.Errorf("Segments container wrong, expected %q, got: %q", SEGMENTS_CONTAINER, container)
30753177 }
3076 _, headers, err := c.Object(CONTAINER, OBJECT)
3178 _, headers, err := c.Object(ctx, CONTAINER, OBJECT)
30773179 if err != nil {
30783180 t.Fatal(err)
30793181 }
30803182 if headers.IsLargeObjectSLO() {
30813183 var info swift.SwiftInfo
3082 info, err = c.QueryInfo()
3184 info, err = c.QueryInfo(ctx)
30833185 if err != nil {
30843186 t.Fatal(err)
30853187 }
30913193 var segContents []string
30923194 for _, obj := range objects {
30933195 var value string
3094 value, err = c.ObjectGetString(SEGMENTS_CONTAINER, obj.Name)
3196 value, err = c.ObjectGetString(ctx, SEGMENTS_CONTAINER, obj.Name)
30953197 if err != nil {
30963198 t.Error(err)
30973199 }
31073209 }
31083210
31093211 func TestContainerDelete(t *testing.T) {
3212 ctx := context.Background()
31103213 c, rollback := makeConnectionWithContainer(t)
31113214 defer rollback()
3112 err := c.ContainerDelete(CONTAINER)
3113 if err != nil {
3114 t.Fatal(err)
3115 }
3116 err = c.ContainerDelete(CONTAINER)
3215 err := c.ContainerDelete(ctx, CONTAINER)
3216 if err != nil {
3217 t.Fatal(err)
3218 }
3219 err = c.ContainerDelete(ctx, CONTAINER)
31173220 if err != swift.ContainerNotFound {
31183221 t.Fatal("Expecting container not found", err)
31193222 }
3120 _, _, err = c.Container(CONTAINER)
3223 _, _, err = c.Container(ctx, CONTAINER)
31213224 if err != swift.ContainerNotFound {
31223225 t.Fatal("Expecting container not found", err)
31233226 }
31243227 }
31253228
31263229 func TestUnAuthenticate(t *testing.T) {
3230 ctx := context.Background()
31273231 c, rollback := makeConnectionAuth(t)
31283232 defer rollback()
31293233 c.UnAuthenticate()
31313235 t.Fatal("Shouldn't be authenticated")
31323236 }
31333237 // Test re-authenticate
3134 err := c.Authenticate()
3238 err := c.Authenticate(ctx)
31353239 if err != nil {
31363240 t.Fatal("ReAuth failed", err)
31373241 }