-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrequest.go
184 lines (168 loc) · 3.49 KB
/
request.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
package main
import (
"encoding/base64"
"fmt"
"path"
"strings"
)
type page int
const (
pageIndex page = iota
pageLog
pageDownloadRedirect
pageDownload
pageDownloadGz
pageRecord
pageEvents
pageRetry
)
func (p page) String() string {
switch p {
case pageIndex:
return "index"
case pageLog:
return "log"
case pageDownloadRedirect:
return "dlredir"
case pageDownload:
return "download"
case pageDownloadGz:
return "downloadgz"
case pageRecord:
return "record"
case pageEvents:
return "events"
case pageRetry:
return "retry"
}
panic("missing case")
}
type request struct {
buildSpec
Sum string // Empty for build instead of result requests.
Page page
}
// Path in URL for this request, for linking to other pages.
func (r request) link() string {
var variant string
if r.Stripped {
variant = "-stripped"
}
s := fmt.Sprintf("/%s@%s/%s%s-%s-%s%s/", r.Mod, r.Version, r.appendDir(), r.Goos, r.Goarch, r.Goversion, variant)
if r.Sum != "" {
s += r.Sum + "/"
}
s += r.pagePart()
return s
}
func (r request) pagePart() string {
switch r.Page {
case pageIndex:
return ""
case pageLog:
return "log"
case pageDownloadRedirect:
return "dl"
case pageDownload:
return r.downloadFilename()
case pageDownloadGz:
return r.downloadFilename() + ".gz"
case pageRecord:
return "record"
case pageEvents:
return "events"
case pageRetry:
return "retry"
default:
panic("missing case")
}
}
// Name of file the browser will save the file as.
func (r request) downloadFilename() string {
var name string
if r.Dir != "/" {
name = path.Base(r.Dir)
} else {
name = path.Base(r.Mod)
}
ext := ""
if r.Goos == "windows" {
ext = ".exe"
}
var variant string
if r.Stripped {
variant = "-stripped"
}
return fmt.Sprintf("%s-%s-%s%s%s", name, r.Version, r.Goversion, variant, ext)
}
func isSum(s string) bool {
if !strings.HasPrefix(s, "0") {
return false
}
buf, err := base64.RawURLEncoding.DecodeString(s[1:])
if err != nil {
return false
}
return len(buf) == 20
}
// We'll get paths like /github.com/mjl-/[email protected]/cmd/sherpaclient/linux-amd64-go1.14.1/0m32pSahHbf-fptQdDyWD87GJNXI/{log,dl,<name>,<name>.gz,record,events,retry}
// with optional sum.
func parseRequest(s string) (r request, hint string, ok bool) {
if s == "" {
return
}
t := strings.Split(s[1:], "/")
// Look for a page-part and take it off.
var page string
if t[len(t)-1] == "" {
t = t[:len(t)-1]
} else {
page = t[len(t)-1]
t = t[:len(t)-1]
}
if len(t) > 2 && isSum(t[len(t)-1]) {
r.Sum = t[len(t)-1]
t = t[:len(t)-1]
}
if len(t) < 2 {
hint = "Missing goos-goarch-goversion at end of path"
return
}
// Now we have a regular buildspec left.
if bs, err := parseBuildSpec(strings.Join(t, "/") + "/"); err != nil {
hint = "Bad module@version/path: " + err.Error() + ", or missing slash at end of URL"
return
} else {
r.buildSpec = bs
}
switch page {
case "":
r.Page = pageIndex
case "log":
r.Page = pageLog
case "dl":
r.Page = pageDownloadRedirect
case "record":
r.Page = pageRecord
case "events":
r.Page = pageEvents
case "retry":
r.Page = pageRetry
default:
dl := r.downloadFilename()
if page == dl {
r.Page = pageDownload
} else if page == dl+".gz" {
r.Page = pageDownloadGz
} else {
hint = "Missing slash at end of URL or unknown build/result page"
return
}
}
if r.Sum != "" && (r.Page == pageEvents || r.Page == pageRetry) {
hint = fmt.Sprintf("No %s endpoint for results", r.Page.String())
return
}
ok = true
return
}