gitea-attachements-proxy/main.go

171 lines
4.2 KiB
Go

package main
import (
"code.gitea.io/sdk/gitea"
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/recover"
jsoniter "github.com/json-iterator/go"
"github.com/kpango/glg"
"sync"
)
var json = jsoniter.ConfigCompatibleWithStandardLibrary
type Channel int
const (
Stable Channel = iota
Prerelease
)
type Attachement struct {
User string
Repo string
Tag string
Filename string
Channel Channel
}
type RegionCounter struct {
RegionCount map[string]int
sync.RWMutex
}
const giteaURL = "https://git.entr0py.de"
func getAttachementURL(attachement Attachement) (string, error) {
client, err := gitea.NewClient(giteaURL)
if err != nil {
return "", fmt.Errorf("Failed to create gitea client: %v")
}
var release *gitea.Release
if attachement.Tag != "" {
release, _, err = client.GetReleaseByTag(attachement.User, attachement.Repo, attachement.Tag)
if err != nil {
return "", fmt.Errorf("Failed to get release by tag: %v")
}
} else {
isPrerelease := false
if attachement.Channel == Prerelease {
isPrerelease = true
}
releases, _, err := client.ListReleases(attachement.User, attachement.Repo, gitea.ListReleasesOptions{IsPreRelease: &isPrerelease})
if err != nil {
return "", fmt.Errorf("Failed to get releases: %v")
}
if len(releases) == 0 {
return "", fmt.Errorf("no release found")
}
release = releases[0]
}
for _, a := range release.Attachments {
if a.Name == attachement.Filename {
return a.DownloadURL, nil
}
}
return "", fmt.Errorf("no matching attachement found")
}
func (r *RegionCounter) countRegion(region string) {
glg.Debugf("Region %s", region)
r.Lock()
defer r.Unlock()
if region == "" {
return
}
val, ok := r.RegionCount[region]
if !ok {
r.RegionCount[region] = 1
return
}
r.RegionCount[region] = val + 1
}
func main() {
regionCounter := &RegionCounter{
RegionCount: make(map[string]int),
}
app := fiber.New(fiber.Config{
GETOnly: true,
ServerHeader: "Fiber",
AppName: "Gitea Attachement Proxy",
JSONEncoder: jsoniter.Marshal,
JSONDecoder: jsoniter.Unmarshal,
})
app.Use(recover.New())
app.Get("/:user/:repo/releases/download/latest/:name", func(c *fiber.Ctx) error {
glg.Debugf("%+v", map[string]string{"user": c.Params("user"), "repo": c.Params("repo"), "name": c.Params("name")})
attachement := Attachement{
User: c.Params("user"),
Repo: c.Params("repo"),
Filename: c.Params("name"),
Channel: Stable,
}
url, err := getAttachementURL(attachement)
if err != nil {
glg.Debug(err)
c.SendString(err.Error())
c.SendStatus(404)
return nil
}
go regionCounter.countRegion(c.GetReqHeaders()["Fly-Region"])
c.Redirect(url, 307)
return nil
})
app.Get("/:user/:repo/releases/download/latest\\::channel/:name", func(c *fiber.Ctx) error {
glg.Debugf("%+v", map[string]string{"user": c.Params("user"), "repo": c.Params("repo"), "name": c.Params("name"), "channel": c.Params("channel")})
channel := Stable
if c.Params("channel") == "prerelease" {
channel = Prerelease
}
attachement := Attachement{
User: c.Params("user"),
Repo: c.Params("repo"),
Filename: c.Params("name"),
Channel: channel,
}
url, err := getAttachementURL(attachement)
if err != nil {
glg.Debug(err)
c.SendString(err.Error())
c.SendStatus(404)
return nil
}
go regionCounter.countRegion(c.GetReqHeaders()["Fly-Region"])
c.Redirect(url, 307)
return nil
})
app.Get("/:user/:repo/releases/download/tag\\::tag/:name", func(c *fiber.Ctx) error {
glg.Debugf("%+v", map[string]string{"user": c.Params("user"), "repo": c.Params("repo"), "name": c.Params("name"), "tag": c.Params("tag")})
attachement := Attachement{
User: c.Params("user"),
Repo: c.Params("repo"),
Filename: c.Params("name"),
Tag: c.Params("tag"),
}
url, err := getAttachementURL(attachement)
if err != nil {
glg.Debug(err)
c.SendString(err.Error())
c.SendStatus(404)
return nil
}
go regionCounter.countRegion(c.GetReqHeaders()["Fly-Region"])
c.Redirect(url, 307)
return nil
})
app.Get("/regions", func(c *fiber.Ctx) error {
regionCounter.RLock()
defer regionCounter.RUnlock()
return c.JSON(regionCounter.RegionCount)
})
app.Listen(":8080")
}