-
Notifications
You must be signed in to change notification settings - Fork 0
/
http.go
118 lines (83 loc) · 1.96 KB
/
http.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
109
110
111
112
113
114
115
116
117
118
package reader
import (
"context"
"fmt"
"io"
"log/slog"
"net/http"
"net/url"
"path/filepath"
"strings"
"time"
"github.com/whosonfirst/go-ioutil"
wof_reader "github.com/whosonfirst/go-reader"
)
type GitHubReader struct {
wof_reader.Reader
owner string
repo string
branch string
prefix string
throttle <-chan time.Time
}
func init() {
ctx := context.Background()
err := wof_reader.RegisterReader(ctx, "github", NewGitHubReader)
if err != nil {
panic(err)
}
}
func NewGitHubReader(ctx context.Context, uri string) (wof_reader.Reader, error) {
u, err := url.Parse(uri)
if err != nil {
return nil, fmt.Errorf("Failed to parse URI, %w", err)
}
rate := time.Second / 3
throttle := time.Tick(rate)
r := &GitHubReader{
throttle: throttle,
}
r.owner = u.Host
path := strings.TrimLeft(u.Path, "/")
parts := strings.Split(path, "/")
if len(parts) != 1 {
return nil, fmt.Errorf("Invalid path")
}
r.repo = parts[0]
r.branch = DEFAULT_BRANCH
q := u.Query()
branch := q.Get("branch")
if branch != "" {
r.branch = branch
}
prefix := q.Get("prefix")
if prefix != "" {
r.prefix = prefix
}
return r, nil
}
func (r *GitHubReader) Read(ctx context.Context, uri string) (io.ReadSeekCloser, error) {
<-r.throttle
logger := slog.Default()
logger = logger.With("uri", uri)
url := r.ReaderURI(ctx, uri)
logger.Debug("Read URL", "url", url)
rsp, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("Failed to GET uri, %w", err)
}
if rsp.StatusCode != 200 {
return nil, fmt.Errorf("Unexpected status: %s", rsp.Status)
}
fh, err := ioutil.NewReadSeekCloser(rsp.Body)
if err != nil {
return nil, fmt.Errorf("Failed to create ReadSeekCloser, %w", err)
}
return fh, nil
}
func (r *GitHubReader) ReaderURI(ctx context.Context, key string) string {
if r.prefix != "" {
key = filepath.Join(r.prefix, key)
}
return fmt.Sprintf("https://raw.githubusercontent.com/%s/%s/%s/%s", r.owner, r.repo, r.branch, key)
}