-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathmount.go
More file actions
132 lines (109 loc) · 2.82 KB
/
mount.go
File metadata and controls
132 lines (109 loc) · 2.82 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package diecast
import (
"errors"
"fmt"
"io"
"net"
"net/http"
"net/url"
"path/filepath"
"strings"
"github.com/ghetzel/go-stockutil/log"
"github.com/ghetzel/go-stockutil/stringutil"
)
type MountConfig struct {
Mount string `yaml:"mount" json:"mount"` // The URL path that this mount will respond to
To string `yaml:"to" json:"to"` // The upstream URL or local filesystem path that will serve this path
Options map[string]any `yaml:"options" json:"options"` // Mount-specific options
}
var ErrMountHalt = errors.New(`mount halted`)
type Mount interface {
Open(string) (http.File, error)
OpenWithType(string, *http.Request, io.Reader) (*MountResponse, error)
WillRespondTo(string, *http.Request, io.Reader) bool
GetMountPoint() string
GetTarget() string
}
func NewMountFromSpec(spec string) (Mount, error) {
mountPoint, source := stringutil.SplitPair(spec, `:`)
if source == `` {
source = mountPoint
}
scheme, _ := stringutil.SplitPair(source, `:`)
var mount Mount
switch scheme {
case `http`, `https`:
mount = &ProxyMount{
URL: source,
MountPoint: mountPoint,
}
case `s3`, `aws+s3`:
mount = &S3Mount{
MountPoint: mountPoint,
Path: strings.TrimPrefix(source, scheme+`://`),
}
default:
if absPath, err := filepath.Abs(source); err == nil {
source = absPath
} else {
return nil, err
}
mount = &FileMount{
Path: source,
MountPoint: mountPoint,
}
}
return mount, nil
}
func mountSummary(mount Mount) string {
var mtype = fmt.Sprintf("%T", mount)
mtype = strings.TrimPrefix(mtype, `*diecast.`)
mtype = strings.TrimSuffix(mtype, `Mount`)
mtype = strings.ToLower(mtype)
return fmt.Sprintf("%s: %s -> %s", mtype, mount.GetMountPoint(), mount.GetTarget())
}
func IsSameMount(first Mount, second Mount) bool {
if first != nil {
if second != nil {
if first.GetMountPoint() == second.GetMountPoint() {
if first.GetTarget() == second.GetTarget() {
return true
}
}
}
}
return false
}
func IsHardStop(err error) bool {
if err == ErrMountHalt {
return true
} else if _, ok := err.(*url.Error); ok {
return true
} else if _, ok := err.(net.Error); ok {
return true
} else if log.ErrContains(err, `request canceled`) {
return true
} else if log.ErrContains(err, `x509:`) {
return true
} else if log.ErrHasPrefix(err, `dial `) {
return true
}
return false
}
func IsDirectoryError(err error) bool {
if err != nil && err.Error() == `is a directory` {
return true
}
return false
}
func openAsHttpFile(mount Mount, name string) (http.File, error) {
if file, err := mount.OpenWithType(name, nil, nil); err == nil {
if hfile, ok := file.GetPayload().(http.File); ok && hfile != nil {
return hfile, nil
} else {
return nil, fmt.Errorf("wrong response type")
}
} else {
return nil, err
}
}