blob: 0ad0315de4d8821858b40ab0d3db848ca8683b09 [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"
Ash Wilsonaf262872014-10-20 09:32:29 -04006 "io/ioutil"
Jon Perritt8c93a302014-09-28 22:35:57 -05007 "time"
Ash Wilson604320e2014-09-10 16:02:28 -04008
9 "github.com/racker/perigee"
10 "github.com/rackspace/gophercloud"
Ash Wilsonca6f7562014-09-16 15:43:54 -040011 "github.com/rackspace/gophercloud/pagination"
Jon Perritt816d2a02014-03-11 20:49:46 -050012)
13
Jon Perritte90aced2014-10-12 23:24:06 -050014// ListOptsBuilder allows extensions to add additional parameters to the List
15// request.
16type ListOptsBuilder interface {
17 ToObjectListParams() (bool, string, error)
18}
19
Jon Perritt8c93a302014-09-28 22:35:57 -050020// ListOpts is a structure that holds parameters for listing objects.
21type ListOpts struct {
22 Full bool
Jon Perritt04851d32014-10-14 02:07:13 -050023 Limit int `q:"limit"`
24 Marker string `q:"marker"`
25 EndMarker string `q:"end_marker"`
26 Format string `q:"format"`
27 Prefix string `q:"prefix"`
28 Delimiter string `q:"delimiter"`
29 Path string `q:"path"`
Ash Wilsonca6f7562014-09-16 15:43:54 -040030}
31
Jon Perritte90aced2014-10-12 23:24:06 -050032// ToObjectListParams formats a ListOpts into a query string and boolean
33// representing whether to list complete information for each object.
34func (opts ListOpts) ToObjectListParams() (bool, string, error) {
35 q, err := gophercloud.BuildQueryString(opts)
36 if err != nil {
37 return false, "", err
38 }
39 return opts.Full, q.String(), nil
40}
41
Jon Perritt816d2a02014-03-11 20:49:46 -050042// List is a function that retrieves all objects in a container. It also returns the details
43// for the container. To extract only the object information or names, pass the ListResult
Jon Perritteb575642014-04-24 15:16:31 -050044// response to the ExtractInfo or ExtractNames function, respectively.
Jon Perritte90aced2014-10-12 23:24:06 -050045func List(c *gophercloud.ServiceClient, containerName string, opts ListOptsBuilder) pagination.Pager {
46 headers := map[string]string{"Accept": "text/plain", "Content-Type": "text/plain"}
Jon Perritt816d2a02014-03-11 20:49:46 -050047
Jon Perrittea4e3012014-10-09 22:03:19 -050048 url := listURL(c, containerName)
Jon Perrittde47eac2014-09-30 15:34:17 -050049 if opts != nil {
Jon Perritte90aced2014-10-12 23:24:06 -050050 full, query, err := opts.ToObjectListParams()
Jon Perrittde47eac2014-09-30 15:34:17 -050051 if err != nil {
Jon Perrittde47eac2014-09-30 15:34:17 -050052 return pagination.Pager{Err: err}
53 }
Jon Perritte90aced2014-10-12 23:24:06 -050054 url += query
Jon Perritt816d2a02014-03-11 20:49:46 -050055
Jon Perritte90aced2014-10-12 23:24:06 -050056 if full {
57 headers = map[string]string{"Accept": "application/json", "Content-Type": "application/json"}
Jon Perrittde47eac2014-09-30 15:34:17 -050058 }
Ash Wilsonca6f7562014-09-16 15:43:54 -040059 }
60
Ash Wilsonb8b16f82014-10-20 10:19:49 -040061 createPage := func(r pagination.PageResult) pagination.Page {
62 p := ObjectPage{pagination.MarkerPageBase{PageResult: r}}
Ash Wilsonca6f7562014-09-16 15:43:54 -040063 p.MarkerPageBase.Owner = p
64 return p
Jon Perritt816d2a02014-03-11 20:49:46 -050065 }
66
Ash Wilsonca6f7562014-09-16 15:43:54 -040067 pager := pagination.NewPager(c, url, createPage)
68 pager.Headers = headers
69 return pager
Jon Perritt816d2a02014-03-11 20:49:46 -050070}
71
Jon Perritte90aced2014-10-12 23:24:06 -050072// DownloadOptsBuilder allows extensions to add additional parameters to the
73// Download request.
74type DownloadOptsBuilder interface {
75 ToObjectDownloadParams() (map[string]string, string, error)
76}
77
Jon Perritt8c93a302014-09-28 22:35:57 -050078// DownloadOpts is a structure that holds parameters for downloading an object.
79type DownloadOpts struct {
80 IfMatch string `h:"If-Match"`
81 IfModifiedSince time.Time `h:"If-Modified-Since"`
82 IfNoneMatch string `h:"If-None-Match"`
83 IfUnmodifiedSince time.Time `h:"If-Unmodified-Since"`
84 Range string `h:"Range"`
85 Expires string `q:"expires"`
86 MultipartManifest string `q:"multipart-manifest"`
87 Signature string `q:"signature"`
88}
89
Jon Perritte90aced2014-10-12 23:24:06 -050090// ToObjectDownloadParams formats a DownloadOpts into a query string and map of
91// headers.
92func (opts ListOpts) ToObjectDownloadParams() (map[string]string, string, error) {
93 q, err := gophercloud.BuildQueryString(opts)
94 if err != nil {
95 return nil, "", err
96 }
97 h, err := gophercloud.BuildHeaders(opts)
98 if err != nil {
99 return nil, q.String(), err
100 }
101 return h, q.String(), nil
102}
103
Jon Perritt816d2a02014-03-11 20:49:46 -0500104// Download is a function that retrieves the content and metadata for an object.
Jon Perritte90aced2014-10-12 23:24:06 -0500105// To extract just the content, pass the DownloadResult response to the
106// ExtractContent function.
107func Download(c *gophercloud.ServiceClient, containerName, objectName string, opts DownloadOptsBuilder) DownloadResult {
Jon Perritt5db08922014-09-30 21:32:48 -0500108 var res DownloadResult
Jon Perritt8c93a302014-09-28 22:35:57 -0500109
Jon Perrittea4e3012014-10-09 22:03:19 -0500110 url := downloadURL(c, containerName, objectName)
Ash Wilson77857dc2014-10-22 09:09:02 -0400111 h := c.AuthenticatedHeaders()
Jon Perritt816d2a02014-03-11 20:49:46 -0500112
Jon Perrittde47eac2014-09-30 15:34:17 -0500113 if opts != nil {
Jon Perritte90aced2014-10-12 23:24:06 -0500114 headers, query, err := opts.ToObjectDownloadParams()
Jon Perrittde47eac2014-09-30 15:34:17 -0500115 if err != nil {
Jon Perritt5db08922014-09-30 21:32:48 -0500116 res.Err = err
117 return res
Jon Perrittde47eac2014-09-30 15:34:17 -0500118 }
119
120 for k, v := range headers {
121 h[k] = v
122 }
123
Jon Perritte90aced2014-10-12 23:24:06 -0500124 url += query
Jon Perritt8c93a302014-09-28 22:35:57 -0500125 }
126
Jon Perritt816d2a02014-03-11 20:49:46 -0500127 resp, err := perigee.Request("GET", url, perigee.Options{
Jon Perritt816d2a02014-03-11 20:49:46 -0500128 MoreHeaders: h,
Ash Wilsone47ea9e2014-09-10 16:03:44 -0400129 OkCodes: []int{200},
Jon Perritt816d2a02014-03-11 20:49:46 -0500130 })
Ash Wilsonaf262872014-10-20 09:32:29 -0400131 defer resp.HttpResponse.Body.Close()
132 body, err := ioutil.ReadAll(resp.HttpResponse.Body)
Ash Wilsond3dc2542014-10-20 10:10:48 -0400133 res.Body = body
Jon Perritt5db08922014-09-30 21:32:48 -0500134 res.Err = err
Ash Wilson72e4d2c2014-10-20 10:27:30 -0400135 res.Header = resp.HttpResponse.Header
Jon Perritt5db08922014-09-30 21:32:48 -0500136 return res
Jon Perritt8c93a302014-09-28 22:35:57 -0500137}
138
Jon Perritte90aced2014-10-12 23:24:06 -0500139// CreateOptsBuilder allows extensions to add additional parameters to the
140// Create request.
141type CreateOptsBuilder interface {
142 ToObjectCreateParams() (map[string]string, string, error)
143}
144
Jon Perritt8c93a302014-09-28 22:35:57 -0500145// CreateOpts is a structure that holds parameters for creating an object.
146type CreateOpts struct {
147 Metadata map[string]string
148 ContentDisposition string `h:"Content-Disposition"`
149 ContentEncoding string `h:"Content-Encoding"`
150 ContentLength int `h:"Content-Length"`
151 ContentType string `h:"Content-Type"`
152 CopyFrom string `h:"X-Copy-From"`
153 DeleteAfter int `h:"X-Delete-After"`
154 DeleteAt int `h:"X-Delete-At"`
155 DetectContentType string `h:"X-Detect-Content-Type"`
156 ETag string `h:"ETag"`
157 IfNoneMatch string `h:"If-None-Match"`
158 ObjectManifest string `h:"X-Object-Manifest"`
159 TransferEncoding string `h:"Transfer-Encoding"`
160 Expires string `q:"expires"`
161 MultipartManifest string `q:"multiple-manifest"`
162 Signature string `q:"signature"`
Jon Perritt816d2a02014-03-11 20:49:46 -0500163}
164
Jon Perritte90aced2014-10-12 23:24:06 -0500165// ToObjectCreateParams formats a CreateOpts into a query string and map of
166// headers.
167func (opts CreateOpts) ToObjectCreateParams() (map[string]string, string, error) {
168 q, err := gophercloud.BuildQueryString(opts)
169 if err != nil {
170 return nil, "", err
171 }
172 h, err := gophercloud.BuildHeaders(opts)
173 if err != nil {
174 return nil, q.String(), err
175 }
176
177 for k, v := range opts.Metadata {
178 h["X-Object-Meta-"+k] = v
179 }
180
181 return h, q.String(), nil
182}
183
Jon Perritt816d2a02014-03-11 20:49:46 -0500184// Create is a function that creates a new object or replaces an existing object.
Jon Perritte90aced2014-10-12 23:24:06 -0500185func Create(c *gophercloud.ServiceClient, containerName, objectName string, content io.Reader, opts CreateOptsBuilder) CreateResult {
Jon Perritt5db08922014-09-30 21:32:48 -0500186 var res CreateResult
Jon Perritt816d2a02014-03-11 20:49:46 -0500187
Jon Perrittea4e3012014-10-09 22:03:19 -0500188 url := createURL(c, containerName, objectName)
Ash Wilson77857dc2014-10-22 09:09:02 -0400189 h := c.AuthenticatedHeaders()
Jon Perritt816d2a02014-03-11 20:49:46 -0500190
Jon Perrittde47eac2014-09-30 15:34:17 -0500191 if opts != nil {
Jon Perritte90aced2014-10-12 23:24:06 -0500192 headers, query, err := opts.ToObjectCreateParams()
Jon Perrittde47eac2014-09-30 15:34:17 -0500193 if err != nil {
Jon Perritt5db08922014-09-30 21:32:48 -0500194 res.Err = err
195 return res
Jon Perrittde47eac2014-09-30 15:34:17 -0500196 }
Jon Perritt8c93a302014-09-28 22:35:57 -0500197
Jon Perrittde47eac2014-09-30 15:34:17 -0500198 for k, v := range headers {
199 h[k] = v
200 }
Jon Perritt816d2a02014-03-11 20:49:46 -0500201
Jon Perritte90aced2014-10-12 23:24:06 -0500202 url += query
Jon Perritt8c93a302014-09-28 22:35:57 -0500203 }
Jon Perritt816d2a02014-03-11 20:49:46 -0500204
Jon Perritta77ba0d2014-10-17 01:15:29 -0500205 contentType := h["Content-Type"]
Jon Perritt816d2a02014-03-11 20:49:46 -0500206
Jon Perritt5db08922014-09-30 21:32:48 -0500207 resp, err := perigee.Request("PUT", url, perigee.Options{
Jon Perritta77ba0d2014-10-17 01:15:29 -0500208 ContentType: contentType,
209 ReqBody: content,
Jon Perritt816d2a02014-03-11 20:49:46 -0500210 MoreHeaders: h,
Jon Perritta77ba0d2014-10-17 01:15:29 -0500211 OkCodes: []int{201, 202},
Jon Perritt816d2a02014-03-11 20:49:46 -0500212 })
Ash Wilson72e4d2c2014-10-20 10:27:30 -0400213 res.Header = resp.HttpResponse.Header
Jon Perritt5db08922014-09-30 21:32:48 -0500214 res.Err = err
215 return res
Jon Perritt816d2a02014-03-11 20:49:46 -0500216}
217
Jon Perritte90aced2014-10-12 23:24:06 -0500218// CopyOptsBuilder allows extensions to add additional parameters to the
219// Copy request.
220type CopyOptsBuilder interface {
Jon Perritt04851d32014-10-14 02:07:13 -0500221 ToObjectCopyMap() (map[string]string, error)
Jon Perritte90aced2014-10-12 23:24:06 -0500222}
223
224// CopyOpts is a structure that holds parameters for copying one object to
225// another.
Jon Perritt8c93a302014-09-28 22:35:57 -0500226type CopyOpts struct {
227 Metadata map[string]string
228 ContentDisposition string `h:"Content-Disposition"`
229 ContentEncoding string `h:"Content-Encoding"`
230 ContentType string `h:"Content-Type"`
231 Destination string `h:"Destination,required"`
232}
233
Jon Perritt04851d32014-10-14 02:07:13 -0500234// ToObjectCopyMap formats a CopyOpts into a map of headers.
235func (opts CopyOpts) ToObjectCopyMap() (map[string]string, error) {
Jon Perritte90aced2014-10-12 23:24:06 -0500236 if opts.Destination == "" {
237 return nil, fmt.Errorf("Required CopyOpts field 'Destination' not set.")
238 }
239 h, err := gophercloud.BuildHeaders(opts)
240 if err != nil {
241 return nil, err
242 }
243 for k, v := range opts.Metadata {
244 h["X-Object-Meta-"+k] = v
245 }
246 return h, nil
247}
248
Jon Perritt816d2a02014-03-11 20:49:46 -0500249// Copy is a function that copies one object to another.
Jon Perritte90aced2014-10-12 23:24:06 -0500250func Copy(c *gophercloud.ServiceClient, containerName, objectName string, opts CopyOptsBuilder) CopyResult {
Jon Perritt5db08922014-09-30 21:32:48 -0500251 var res CopyResult
Ash Wilson77857dc2014-10-22 09:09:02 -0400252 h := c.AuthenticatedHeaders()
Jon Perritt816d2a02014-03-11 20:49:46 -0500253
Jon Perritt04851d32014-10-14 02:07:13 -0500254 headers, err := opts.ToObjectCopyMap()
Jon Perritt8c93a302014-09-28 22:35:57 -0500255 if err != nil {
Jon Perritt5db08922014-09-30 21:32:48 -0500256 res.Err = err
257 return res
Jon Perritt816d2a02014-03-11 20:49:46 -0500258 }
Jon Perritte90aced2014-10-12 23:24:06 -0500259
Jon Perritt8c93a302014-09-28 22:35:57 -0500260 for k, v := range headers {
Jon Perritt816d2a02014-03-11 20:49:46 -0500261 h[k] = v
262 }
263
Jon Perrittea4e3012014-10-09 22:03:19 -0500264 url := copyURL(c, containerName, objectName)
Jon Perritt5db08922014-09-30 21:32:48 -0500265 resp, err := perigee.Request("COPY", url, perigee.Options{
Jon Perritt8c93a302014-09-28 22:35:57 -0500266 MoreHeaders: h,
267 OkCodes: []int{201},
268 })
Ash Wilson72e4d2c2014-10-20 10:27:30 -0400269 res.Header = resp.HttpResponse.Header
Jon Perritt5db08922014-09-30 21:32:48 -0500270 return res
Jon Perritt8c93a302014-09-28 22:35:57 -0500271}
272
Jon Perritte90aced2014-10-12 23:24:06 -0500273// DeleteOptsBuilder allows extensions to add additional parameters to the
274// Delete request.
275type DeleteOptsBuilder interface {
Jon Perritt26780d52014-10-14 11:35:58 -0500276 ToObjectDeleteQuery() (string, error)
Jon Perritte90aced2014-10-12 23:24:06 -0500277}
278
Jon Perritt8c93a302014-09-28 22:35:57 -0500279// DeleteOpts is a structure that holds parameters for deleting an object.
280type DeleteOpts struct {
281 MultipartManifest string `q:"multipart-manifest"`
282}
283
Jon Perritt26780d52014-10-14 11:35:58 -0500284// ToObjectDeleteQuery formats a DeleteOpts into a query string.
285func (opts DeleteOpts) ToObjectDeleteQuery() (string, error) {
Jon Perritte90aced2014-10-12 23:24:06 -0500286 q, err := gophercloud.BuildQueryString(opts)
287 if err != nil {
288 return "", err
289 }
290 return q.String(), nil
291}
292
Jon Perritt8c93a302014-09-28 22:35:57 -0500293// Delete is a function that deletes an object.
Jon Perritte90aced2014-10-12 23:24:06 -0500294func Delete(c *gophercloud.ServiceClient, containerName, objectName string, opts DeleteOptsBuilder) DeleteResult {
Jon Perritt5db08922014-09-30 21:32:48 -0500295 var res DeleteResult
Jon Perrittea4e3012014-10-09 22:03:19 -0500296 url := deleteURL(c, containerName, objectName)
Jon Perritt8c93a302014-09-28 22:35:57 -0500297
Jon Perrittde47eac2014-09-30 15:34:17 -0500298 if opts != nil {
Jon Perritt26780d52014-10-14 11:35:58 -0500299 query, err := opts.ToObjectDeleteQuery()
Jon Perrittde47eac2014-09-30 15:34:17 -0500300 if err != nil {
Jon Perritt5db08922014-09-30 21:32:48 -0500301 res.Err = err
302 return res
Jon Perrittde47eac2014-09-30 15:34:17 -0500303 }
Jon Perritte90aced2014-10-12 23:24:06 -0500304 url += query
Jon Perritt8c93a302014-09-28 22:35:57 -0500305 }
306
Jon Perritt5db08922014-09-30 21:32:48 -0500307 resp, err := perigee.Request("DELETE", url, perigee.Options{
Ash Wilson77857dc2014-10-22 09:09:02 -0400308 MoreHeaders: c.AuthenticatedHeaders(),
Jon Perritt8c93a302014-09-28 22:35:57 -0500309 OkCodes: []int{204},
310 })
Ash Wilson72e4d2c2014-10-20 10:27:30 -0400311 res.Header = resp.HttpResponse.Header
Jon Perritt5db08922014-09-30 21:32:48 -0500312 res.Err = err
313 return res
Jon Perritt8c93a302014-09-28 22:35:57 -0500314}
315
Jon Perritte90aced2014-10-12 23:24:06 -0500316// GetOptsBuilder allows extensions to add additional parameters to the
317// Get request.
318type GetOptsBuilder interface {
Jon Perritt26780d52014-10-14 11:35:58 -0500319 ToObjectGetQuery() (string, error)
Jon Perritte90aced2014-10-12 23:24:06 -0500320}
321
Jon Perritt8c93a302014-09-28 22:35:57 -0500322// GetOpts is a structure that holds parameters for getting an object's metadata.
323type GetOpts struct {
324 Expires string `q:"expires"`
325 Signature string `q:"signature"`
326}
327
Jon Perritt26780d52014-10-14 11:35:58 -0500328// ToObjectGetQuery formats a GetOpts into a query string.
329func (opts GetOpts) ToObjectGetQuery() (string, error) {
Jon Perritte90aced2014-10-12 23:24:06 -0500330 q, err := gophercloud.BuildQueryString(opts)
331 if err != nil {
332 return "", err
333 }
334 return q.String(), nil
335}
336
Jon Perritt8c93a302014-09-28 22:35:57 -0500337// Get is a function that retrieves the metadata of an object. To extract just the custom
338// metadata, pass the GetResult response to the ExtractMetadata function.
Jon Perritte90aced2014-10-12 23:24:06 -0500339func Get(c *gophercloud.ServiceClient, containerName, objectName string, opts GetOptsBuilder) GetResult {
Jon Perritt5db08922014-09-30 21:32:48 -0500340 var res GetResult
Jon Perrittea4e3012014-10-09 22:03:19 -0500341 url := getURL(c, containerName, objectName)
Jon Perrittde47eac2014-09-30 15:34:17 -0500342
343 if opts != nil {
Jon Perritt26780d52014-10-14 11:35:58 -0500344 query, err := opts.ToObjectGetQuery()
Jon Perrittde47eac2014-09-30 15:34:17 -0500345 if err != nil {
Jon Perritt5db08922014-09-30 21:32:48 -0500346 res.Err = err
347 return res
Jon Perrittde47eac2014-09-30 15:34:17 -0500348 }
Jon Perritte90aced2014-10-12 23:24:06 -0500349 url += query
Jon Perritt8c93a302014-09-28 22:35:57 -0500350 }
351
Jon Perritt8c93a302014-09-28 22:35:57 -0500352 resp, err := perigee.Request("HEAD", url, perigee.Options{
Ash Wilson77857dc2014-10-22 09:09:02 -0400353 MoreHeaders: c.AuthenticatedHeaders(),
Jon Perritt8c93a302014-09-28 22:35:57 -0500354 OkCodes: []int{200, 204},
355 })
Ash Wilson72e4d2c2014-10-20 10:27:30 -0400356 res.Header = resp.HttpResponse.Header
Jon Perritt5db08922014-09-30 21:32:48 -0500357 res.Err = err
Jon Perritt5db08922014-09-30 21:32:48 -0500358 return res
Jon Perritt8c93a302014-09-28 22:35:57 -0500359}
360
Jon Perritte90aced2014-10-12 23:24:06 -0500361// UpdateOptsBuilder allows extensions to add additional parameters to the
362// Update request.
363type UpdateOptsBuilder interface {
Jon Perritt04851d32014-10-14 02:07:13 -0500364 ToObjectUpdateMap() (map[string]string, error)
Jon Perritte90aced2014-10-12 23:24:06 -0500365}
366
Jon Perritt8c93a302014-09-28 22:35:57 -0500367// UpdateOpts is a structure that holds parameters for updating, creating, or deleting an
368// object's metadata.
369type UpdateOpts struct {
370 Metadata map[string]string
371 ContentDisposition string `h:"Content-Disposition"`
372 ContentEncoding string `h:"Content-Encoding"`
373 ContentType string `h:"Content-Type"`
374 DeleteAfter int `h:"X-Delete-After"`
375 DeleteAt int `h:"X-Delete-At"`
376 DetectContentType bool `h:"X-Detect-Content-Type"`
377}
378
Jon Perritt04851d32014-10-14 02:07:13 -0500379// ToObjectUpdateMap formats a UpdateOpts into a map of headers.
380func (opts UpdateOpts) ToObjectUpdateMap() (map[string]string, error) {
Jon Perritte90aced2014-10-12 23:24:06 -0500381 h, err := gophercloud.BuildHeaders(opts)
382 if err != nil {
383 return nil, err
384 }
385 for k, v := range opts.Metadata {
386 h["X-Object-Meta-"+k] = v
387 }
388 return h, nil
389}
390
Jon Perritt8c93a302014-09-28 22:35:57 -0500391// Update is a function that creates, updates, or deletes an object's metadata.
Jon Perritte90aced2014-10-12 23:24:06 -0500392func Update(c *gophercloud.ServiceClient, containerName, objectName string, opts UpdateOptsBuilder) UpdateResult {
Jon Perritt5db08922014-09-30 21:32:48 -0500393 var res UpdateResult
Ash Wilson77857dc2014-10-22 09:09:02 -0400394 h := c.AuthenticatedHeaders()
Jon Perritt8c93a302014-09-28 22:35:57 -0500395
Jon Perrittde47eac2014-09-30 15:34:17 -0500396 if opts != nil {
Jon Perritt04851d32014-10-14 02:07:13 -0500397 headers, err := opts.ToObjectUpdateMap()
Jon Perrittde47eac2014-09-30 15:34:17 -0500398 if err != nil {
Jon Perritt5db08922014-09-30 21:32:48 -0500399 res.Err = err
400 return res
Jon Perrittde47eac2014-09-30 15:34:17 -0500401 }
Jon Perritt8c93a302014-09-28 22:35:57 -0500402
Jon Perrittde47eac2014-09-30 15:34:17 -0500403 for k, v := range headers {
404 h[k] = v
405 }
Jon Perritt8c93a302014-09-28 22:35:57 -0500406 }
407
Jon Perrittea4e3012014-10-09 22:03:19 -0500408 url := updateURL(c, containerName, objectName)
Jon Perritt5db08922014-09-30 21:32:48 -0500409 resp, err := perigee.Request("POST", url, perigee.Options{
Jon Perritt816d2a02014-03-11 20:49:46 -0500410 MoreHeaders: h,
Ash Wilsone47ea9e2014-09-10 16:03:44 -0400411 OkCodes: []int{202},
Jon Perritt816d2a02014-03-11 20:49:46 -0500412 })
Ash Wilson72e4d2c2014-10-20 10:27:30 -0400413 res.Header = resp.HttpResponse.Header
Jon Perritt5db08922014-09-30 21:32:48 -0500414 res.Err = err
415 return res
Jon Perritt816d2a02014-03-11 20:49:46 -0500416}