-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
helpers.go
108 lines (90 loc) · 1.88 KB
/
helpers.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
106
107
108
package singlepage
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
"zgo.at/zstd/zstring"
)
// LookupError is used when we can't look up a resource. This may be a non-fatal
// error.
type LookupError struct {
Path string
Err error
}
func (e *LookupError) Error() string { return e.Err.Error() }
// ParseError indicates there was a parsing failure. This may be a non-fatal
// error.
type ParseError struct {
Path string
Err error
}
func (e *ParseError) Error() string { return e.Err.Error() }
// Report if a path is remote.
func isRemote(path string) bool {
return strings.HasPrefix(path, "http://") ||
strings.HasPrefix(path, "https://") ||
strings.HasPrefix(path, "//")
}
// warn about an error.
func warn(opts Options, err error) (bool, error) {
switch err.(type) {
case nil:
return true, nil
case *LookupError, *ParseError:
if opts.Strict {
return false, err
}
if !opts.Quiet {
_, _ = fmt.Fprintf(os.Stderr, "singlepage: warning: %s\n", err)
}
return false, nil
default:
return false, err
}
}
// Read a path, which may be either local or HTTP.
func readPath(path string) ([]byte, error) {
if !isRemote(path) {
if strings.HasPrefix(path, "/") {
path = "." + path
}
d, err := os.ReadFile(path)
if err != nil {
return nil, &LookupError{
Path: path,
Err: err,
}
}
return d, nil
}
if strings.HasPrefix(path, "//") {
path = "https:" + path
}
c := http.Client{Timeout: 5 * time.Second}
resp, err := c.Get(path)
if err != nil {
return nil, &LookupError{
Path: path,
Err: err,
}
}
defer resp.Body.Close()
d, err := io.ReadAll(resp.Body)
if err != nil {
return nil, &LookupError{
Path: path,
Err: err,
}
}
if resp.StatusCode != 200 {
return nil, &LookupError{
Path: path,
Err: fmt.Errorf("%d %s: %s", resp.StatusCode, resp.Status,
zstring.ElideLeft(string(d), 100)),
}
}
return d, nil
}