forked from lxfontes/s3dir
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paths3dir.go
100 lines (83 loc) · 1.96 KB
/
s3dir.go
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
package s3dir
import (
"errors"
"net/http"
"os"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3iface"
)
var (
ErrNotImplemented = errors.New("Not implemented")
)
type Bucket struct {
s3 s3iface.S3API
bucket *string
config BucketConfig
}
type BucketConfig struct {
Region string
BucketName string
BucketPrefix string
}
func NewBucket(cfg BucketConfig) (*Bucket, error) {
if "" != cfg.BucketPrefix && !strings.HasPrefix(cfg.BucketPrefix, "/") {
cfg.BucketPrefix = "/" + cfg.BucketPrefix
}
sess := session.Must(session.NewSession(&aws.Config{
Region: aws.String(cfg.Region),
//LogLevel: aws.LogLevel(aws.LogDebug),
}))
b := &Bucket{
s3: s3.New(sess),
bucket: aws.String(cfg.BucketName),
config: cfg,
}
params := &s3.HeadBucketInput{
Bucket: b.bucket,
}
if _, err := b.s3.HeadBucket(params); err != nil {
return nil, err
}
return b, nil
}
func (b *Bucket) Open(path string) (http.File, error) {
if b.config.BucketPrefix != "" && !strings.HasPrefix(path, b.config.BucketPrefix) {
path = b.config.BucketPrefix + path
}
prefix := strings.TrimPrefix(path, "/")
if len(prefix) > 0 && !strings.HasSuffix(prefix, "/") {
prefix += "/"
}
input := &s3.ListObjectsInput{
Bucket: b.bucket,
Prefix: &prefix,
Delimiter: aws.String("/"),
}
l, err := b.s3.ListObjects(input)
if err != nil {
return nil, err
}
if len(l.CommonPrefixes) > 0 || len(l.Contents) > 0 {
return NewDir(b, prefix, l), nil
}
// This is an actual object. Get it
params := &s3.GetObjectInput{
Bucket: b.bucket,
Key: aws.String(path),
}
resp, err := b.s3.GetObject(params)
if err != nil {
if awsErr, ok := err.(awserr.Error); ok {
switch awsErr.Code() {
case s3.ErrCodeNoSuchKey:
return nil, os.ErrNotExist
}
}
return nil, err
}
return NewFile(b, path, resp), nil
}