blob: 1622ff7cfce5e10f5499f0970b223cfdb8cd4ab9 [file] [log] [blame]
Jon Perritt816d2a02014-03-11 20:49:46 -05001package objects
2
3import (
4 "fmt"
Jon Perritt8c93a302014-09-28 22:35:57 -05005 "io"
6 "time"
Ash Wilson604320e2014-09-10 16:02:28 -04007
8 "github.com/racker/perigee"
9 "github.com/rackspace/gophercloud"
Ash Wilsonca6f7562014-09-16 15:43:54 -040010 "github.com/rackspace/gophercloud/pagination"
Jon Perritt816d2a02014-03-11 20:49:46 -050011)
12
Jon Perritt8c93a302014-09-28 22:35:57 -050013// ListOpts is a structure that holds parameters for listing objects.
14type ListOpts struct {
15 Full bool
16 Limit int `q:"limit"`
17 Marker string `q:"marker"`
18 EndMarker string `q:"end_marker"`
19 Format string `q:"format"`
20 Prefix string `q:"prefix"`
21 Delimiter [1]byte `q:"delimiter"`
22 Path string `q:"path"`
Ash Wilsonca6f7562014-09-16 15:43:54 -040023}
24
Jon Perritt816d2a02014-03-11 20:49:46 -050025// List is a function that retrieves all objects in a container. It also returns the details
26// for the container. To extract only the object information or names, pass the ListResult
Jon Perritteb575642014-04-24 15:16:31 -050027// response to the ExtractInfo or ExtractNames function, respectively.
Jon Perritt8c93a302014-09-28 22:35:57 -050028func List(c *gophercloud.ServiceClient, containerName string, opts ListOpts) pagination.Pager {
Ash Wilsonca6f7562014-09-16 15:43:54 -040029 var headers map[string]string
Jon Perritt816d2a02014-03-11 20:49:46 -050030
Jon Perritt8c93a302014-09-28 22:35:57 -050031 query, err := gophercloud.BuildQueryString(opts)
32 if err != nil {
33 fmt.Printf("Error building query string: %v", err)
34 return pagination.Pager{Err: err}
35 }
Jon Perritt816d2a02014-03-11 20:49:46 -050036
37 if !opts.Full {
Jon Perrittfdac6e52014-09-29 19:43:45 -050038 headers = map[string]string{"Accept": "text/plain", "Content-Type": "text/plain"}
Ash Wilsonca6f7562014-09-16 15:43:54 -040039 }
40
41 createPage := func(r pagination.LastHTTPResponse) pagination.Page {
Jon Perritt8c93a302014-09-28 22:35:57 -050042 p := ObjectPage{pagination.MarkerPageBase{LastHTTPResponse: r}}
Ash Wilsonca6f7562014-09-16 15:43:54 -040043 p.MarkerPageBase.Owner = p
44 return p
Jon Perritt816d2a02014-03-11 20:49:46 -050045 }
46
Jon Perritt8c93a302014-09-28 22:35:57 -050047 url := containerURL(c, containerName) + query
Ash Wilsonca6f7562014-09-16 15:43:54 -040048 pager := pagination.NewPager(c, url, createPage)
49 pager.Headers = headers
50 return pager
Jon Perritt816d2a02014-03-11 20:49:46 -050051}
52
Jon Perritt8c93a302014-09-28 22:35:57 -050053// DownloadOpts is a structure that holds parameters for downloading an object.
54type DownloadOpts struct {
55 IfMatch string `h:"If-Match"`
56 IfModifiedSince time.Time `h:"If-Modified-Since"`
57 IfNoneMatch string `h:"If-None-Match"`
58 IfUnmodifiedSince time.Time `h:"If-Unmodified-Since"`
59 Range string `h:"Range"`
60 Expires string `q:"expires"`
61 MultipartManifest string `q:"multipart-manifest"`
62 Signature string `q:"signature"`
63}
64
Jon Perritt816d2a02014-03-11 20:49:46 -050065// Download is a function that retrieves the content and metadata for an object.
Jon Perritteb575642014-04-24 15:16:31 -050066// To extract just the content, pass the DownloadResult response to the ExtractContent
Jon Perritt816d2a02014-03-11 20:49:46 -050067// function.
Jon Perritt8c93a302014-09-28 22:35:57 -050068func Download(c *gophercloud.ServiceClient, containerName, objectName string, opts DownloadOpts) DownloadResult {
69 var dr DownloadResult
70
Ash Wilson604320e2014-09-10 16:02:28 -040071 h := c.Provider.AuthenticatedHeaders()
Jon Perritt816d2a02014-03-11 20:49:46 -050072
Jon Perritt8c93a302014-09-28 22:35:57 -050073 headers, err := gophercloud.BuildHeaders(opts)
74 if err != nil {
75 dr.Err = err
76 return dr
77 }
78
79 for k, v := range headers {
Jon Perritt816d2a02014-03-11 20:49:46 -050080 h[k] = v
81 }
82
Jon Perritt8c93a302014-09-28 22:35:57 -050083 query, err := gophercloud.BuildQueryString(opts)
84 if err != nil {
85 dr.Err = err
86 return dr
87 }
Jon Perritt816d2a02014-03-11 20:49:46 -050088
Jon Perritt8c93a302014-09-28 22:35:57 -050089 url := objectURL(c, containerName, objectName) + query
Jon Perritt816d2a02014-03-11 20:49:46 -050090 resp, err := perigee.Request("GET", url, perigee.Options{
Jon Perritt816d2a02014-03-11 20:49:46 -050091 MoreHeaders: h,
Ash Wilsone47ea9e2014-09-10 16:03:44 -040092 OkCodes: []int{200},
Jon Perritt816d2a02014-03-11 20:49:46 -050093 })
Jon Perritt8c93a302014-09-28 22:35:57 -050094 dr.Err = err
95 dr.Resp = &resp.HttpResponse
96 return dr
97}
98
99// CreateOpts is a structure that holds parameters for creating an object.
100type CreateOpts struct {
101 Metadata map[string]string
102 ContentDisposition string `h:"Content-Disposition"`
103 ContentEncoding string `h:"Content-Encoding"`
104 ContentLength int `h:"Content-Length"`
105 ContentType string `h:"Content-Type"`
106 CopyFrom string `h:"X-Copy-From"`
107 DeleteAfter int `h:"X-Delete-After"`
108 DeleteAt int `h:"X-Delete-At"`
109 DetectContentType string `h:"X-Detect-Content-Type"`
110 ETag string `h:"ETag"`
111 IfNoneMatch string `h:"If-None-Match"`
112 ObjectManifest string `h:"X-Object-Manifest"`
113 TransferEncoding string `h:"Transfer-Encoding"`
114 Expires string `q:"expires"`
115 MultipartManifest string `q:"multiple-manifest"`
116 Signature string `q:"signature"`
Jon Perritt816d2a02014-03-11 20:49:46 -0500117}
118
119// Create is a function that creates a new object or replaces an existing object.
Jon Perritt8c93a302014-09-28 22:35:57 -0500120func Create(c *gophercloud.ServiceClient, containerName, objectName string, content io.Reader, opts CreateOpts) error {
Jon Perritt816d2a02014-03-11 20:49:46 -0500121 var reqBody []byte
122
Ash Wilson604320e2014-09-10 16:02:28 -0400123 h := c.Provider.AuthenticatedHeaders()
Jon Perritt816d2a02014-03-11 20:49:46 -0500124
Jon Perritt8c93a302014-09-28 22:35:57 -0500125 headers, err := gophercloud.BuildHeaders(opts)
126 if err != nil {
127 return nil
128 }
129
130 for k, v := range headers {
Jon Perritt816d2a02014-03-11 20:49:46 -0500131 h[k] = v
132 }
133
134 for k, v := range opts.Metadata {
135 h["X-Object-Meta-"+k] = v
136 }
137
Jon Perritt8c93a302014-09-28 22:35:57 -0500138 query, err := gophercloud.BuildQueryString(opts)
139 if err != nil {
140 return err
141 }
Jon Perritt816d2a02014-03-11 20:49:46 -0500142
Jon Perritt816d2a02014-03-11 20:49:46 -0500143 if content != nil {
Jon Perritt884e0312014-08-14 17:25:38 -0500144 reqBody = make([]byte, 0)
Ash Wilson604320e2014-09-10 16:02:28 -0400145 _, err := content.Read(reqBody)
Jon Perritt816d2a02014-03-11 20:49:46 -0500146 if err != nil {
147 return err
148 }
149 }
150
Jon Perritt8c93a302014-09-28 22:35:57 -0500151 url := objectURL(c, containerName, objectName) + query
152 _, err = perigee.Request("PUT", url, perigee.Options{
Jon Perritt816d2a02014-03-11 20:49:46 -0500153 ReqBody: reqBody,
154 MoreHeaders: h,
Ash Wilsone47ea9e2014-09-10 16:03:44 -0400155 OkCodes: []int{201},
Jon Perritt816d2a02014-03-11 20:49:46 -0500156 })
157 return err
158}
159
Jon Perritt8c93a302014-09-28 22:35:57 -0500160// CopyOpts is a structure that holds parameters for copying one object to another.
161type CopyOpts struct {
162 Metadata map[string]string
163 ContentDisposition string `h:"Content-Disposition"`
164 ContentEncoding string `h:"Content-Encoding"`
165 ContentType string `h:"Content-Type"`
166 Destination string `h:"Destination,required"`
167}
168
Jon Perritt816d2a02014-03-11 20:49:46 -0500169// Copy is a function that copies one object to another.
Jon Perritt8c93a302014-09-28 22:35:57 -0500170func Copy(c *gophercloud.ServiceClient, containerName, objectName string, opts CopyOpts) error {
Ash Wilson604320e2014-09-10 16:02:28 -0400171 h := c.Provider.AuthenticatedHeaders()
Jon Perritt816d2a02014-03-11 20:49:46 -0500172
Jon Perritt8c93a302014-09-28 22:35:57 -0500173 headers, err := gophercloud.BuildHeaders(opts)
174 if err != nil {
175 return err
Jon Perritt816d2a02014-03-11 20:49:46 -0500176 }
Jon Perritt8c93a302014-09-28 22:35:57 -0500177 for k, v := range headers {
Jon Perritt816d2a02014-03-11 20:49:46 -0500178 h[k] = v
179 }
180
181 for k, v := range opts.Metadata {
182 h["X-Object-Meta-"+k] = v
183 }
184
Jon Perritt8c93a302014-09-28 22:35:57 -0500185 url := objectURL(c, containerName, objectName)
186 _, err = perigee.Request("COPY", url, perigee.Options{
187 MoreHeaders: h,
188 OkCodes: []int{201},
189 })
190 return err
191}
192
193// DeleteOpts is a structure that holds parameters for deleting an object.
194type DeleteOpts struct {
195 MultipartManifest string `q:"multipart-manifest"`
196}
197
198// Delete is a function that deletes an object.
199func Delete(c *gophercloud.ServiceClient, containerName, objectName string, opts DeleteOpts) error {
200 h := c.Provider.AuthenticatedHeaders()
201
202 query, err := gophercloud.BuildQueryString(opts)
203 if err != nil {
204 return err
205 }
206
207 url := objectURL(c, containerName, objectName) + query
208 _, err = perigee.Request("DELETE", url, perigee.Options{
209 MoreHeaders: h,
210 OkCodes: []int{204},
211 })
212 return err
213}
214
215// GetOpts is a structure that holds parameters for getting an object's metadata.
216type GetOpts struct {
217 Expires string `q:"expires"`
218 Signature string `q:"signature"`
219}
220
221// Get is a function that retrieves the metadata of an object. To extract just the custom
222// metadata, pass the GetResult response to the ExtractMetadata function.
223func Get(c *gophercloud.ServiceClient, containerName, objectName string, opts GetOpts) GetResult {
224 var gr GetResult
225 query, err := gophercloud.BuildQueryString(opts)
226 if err != nil {
227 gr.Err = err
228 return gr
229 }
230
231 url := objectURL(c, containerName, objectName) + query
232 resp, err := perigee.Request("HEAD", url, perigee.Options{
233 MoreHeaders: c.Provider.AuthenticatedHeaders(),
234 OkCodes: []int{200, 204},
235 })
236 gr.Err = err
237 gr.Resp = &resp.HttpResponse
238 return gr
239}
240
241// UpdateOpts is a structure that holds parameters for updating, creating, or deleting an
242// object's metadata.
243type UpdateOpts struct {
244 Metadata map[string]string
245 ContentDisposition string `h:"Content-Disposition"`
246 ContentEncoding string `h:"Content-Encoding"`
247 ContentType string `h:"Content-Type"`
248 DeleteAfter int `h:"X-Delete-After"`
249 DeleteAt int `h:"X-Delete-At"`
250 DetectContentType bool `h:"X-Detect-Content-Type"`
251}
252
253// Update is a function that creates, updates, or deletes an object's metadata.
254func Update(c *gophercloud.ServiceClient, containerName, objectName string, opts UpdateOpts) error {
255 h := c.Provider.AuthenticatedHeaders()
256
257 headers, err := gophercloud.BuildHeaders(opts)
258 if err != nil {
259 return nil
260 }
261
262 for k, v := range headers {
263 h[k] = v
264 }
265
266 for k, v := range opts.Metadata {
267 h["X-Object-Meta-"+k] = v
268 }
269
270 url := objectURL(c, containerName, objectName)
271 _, err = perigee.Request("POST", url, perigee.Options{
Jon Perritt816d2a02014-03-11 20:49:46 -0500272 MoreHeaders: h,
Ash Wilsone47ea9e2014-09-10 16:03:44 -0400273 OkCodes: []int{202},
Jon Perritt816d2a02014-03-11 20:49:46 -0500274 })
275 return err
276}