-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathget.go
More file actions
111 lines (103 loc) · 2.83 KB
/
Copy pathget.go
File metadata and controls
111 lines (103 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package s3
import (
"context"
"fmt"
"os"
"path"
"strings"
"time"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/pkg/errors"
"github.com/viant/afs/file"
"github.com/viant/afs/option"
"github.com/viant/afs/option/content"
"github.com/viant/afs/storage"
)
// Get returns an object for supplied location
func (s *Storager) get(ctx context.Context, location string, options []storage.Option) (os.FileInfo, error) {
location = strings.Trim(location, "/")
_, name := path.Split(location)
object, err := s.HeadObject(context.Background(), &s3.HeadObjectInput{Bucket: &s.bucket,
Key: &location})
// object, err := s.GetObject(&s3.GetObjectInput{
// Bucket: &s.bucket,
// Key: &location,
// })
if err != nil {
return nil, err
}
hasObject := object != nil && (object.ContentLength != nil || object.LastModified != nil)
if !hasObject {
return nil, fmt.Errorf(noSuchKeyMessage + " " + location)
}
s.assignMetadataWithHead(options, object)
contentLength := int64(0)
modified := time.Now()
if object.LastModified != nil {
modified = *object.LastModified
}
if object.ContentLength != nil {
contentLength = *object.ContentLength
}
if err = s.presign(ctx, location, options); err != nil {
return nil, err
}
return file.NewInfo(name, contentLength, file.DefaultFileOsMode, modified, false, object), nil
}
func (s *Storager) assignMetadata(options []storage.Option, object *s3.GetObjectOutput) {
meta := &content.Meta{}
if _, ok := option.Assign(options, &meta); ok {
meta.Values = make(map[string]string)
if len(object.Metadata) > 0 {
for k, v := range object.Metadata {
value := ""
if v != "" {
value = v
}
meta.Values[k] = value
}
}
}
}
func (s *Storager) assignMetadataWithHead(options []storage.Option, object *s3.HeadObjectOutput) {
meta := &content.Meta{}
if _, ok := option.Assign(options, &meta); ok {
meta.Values = make(map[string]string)
if len(object.Metadata) > 0 {
for k, v := range object.Metadata {
value := ""
if v != "" {
value = v
}
meta.Values[k] = value
}
}
}
}
// Get returns an object for supplied location
func (s *Storager) Get(ctx context.Context, location string, options ...storage.Option) (os.FileInfo, error) {
started := time.Now()
defer func() {
s.logF("s3:Get %v %s\n", location, time.Since(started))
}()
location = strings.Trim(location, "/")
info, err := s.get(ctx, location, options)
if err == nil {
return info, err
}
if isNotFound(err) {
objectKind := &option.ObjectKind{}
if _, ok := option.Assign(options, &objectKind); ok && objectKind.File {
return nil, err
}
}
options = append(options, option.NewPage(0, 1))
objects, err := s.List(ctx, location, options...)
if err != nil {
return nil, err
}
if len(objects) == 0 {
return nil, errors.Errorf("%v %v", location, doesNotExistsMessage)
}
return objects[0], err
}