Attributes returns attributes for the blob stored at key. If the blob does not exist, Attributes returns an error for which gcerrors.Code will return gcerrors.NotFound.
(ctx context.Context, key string)
| 961 | // If the blob does not exist, Attributes returns an error for which |
| 962 | // gcerrors.Code will return gcerrors.NotFound. |
| 963 | func (b *Bucket) Attributes(ctx context.Context, key string) (_ *Attributes, err error) { |
| 964 | if !utf8.ValidString(key) { |
| 965 | return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "blob: Attributes key must be a valid UTF-8 string: %q", key) |
| 966 | } |
| 967 | |
| 968 | b.mu.RLock() |
| 969 | defer b.mu.RUnlock() |
| 970 | if b.closed { |
| 971 | return nil, errClosed |
| 972 | } |
| 973 | ctx, span := b.tracer.Start(ctx, "Attributes") |
| 974 | defer func() { b.tracer.End(ctx, span, err) }() |
| 975 | |
| 976 | a, err := b.b.Attributes(ctx, key) |
| 977 | if err != nil { |
| 978 | return nil, wrapError(b.b, err, key) |
| 979 | } |
| 980 | var md map[string]string |
| 981 | if len(a.Metadata) > 0 { |
| 982 | // Services are inconsistent, but at least some treat keys |
| 983 | // as case-insensitive. To make the behavior consistent, we |
| 984 | // force-lowercase them when writing and reading. |
| 985 | md = make(map[string]string, len(a.Metadata)) |
| 986 | for k, v := range a.Metadata { |
| 987 | md[strings.ToLower(k)] = v |
| 988 | } |
| 989 | } |
| 990 | return &Attributes{ |
| 991 | CacheControl: a.CacheControl, |
| 992 | ContentDisposition: a.ContentDisposition, |
| 993 | ContentEncoding: a.ContentEncoding, |
| 994 | ContentLanguage: a.ContentLanguage, |
| 995 | ContentType: a.ContentType, |
| 996 | Metadata: md, |
| 997 | CreateTime: a.CreateTime, |
| 998 | ModTime: a.ModTime, |
| 999 | Size: a.Size, |
| 1000 | MD5: a.MD5, |
| 1001 | ETag: a.ETag, |
| 1002 | asFunc: a.AsFunc, |
| 1003 | }, nil |
| 1004 | } |
| 1005 | |
| 1006 | // NewReader is a shortcut for NewRangeReader with offset=0 and length=-1. |
| 1007 | func (b *Bucket) NewReader(ctx context.Context, key string, opts *ReaderOptions) (*Reader, error) { |