-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkodofs.go
105 lines (85 loc) · 2.58 KB
/
kodofs.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
101
102
103
104
105
package kodofs
import (
"context"
"io/fs"
"log"
"net/http"
"os"
"path"
"strings"
xfs "github.com/qiniu/x/http/fs"
"github.com/xushiwei/kodofs/kodo"
)
var (
debugNet bool
)
const (
DbgFlagNetwork = kodo.DbgFlagNetwork
DbgFlagAll = kodo.DbgFlagAll
)
func SetDebug(dbgFlags int) {
debugNet = (dbgFlags & DbgFlagNetwork) != 0
kodo.SetDebug(dbgFlags)
}
// -----------------------------------------------------------------------------------------
type Credentials kodo.Credentials
func NewCredentials(accessKey, secretKey string) *Credentials {
return (*Credentials)(kodo.NewCredentials(accessKey, secretKey))
}
// -----------------------------------------------------------------------------------------
type PrepareOpen = func(name string) (ctx context.Context, opener xfs.HttpOpener)
func simplePrepareOpen(name string) (ctx context.Context, opener xfs.HttpOpener) {
ctx = context.Background()
return
}
// -----------------------------------------------------------------------------------------
type Bucket struct {
bkt *kodo.Bucket
prepare PrepareOpen
host string
}
func (mac *Credentials) NewBucket(bucket string, host string, prepare PrepareOpen) *Bucket {
if prepare == nil {
prepare = simplePrepareOpen
}
auth := (*kodo.Credentials)(mac)
bkt := auth.NewBucket(bucket)
host = strings.TrimSuffix(host, "/")
return &Bucket{bkt, prepare, host}
}
// Open implements net/http.FileSystem.Open (https://pkg.go.dev/net/http#FileSystem).
func (b *Bucket) Open(name string) (f http.File, err error) {
ctx, opener := b.prepare(name)
if name != "/" {
f, err = opener.Open(ctx, b.host+name)
if debugNet {
log.Println("kodofs.Open:", name, "err:", err)
}
if err == nil || isIndexPage(name) || !os.IsNotExist(err) {
return
}
}
fis, err := b.bkt.ReaddirContext(ctx, name)
if err != nil {
return
}
if len(fis) == 0 {
return nil, fs.ErrNotExist
}
fname := path.Base(name)
return xfs.Dir(xfs.NewDirInfo(fname), fis), nil
}
func isIndexPage(name string) bool {
return strings.HasSuffix(name, "/index.html")
}
func (b *Bucket) ReaddirContext(ctx context.Context, dir string) (fis []fs.FileInfo, err error) {
return b.bkt.ReaddirContext(ctx, dir)
}
// -----------------------------------------------------------------------------------------
func New(accessKey, secretKey string, bucket string, host string, prepare PrepareOpen) *Bucket {
if debugNet {
log.Println("kodofs.New:", bucket, host)
}
return NewCredentials(accessKey, secretKey).NewBucket(bucket, host, prepare)
}
// -----------------------------------------------------------------------------------------