blob: 900290cfb682ecb4e6f42ab2b7a37d468aa01fd1 [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 Perrittde47eac2014-09-30 15:34:17 -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 Perrittde47eac2014-09-30 15:34:17 -050031 url := containerURL(c, containerName)
32 if opts != nil {
33 query, err := gophercloud.BuildQueryString(opts)
34 if err != nil {
35 fmt.Printf("Error building query string: %v", err)
36 return pagination.Pager{Err: err}
37 }
38 url += query.String()
Jon Perritt816d2a02014-03-11 20:49:46 -050039
Jon Perrittde47eac2014-09-30 15:34:17 -050040 if !opts.Full {
41 headers = map[string]string{"Accept": "text/plain", "Content-Type": "text/plain"}
42 }
Ash Wilsonca6f7562014-09-16 15:43:54 -040043 }
44
45 createPage := func(r pagination.LastHTTPResponse) pagination.Page {
Jon Perritt8c93a302014-09-28 22:35:57 -050046 p := ObjectPage{pagination.MarkerPageBase{LastHTTPResponse: r}}
Ash Wilsonca6f7562014-09-16 15:43:54 -040047 p.MarkerPageBase.Owner = p
48 return p
Jon Perritt816d2a02014-03-11 20:49:46 -050049 }
50
Ash Wilsonca6f7562014-09-16 15:43:54 -040051 pager := pagination.NewPager(c, url, createPage)
52 pager.Headers = headers
53 return pager
Jon Perritt816d2a02014-03-11 20:49:46 -050054}
55
Jon Perritt8c93a302014-09-28 22:35:57 -050056// DownloadOpts is a structure that holds parameters for downloading an object.
57type DownloadOpts struct {
58 IfMatch string `h:"If-Match"`
59 IfModifiedSince time.Time `h:"If-Modified-Since"`
60 IfNoneMatch string `h:"If-None-Match"`
61 IfUnmodifiedSince time.Time `h:"If-Unmodified-Since"`
62 Range string `h:"Range"`
63 Expires string `q:"expires"`
64 MultipartManifest string `q:"multipart-manifest"`
65 Signature string `q:"signature"`
66}
67
Jon Perritt816d2a02014-03-11 20:49:46 -050068// Download is a function that retrieves the content and metadata for an object.
Jon Perritteb575642014-04-24 15:16:31 -050069// To extract just the content, pass the DownloadResult response to the ExtractContent
Jon Perritt816d2a02014-03-11 20:49:46 -050070// function.
Jon Perrittde47eac2014-09-30 15:34:17 -050071func Download(c *gophercloud.ServiceClient, containerName, objectName string, opts *DownloadOpts) DownloadResult {
Jon Perritt8c93a302014-09-28 22:35:57 -050072 var dr DownloadResult
73
Jon Perrittde47eac2014-09-30 15:34:17 -050074 url := objectURL(c, containerName, objectName)
Ash Wilson604320e2014-09-10 16:02:28 -040075 h := c.Provider.AuthenticatedHeaders()
Jon Perritt816d2a02014-03-11 20:49:46 -050076
Jon Perrittde47eac2014-09-30 15:34:17 -050077 if opts != nil {
78 headers, err := gophercloud.BuildHeaders(opts)
79 if err != nil {
80 dr.Err = err
81 return dr
82 }
83
84 for k, v := range headers {
85 h[k] = v
86 }
87
88 query, err := gophercloud.BuildQueryString(opts)
89 if err != nil {
90 dr.Err = err
91 return dr
92 }
93 url += query.String()
Jon Perritt8c93a302014-09-28 22:35:57 -050094 }
95
Jon Perritt816d2a02014-03-11 20:49:46 -050096 resp, err := perigee.Request("GET", url, perigee.Options{
Jon Perritt816d2a02014-03-11 20:49:46 -050097 MoreHeaders: h,
Ash Wilsone47ea9e2014-09-10 16:03:44 -040098 OkCodes: []int{200},
Jon Perritt816d2a02014-03-11 20:49:46 -050099 })
Jon Perritt8c93a302014-09-28 22:35:57 -0500100 dr.Err = err
101 dr.Resp = &resp.HttpResponse
102 return dr
103}
104
105// CreateOpts is a structure that holds parameters for creating an object.
106type CreateOpts struct {
107 Metadata map[string]string
108 ContentDisposition string `h:"Content-Disposition"`
109 ContentEncoding string `h:"Content-Encoding"`
110 ContentLength int `h:"Content-Length"`
111 ContentType string `h:"Content-Type"`
112 CopyFrom string `h:"X-Copy-From"`
113 DeleteAfter int `h:"X-Delete-After"`
114 DeleteAt int `h:"X-Delete-At"`
115 DetectContentType string `h:"X-Detect-Content-Type"`
116 ETag string `h:"ETag"`
117 IfNoneMatch string `h:"If-None-Match"`
118 ObjectManifest string `h:"X-Object-Manifest"`
119 TransferEncoding string `h:"Transfer-Encoding"`
120 Expires string `q:"expires"`
121 MultipartManifest string `q:"multiple-manifest"`
122 Signature string `q:"signature"`
Jon Perritt816d2a02014-03-11 20:49:46 -0500123}
124
125// Create is a function that creates a new object or replaces an existing object.
Jon Perrittde47eac2014-09-30 15:34:17 -0500126func Create(c *gophercloud.ServiceClient, containerName, objectName string, content io.Reader, opts *CreateOpts) error {
Jon Perritt816d2a02014-03-11 20:49:46 -0500127 var reqBody []byte
128
Jon Perrittde47eac2014-09-30 15:34:17 -0500129 url := objectURL(c, containerName, objectName)
Ash Wilson604320e2014-09-10 16:02:28 -0400130 h := c.Provider.AuthenticatedHeaders()
Jon Perritt816d2a02014-03-11 20:49:46 -0500131
Jon Perrittde47eac2014-09-30 15:34:17 -0500132 if opts != nil {
133 headers, err := gophercloud.BuildHeaders(opts)
134 if err != nil {
135 return nil
136 }
Jon Perritt8c93a302014-09-28 22:35:57 -0500137
Jon Perrittde47eac2014-09-30 15:34:17 -0500138 for k, v := range headers {
139 h[k] = v
140 }
Jon Perritt816d2a02014-03-11 20:49:46 -0500141
Jon Perrittde47eac2014-09-30 15:34:17 -0500142 for k, v := range opts.Metadata {
143 h["X-Object-Meta-"+k] = v
144 }
Jon Perritt816d2a02014-03-11 20:49:46 -0500145
Jon Perrittde47eac2014-09-30 15:34:17 -0500146 query, err := gophercloud.BuildQueryString(opts)
147 if err != nil {
148 return err
149 }
150 url += query.String()
Jon Perritt8c93a302014-09-28 22:35:57 -0500151 }
Jon Perritt816d2a02014-03-11 20:49:46 -0500152
Jon Perritt816d2a02014-03-11 20:49:46 -0500153 if content != nil {
Jon Perritt884e0312014-08-14 17:25:38 -0500154 reqBody = make([]byte, 0)
Ash Wilson604320e2014-09-10 16:02:28 -0400155 _, err := content.Read(reqBody)
Jon Perritt816d2a02014-03-11 20:49:46 -0500156 if err != nil {
157 return err
158 }
159 }
160
Jon Perrittde47eac2014-09-30 15:34:17 -0500161 _, err := perigee.Request("PUT", url, perigee.Options{
Jon Perritt816d2a02014-03-11 20:49:46 -0500162 ReqBody: reqBody,
163 MoreHeaders: h,
Ash Wilsone47ea9e2014-09-10 16:03:44 -0400164 OkCodes: []int{201},
Jon Perritt816d2a02014-03-11 20:49:46 -0500165 })
166 return err
167}
168
Jon Perritt8c93a302014-09-28 22:35:57 -0500169// CopyOpts is a structure that holds parameters for copying one object to another.
170type CopyOpts struct {
171 Metadata map[string]string
172 ContentDisposition string `h:"Content-Disposition"`
173 ContentEncoding string `h:"Content-Encoding"`
174 ContentType string `h:"Content-Type"`
175 Destination string `h:"Destination,required"`
176}
177
Jon Perritt816d2a02014-03-11 20:49:46 -0500178// Copy is a function that copies one object to another.
Jon Perrittde47eac2014-09-30 15:34:17 -0500179func Copy(c *gophercloud.ServiceClient, containerName, objectName string, opts *CopyOpts) error {
Ash Wilson604320e2014-09-10 16:02:28 -0400180 h := c.Provider.AuthenticatedHeaders()
Jon Perritt816d2a02014-03-11 20:49:46 -0500181
Jon Perrittde47eac2014-09-30 15:34:17 -0500182 if opts == nil {
183 return fmt.Errorf("Required CopyOpts field 'Destination' not set.")
184 }
Jon Perritt8c93a302014-09-28 22:35:57 -0500185 headers, err := gophercloud.BuildHeaders(opts)
186 if err != nil {
187 return err
Jon Perritt816d2a02014-03-11 20:49:46 -0500188 }
Jon Perritt8c93a302014-09-28 22:35:57 -0500189 for k, v := range headers {
Jon Perritt816d2a02014-03-11 20:49:46 -0500190 h[k] = v
191 }
192
193 for k, v := range opts.Metadata {
194 h["X-Object-Meta-"+k] = v
195 }
196
Jon Perritt8c93a302014-09-28 22:35:57 -0500197 url := objectURL(c, containerName, objectName)
198 _, err = perigee.Request("COPY", url, perigee.Options{
199 MoreHeaders: h,
200 OkCodes: []int{201},
201 })
202 return err
203}
204
205// DeleteOpts is a structure that holds parameters for deleting an object.
206type DeleteOpts struct {
207 MultipartManifest string `q:"multipart-manifest"`
208}
209
210// Delete is a function that deletes an object.
Jon Perrittde47eac2014-09-30 15:34:17 -0500211func Delete(c *gophercloud.ServiceClient, containerName, objectName string, opts *DeleteOpts) error {
212 url := objectURL(c, containerName, objectName)
Jon Perritt8c93a302014-09-28 22:35:57 -0500213
Jon Perrittde47eac2014-09-30 15:34:17 -0500214 if opts != nil {
215 query, err := gophercloud.BuildQueryString(opts)
216 if err != nil {
217 return err
218 }
219 url += query.String()
Jon Perritt8c93a302014-09-28 22:35:57 -0500220 }
221
Jon Perrittde47eac2014-09-30 15:34:17 -0500222 _, err := perigee.Request("DELETE", url, perigee.Options{
223 MoreHeaders: c.Provider.AuthenticatedHeaders(),
Jon Perritt8c93a302014-09-28 22:35:57 -0500224 OkCodes: []int{204},
225 })
226 return err
227}
228
229// GetOpts is a structure that holds parameters for getting an object's metadata.
230type GetOpts struct {
231 Expires string `q:"expires"`
232 Signature string `q:"signature"`
233}
234
235// Get is a function that retrieves the metadata of an object. To extract just the custom
236// metadata, pass the GetResult response to the ExtractMetadata function.
Jon Perrittde47eac2014-09-30 15:34:17 -0500237func Get(c *gophercloud.ServiceClient, containerName, objectName string, opts *GetOpts) GetResult {
Jon Perritt8c93a302014-09-28 22:35:57 -0500238 var gr GetResult
Jon Perrittde47eac2014-09-30 15:34:17 -0500239 url := objectURL(c, containerName, objectName)
240
241 if opts != nil {
242 query, err := gophercloud.BuildQueryString(opts)
243 if err != nil {
244 gr.Err = err
245 return gr
246 }
247 url += query.String()
Jon Perritt8c93a302014-09-28 22:35:57 -0500248 }
249
Jon Perritt8c93a302014-09-28 22:35:57 -0500250 resp, err := perigee.Request("HEAD", url, perigee.Options{
251 MoreHeaders: c.Provider.AuthenticatedHeaders(),
252 OkCodes: []int{200, 204},
253 })
254 gr.Err = err
255 gr.Resp = &resp.HttpResponse
256 return gr
257}
258
259// UpdateOpts is a structure that holds parameters for updating, creating, or deleting an
260// object's metadata.
261type UpdateOpts struct {
262 Metadata map[string]string
263 ContentDisposition string `h:"Content-Disposition"`
264 ContentEncoding string `h:"Content-Encoding"`
265 ContentType string `h:"Content-Type"`
266 DeleteAfter int `h:"X-Delete-After"`
267 DeleteAt int `h:"X-Delete-At"`
268 DetectContentType bool `h:"X-Detect-Content-Type"`
269}
270
271// Update is a function that creates, updates, or deletes an object's metadata.
Jon Perrittde47eac2014-09-30 15:34:17 -0500272func Update(c *gophercloud.ServiceClient, containerName, objectName string, opts *UpdateOpts) error {
Jon Perritt8c93a302014-09-28 22:35:57 -0500273 h := c.Provider.AuthenticatedHeaders()
274
Jon Perrittde47eac2014-09-30 15:34:17 -0500275 if opts != nil {
276 headers, err := gophercloud.BuildHeaders(opts)
277 if err != nil {
278 return nil
279 }
Jon Perritt8c93a302014-09-28 22:35:57 -0500280
Jon Perrittde47eac2014-09-30 15:34:17 -0500281 for k, v := range headers {
282 h[k] = v
283 }
Jon Perritt8c93a302014-09-28 22:35:57 -0500284
Jon Perrittde47eac2014-09-30 15:34:17 -0500285 for k, v := range opts.Metadata {
286 h["X-Object-Meta-"+k] = v
287 }
Jon Perritt8c93a302014-09-28 22:35:57 -0500288 }
289
290 url := objectURL(c, containerName, objectName)
Jon Perrittde47eac2014-09-30 15:34:17 -0500291 _, err := perigee.Request("POST", url, perigee.Options{
Jon Perritt816d2a02014-03-11 20:49:46 -0500292 MoreHeaders: h,
Ash Wilsone47ea9e2014-09-10 16:03:44 -0400293 OkCodes: []int{202},
Jon Perritt816d2a02014-03-11 20:49:46 -0500294 })
295 return err
296}