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") }