@@ -2,6 +2,7 @@ package main
2
2
3
3
import (
4
4
"bytes"
5
+ "encoding/json"
5
6
"errors"
6
7
"flag"
7
8
"fmt"
@@ -19,11 +20,42 @@ import (
19
20
"github.com/barelyhuman/goblin/resolver"
20
21
"github.com/barelyhuman/goblin/storage"
21
22
"github.com/joho/godotenv"
23
+ "go.uber.org/ratelimit"
22
24
)
23
25
24
26
var shTemplates * template.Template
25
27
var serverURL string
26
28
var storageClient storage.Storage
29
+ var rateLimiter ratelimit.Limiter
30
+
31
+ type ErrorJSON struct {
32
+ Success bool `json:"success"`
33
+ Message string `json:"message"`
34
+ }
35
+
36
+ func (ej ErrorJSON ) toJSONString () (string , error ) {
37
+ marshaled , err := json .Marshal (ej )
38
+ if err != nil {
39
+ return "" , err
40
+ }
41
+ return string (marshaled ), nil
42
+ }
43
+
44
+ type VersionJSON struct {
45
+ Success bool `json:"success"`
46
+ Package string `json:"package"`
47
+ Binary string `json:"binary"`
48
+ OriginalVersion string `json:"originalVersion"`
49
+ Version string `json:"version"`
50
+ }
51
+
52
+ func (ej VersionJSON ) toJSONString () (string , error ) {
53
+ marshaled , err := json .Marshal (ej )
54
+ if err != nil {
55
+ return "" , err
56
+ }
57
+ return string (marshaled ), nil
58
+ }
27
59
28
60
func HandleRequest (rw http.ResponseWriter , req * http.Request ) {
29
61
path := req .URL .Path
@@ -41,6 +73,13 @@ func HandleRequest(rw http.ResponseWriter, req *http.Request) {
41
73
return
42
74
}
43
75
76
+ if strings .HasPrefix (path , "/version" ) {
77
+ log .Println ("Resolving version" )
78
+ rateLimiter .Take ()
79
+ resolveVersionJSON (rw , req )
80
+ return
81
+ }
82
+
44
83
if strings .HasPrefix (path , "/binary" ) {
45
84
log .Print ("handle binary" )
46
85
fetchBinary (rw , req )
@@ -75,6 +114,9 @@ func main() {
75
114
76
115
flag .Parse ()
77
116
117
+ // starting off with 250 since there's only one operation that's being rate limited
118
+ rateLimiter = ratelimit .New (250 )
119
+
78
120
if _ , err := os .Stat (* envFile ); ! errors .Is (err , os .ErrNotExist ) {
79
121
err := godotenv .Load ()
80
122
if err != nil {
@@ -225,6 +267,36 @@ func fetchInstallScript(rw http.ResponseWriter, req *http.Request) {
225
267
})
226
268
}
227
269
270
+ func resolveVersionJSON (rw http.ResponseWriter , req * http.Request ) {
271
+ // only reply in JSON
272
+ rw .Header ().Set ("Content-Type" , "application/json" )
273
+
274
+ pkg := strings .TrimPrefix (req .URL .Path , "/version" )
275
+ pkg , _ , version , name := parsePackage (pkg )
276
+ v := & resolver.Resolver {
277
+ Pkg : pkg ,
278
+ }
279
+ v .ParseVersion (version )
280
+ resolvedVersion , err := v .ResolveVersion ()
281
+ if err != nil || len (resolvedVersion ) == 0 {
282
+ errorJson , _ := ErrorJSON {Success : false , Message : "Failed to resolve version:" + version }.toJSONString ()
283
+ rw .Write ([]byte (errorJson ))
284
+ return
285
+ }
286
+
287
+ responseJson , _ := VersionJSON {
288
+ Success : true ,
289
+ Package : pkg ,
290
+ Binary : name ,
291
+ OriginalVersion : version ,
292
+ Version : resolvedVersion ,
293
+ }.toJSONString ()
294
+
295
+ rw .Write ([]byte (responseJson ))
296
+ return
297
+
298
+ }
299
+
228
300
func fetchBinary (rw http.ResponseWriter , req * http.Request ) {
229
301
pkg := strings .TrimPrefix (req .URL .Path , "/binary/" )
230
302
0 commit comments