|
@@ -0,0 +1,105 @@
|
|
1
|
+package main
|
|
2
|
+
|
|
3
|
+import (
|
|
4
|
+ "context"
|
|
5
|
+ "flag"
|
|
6
|
+ "fmt"
|
|
7
|
+ "github.com/google/go-github/github"
|
|
8
|
+ "log"
|
|
9
|
+ "net/http"
|
|
10
|
+ "os"
|
|
11
|
+ "os/signal"
|
|
12
|
+ "strings"
|
|
13
|
+ "syscall"
|
|
14
|
+ "time"
|
|
15
|
+)
|
|
16
|
+
|
|
17
|
+var (
|
|
18
|
+ owner string
|
|
19
|
+ repo string
|
|
20
|
+ ctx context.Context
|
|
21
|
+ client *github.Client
|
|
22
|
+ release *github.RepositoryRelease
|
|
23
|
+)
|
|
24
|
+
|
|
25
|
+func fetchLatest() {
|
|
26
|
+ latest, _, err := client.Repositories.GetLatestRelease(ctx, owner, repo)
|
|
27
|
+ if err != nil {
|
|
28
|
+ log.Println("Error retrieving latest release", err)
|
|
29
|
+ return
|
|
30
|
+ }
|
|
31
|
+ release = latest
|
|
32
|
+}
|
|
33
|
+
|
|
34
|
+func serve(w http.ResponseWriter, request *http.Request) {
|
|
35
|
+ if release == nil {
|
|
36
|
+ w.WriteHeader(http.StatusInternalServerError)
|
|
37
|
+ _, _ = fmt.Fprint(w, "Unknown release")
|
|
38
|
+ return
|
|
39
|
+ }
|
|
40
|
+
|
|
41
|
+ for _, asset := range release.Assets {
|
|
42
|
+ if "/" + *asset.Name == request.RequestURI {
|
|
43
|
+ w.Header().Add("Location", *asset.BrowserDownloadURL)
|
|
44
|
+ w.WriteHeader(http.StatusTemporaryRedirect)
|
|
45
|
+ return
|
|
46
|
+ }
|
|
47
|
+ }
|
|
48
|
+
|
|
49
|
+ w.WriteHeader(http.StatusNotFound)
|
|
50
|
+ _, _ = fmt.Fprint(w, "Asset not found in release ", *release.Name)
|
|
51
|
+}
|
|
52
|
+
|
|
53
|
+func main() {
|
|
54
|
+ var fullRepo = flag.String("repo", "", "the repository to redirect releases for, in user/repo format")
|
|
55
|
+ var port = flag.Int("port", 8080, "the port to listen on for HTTP requests")
|
|
56
|
+ flag.Parse()
|
|
57
|
+
|
|
58
|
+ if strings.Count(*fullRepo, "/") != 1 {
|
|
59
|
+ log.Println("Repository must be specified in user/repo format")
|
|
60
|
+ return
|
|
61
|
+ }
|
|
62
|
+
|
|
63
|
+ repoParts := strings.Split(*fullRepo, "/")
|
|
64
|
+ owner = repoParts[0]
|
|
65
|
+ repo = repoParts[1]
|
|
66
|
+
|
|
67
|
+ client = github.NewClient(nil)
|
|
68
|
+
|
|
69
|
+ ticker := time.NewTicker(time.Hour)
|
|
70
|
+ go func() {
|
|
71
|
+ fetchLatest()
|
|
72
|
+ for range ticker.C {
|
|
73
|
+ fetchLatest()
|
|
74
|
+ }
|
|
75
|
+ }()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+ var cancel context.CancelFunc
|
|
79
|
+ ctx, cancel = context.WithCancel(context.Background())
|
|
80
|
+
|
|
81
|
+ c := make(chan os.Signal, 1)
|
|
82
|
+ signal.Notify(c, os.Interrupt)
|
|
83
|
+ signal.Notify(c, syscall.SIGTERM)
|
|
84
|
+
|
|
85
|
+ go func() {
|
|
86
|
+ for sig := range c {
|
|
87
|
+ cancel()
|
|
88
|
+ ticker.Stop()
|
|
89
|
+ log.Printf("Received %s, exiting.", sig.String())
|
|
90
|
+ os.Exit(0)
|
|
91
|
+ }
|
|
92
|
+ }()
|
|
93
|
+
|
|
94
|
+ log.Printf("Listing on :%d", *port)
|
|
95
|
+
|
|
96
|
+ server := &http.Server{
|
|
97
|
+ Addr: fmt.Sprintf(":%d", *port),
|
|
98
|
+ Handler: http.HandlerFunc(serve),
|
|
99
|
+ }
|
|
100
|
+
|
|
101
|
+ err := server.ListenAndServe()
|
|
102
|
+ if err != nil {
|
|
103
|
+ log.Println("Error listening for requests on port ", port, err)
|
|
104
|
+ }
|
|
105
|
+}
|