GetObject retrieves an object from Swift storage.
( ctx context.Context, reqHeader http.Header, bucket, name, _ string, )
| 15 | |
| 16 | // GetObject retrieves an object from Swift storage. |
| 17 | func (s *Storage) GetObject( |
| 18 | ctx context.Context, reqHeader http.Header, bucket, name, _ string, |
| 19 | ) (*storage.ObjectReader, error) { |
| 20 | // If either bucket or object key is empty, return 404 |
| 21 | if len(bucket) == 0 || len(name) == 0 { |
| 22 | return storage.NewObjectNotFound( |
| 23 | "invalid Swift URL: bucket name or object name are empty", |
| 24 | ), nil |
| 25 | } |
| 26 | |
| 27 | // Check if access to the container is allowed |
| 28 | if !common.IsBucketAllowed(bucket, s.config.AllowedBuckets, s.config.DeniedBuckets) { |
| 29 | return nil, fmt.Errorf("access to the Swift bucket %s is denied", bucket) |
| 30 | } |
| 31 | |
| 32 | // Copy if-modified-since, if-none-match and range headers from |
| 33 | // the original request. They act as the parameters for this storage. |
| 34 | h := make(swift.Headers) |
| 35 | |
| 36 | for _, k := range []string{ |
| 37 | httpheaders.Range, // Range for partial requests |
| 38 | httpheaders.IfNoneMatch, // If-None-Match for caching |
| 39 | httpheaders.IfModifiedSince, // If-Modified-Since for caching |
| 40 | } { |
| 41 | v := reqHeader.Get(k) |
| 42 | if len(v) > 0 { |
| 43 | h[k] = v |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | // Fetch the object from Swift |
| 48 | obj, objectHeaders, err := s.connection.ObjectOpen(ctx, bucket, name, false, h) |
| 49 | |
| 50 | // Convert Swift response headers to normal headers (if any) |
| 51 | header := make(http.Header) |
| 52 | for k, v := range objectHeaders { |
| 53 | header.Set(k, v) |
| 54 | } |
| 55 | |
| 56 | if err != nil { |
| 57 | // Handle not found errors gracefully |
| 58 | if errors.Is(err, swift.ObjectNotFound) || errors.Is(err, swift.ContainerNotFound) { |
| 59 | return storage.NewObjectNotFound(err.Error()), nil |
| 60 | } |
| 61 | |
| 62 | // Same for NotModified |
| 63 | if errors.Is(err, swift.NotModified) { |
| 64 | return storage.NewObjectNotModified(header), nil |
| 65 | } |
| 66 | |
| 67 | return nil, fmt.Errorf("error opening swift object: %w", err) |
| 68 | } |
| 69 | |
| 70 | // Range header: means partial content |
| 71 | partial := len(reqHeader.Get(httpheaders.Range)) > 0 |
| 72 | |
| 73 | // By default, Swift storage handles this. |
| 74 | // Just in case, let's double check. |
nothing calls this directly
no test coverage detected