| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package gs | 5 package gs |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "fmt" | 8 "fmt" |
| 9 "io" | 9 "io" |
| 10 "net/http" | 10 "net/http" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 ) | 30 ) |
| 31 | 31 |
| 32 // Client abstracts funcitonality to connect with and use Google Storage from | 32 // Client abstracts funcitonality to connect with and use Google Storage from |
| 33 // the actual Google Storage client. | 33 // the actual Google Storage client. |
| 34 // | 34 // |
| 35 // Non-production implementations are used primarily for testing. | 35 // Non-production implementations are used primarily for testing. |
| 36 type Client interface { | 36 type Client interface { |
| 37 io.Closer | 37 io.Closer |
| 38 | 38 |
| 39 // NewReader instantiates a new Reader instance for the named bucket/pat
h. | 39 // NewReader instantiates a new Reader instance for the named bucket/pat
h. |
| 40 » NewReader(p Path, o Options) (io.ReadCloser, error) | 40 » // |
| 41 » // The supplied offset must be >= 0, or else this function will panic. |
| 42 » // |
| 43 » // If the supplied length is <0, no upper byte bound will be set. |
| 44 » NewReader(p Path, offset, length int64) (io.ReadCloser, error) |
| 41 | 45 |
| 42 // NewWriter instantiates a new Writer instance for the named bucket/pat
h. | 46 // NewWriter instantiates a new Writer instance for the named bucket/pat
h. |
| 43 NewWriter(p Path) (Writer, error) | 47 NewWriter(p Path) (Writer, error) |
| 44 | 48 |
| 45 // Delete deletes the object at the specified path. | 49 // Delete deletes the object at the specified path. |
| 46 // | 50 // |
| 47 // If the object does not exist, it is considered a success. | 51 // If the object does not exist, it is considered a success. |
| 48 Delete(p Path) error | 52 Delete(p Path) error |
| 49 | 53 |
| 50 // Rename renames an object from one path to another. | 54 // Rename renames an object from one path to another. |
| 51 // | 55 // |
| 52 // NOTE: The object should be removed from its original path, but curren
t | 56 // NOTE: The object should be removed from its original path, but curren
t |
| 53 // implementation uses two operations (Copy + Delete), so it may | 57 // implementation uses two operations (Copy + Delete), so it may |
| 54 // occasionally fail. | 58 // occasionally fail. |
| 55 Rename(src, dst Path) error | 59 Rename(src, dst Path) error |
| 56 } | 60 } |
| 57 | 61 |
| 58 // Options are the set of extra options to apply to the Google Storage request. | |
| 59 type Options struct { | |
| 60 // From is the range request starting index. If >0, the beginning of the | |
| 61 // range request will be set. | |
| 62 From int64 | |
| 63 // To is the range request ending index. If >0, the end of the | |
| 64 // range request will be set. | |
| 65 // | |
| 66 // If no From index is set, this will result in a request indexed from t
he end | |
| 67 // of the object. | |
| 68 To int64 | |
| 69 } | |
| 70 | |
| 71 // prodGSObject is an implementation of Client interface using the production | 62 // prodGSObject is an implementation of Client interface using the production |
| 72 // Google Storage client. | 63 // Google Storage client. |
| 73 type prodClient struct { | 64 type prodClient struct { |
| 74 context.Context | 65 context.Context |
| 75 | 66 |
| 76 // rt is the RoundTripper to use, or nil for the cloud service default. | 67 // rt is the RoundTripper to use, or nil for the cloud service default. |
| 77 rt http.RoundTripper | 68 rt http.RoundTripper |
| 78 // baseClient is a basic Google Storage client instance. It is used for | 69 // baseClient is a basic Google Storage client instance. It is used for |
| 79 // operations that don't need custom header injections. | 70 // operations that don't need custom header injections. |
| 80 baseClient *gs.Client | 71 baseClient *gs.Client |
| (...skipping 28 matching lines...) Expand all Loading... |
| 109 } | 100 } |
| 110 | 101 |
| 111 return &prodWriter{ | 102 return &prodWriter{ |
| 112 Context: c, | 103 Context: c, |
| 113 client: c, | 104 client: c, |
| 114 bucket: bucket, | 105 bucket: bucket, |
| 115 relpath: filename, | 106 relpath: filename, |
| 116 }, nil | 107 }, nil |
| 117 } | 108 } |
| 118 | 109 |
| 119 func (c *prodClient) NewReader(p Path, o Options) (io.ReadCloser, error) { | 110 func (c *prodClient) NewReader(p Path, offset, length int64) (io.ReadCloser, err
or) { |
| 120 » if o.From < 0 { | 111 » if offset < 0 { |
| 121 » » o.From = 0 | 112 » » panic(fmt.Errorf("offset (%d) must be >= 0", offset)) |
| 122 » } | |
| 123 » if o.To <= 0 { | |
| 124 » » o.To = -1 | |
| 125 } | 113 } |
| 126 | 114 |
| 127 obj, err := c.handleForPath(p) | 115 obj, err := c.handleForPath(p) |
| 128 if err != nil { | 116 if err != nil { |
| 129 return nil, err | 117 return nil, err |
| 130 } | 118 } |
| 131 » return obj.NewRangeReader(c, o.From, o.To) | 119 » return obj.NewRangeReader(c, offset, length) |
| 132 } | 120 } |
| 133 | 121 |
| 134 func (c *prodClient) Rename(src, dst Path) error { | 122 func (c *prodClient) Rename(src, dst Path) error { |
| 135 srcObj, err := c.handleForPath(src) | 123 srcObj, err := c.handleForPath(src) |
| 136 if err != nil { | 124 if err != nil { |
| 137 return fmt.Errorf("invalid source path: %s", err) | 125 return fmt.Errorf("invalid source path: %s", err) |
| 138 } | 126 } |
| 139 | 127 |
| 140 dstObj, err := c.handleForPath(dst) | 128 dstObj, err := c.handleForPath(dst) |
| 141 if err != nil { | 129 if err != nil { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 // The storage library doesn't return gs.ErrObjectNotExist when Delete | 230 // The storage library doesn't return gs.ErrObjectNotExist when Delete |
| 243 // returns a 404. Catch that explicitly. | 231 // returns a 404. Catch that explicitly. |
| 244 if t, ok := err.(*googleapi.Error); ok { | 232 if t, ok := err.(*googleapi.Error); ok { |
| 245 switch t.Code { | 233 switch t.Code { |
| 246 case http.StatusNotFound: | 234 case http.StatusNotFound: |
| 247 return true | 235 return true |
| 248 } | 236 } |
| 249 } | 237 } |
| 250 return false | 238 return false |
| 251 } | 239 } |
| OLD | NEW |