1
// Copyright 2012, 2013 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
6
17
"launchpad.net/goamz/s3"
7
18
"launchpad.net/juju-core/environs"
19
"launchpad.net/juju-core/errors"
12
22
func NewStorage(bucket *s3.Bucket) environs.Storage {
157
167
func maybeNotFound(err error) error {
158
168
if err != nil && s3ErrorStatusCode(err) == 404 {
159
return &environs.NotFoundError{err}
169
return &errors.NotFoundError{err, ""}
174
// listBucketResult is the top level XML element of the storage index.
175
// We only need the contents.
176
type listBucketResult struct {
180
// contents describes one entry of the storage index.
181
type contents struct {
185
// httpStorageReader implements the environs.StorageReader interface
186
// to access an EC2 storage via HTTP.
187
type httpStorageReader struct {
191
// NewHTTPStorageReader creates a storage reader for the HTTP
192
// access to an EC2 storage like the juju-dist storage.
193
func NewHTTPStorageReader(url string) environs.StorageReader {
194
return &httpStorageReader{url}
197
// Get implements environs.StorageReader.Get.
198
func (h *httpStorageReader) Get(name string) (io.ReadCloser, error) {
199
nameURL, err := h.URL(name)
203
resp, err := http.Get(nameURL)
204
if err != nil && resp.StatusCode == http.StatusNotFound {
205
return nil, &errors.NotFoundError{err, ""}
207
return resp.Body, nil
210
// List implements environs.StorageReader.List.
211
func (h *httpStorageReader) List(prefix string) ([]string, error) {
212
lbr, err := h.getListBucketResult()
217
for _, c := range lbr.Contents {
218
if strings.HasPrefix(c.Key, prefix) {
219
names = append(names, c.Key)
226
// URL implements environs.StorageReader.URL.
227
func (h *httpStorageReader) URL(name string) (string, error) {
228
if strings.HasSuffix(h.url, "/") {
229
return h.url + name, nil
231
return h.url + "/" + name, nil
234
// getListBucketResult retrieves the index of the storage,
235
func (h *httpStorageReader) getListBucketResult() (*listBucketResult, error) {
236
resp, err := http.Get(h.url)
240
defer resp.Body.Close()
241
buf, err := ioutil.ReadAll(resp.Body)
245
var lbr listBucketResult
246
err = xml.Unmarshal(buf, &lbr)