2022-11-06 04:34:34 +09:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2022-12-01 01:37:27 +09:00
|
|
|
"context"
|
2022-11-06 04:34:34 +09:00
|
|
|
"log"
|
|
|
|
|
2022-12-01 00:17:45 +09:00
|
|
|
"os"
|
|
|
|
|
2022-11-06 04:34:34 +09:00
|
|
|
"github.com/gofiber/fiber/v2"
|
|
|
|
|
|
|
|
"github.com/gofiber/template/html"
|
|
|
|
|
2022-12-01 02:49:43 +09:00
|
|
|
"codeberg.org/gothub/gothub/pages"
|
2022-11-06 04:34:34 +09:00
|
|
|
|
|
|
|
"github.com/gofiber/fiber/v2/middleware/cache"
|
|
|
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/gofiber/fiber/v2/middleware/proxy"
|
2022-11-30 01:59:04 +09:00
|
|
|
|
|
|
|
"github.com/gofiber/fiber/v2/middleware/compress"
|
|
|
|
|
|
|
|
"github.com/gofiber/fiber/v2/middleware/recover"
|
|
|
|
|
|
|
|
"github.com/gofiber/fiber/v2/middleware/limiter"
|
|
|
|
|
|
|
|
"html/template"
|
2022-12-01 01:37:27 +09:00
|
|
|
|
|
|
|
"github.com/carlmjohnson/requests"
|
2022-11-06 04:34:34 +09:00
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
engine := html.New("./views", ".html")
|
|
|
|
|
2022-11-30 01:59:04 +09:00
|
|
|
engine.AddFunc(
|
|
|
|
// add unescape function
|
|
|
|
"unescape", func(s string) template.HTML {
|
|
|
|
return template.HTML(s)
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
2022-11-06 04:34:34 +09:00
|
|
|
app := fiber.New(fiber.Config{
|
|
|
|
Views: engine,
|
2022-11-30 22:43:44 +09:00
|
|
|
Prefork: false,
|
2022-11-30 01:59:04 +09:00
|
|
|
AppName: "GotHub",
|
2022-11-30 05:53:25 +09:00
|
|
|
// fucked up way to fix rate limits
|
|
|
|
EnableTrustedProxyCheck: true,
|
|
|
|
TrustedProxies: []string{"0.0.0.0/0"},
|
|
|
|
ProxyHeader: fiber.HeaderXForwardedFor,
|
2022-11-06 04:34:34 +09:00
|
|
|
ErrorHandler: func(ctx *fiber.Ctx, err error) error {
|
|
|
|
code := fiber.StatusInternalServerError
|
|
|
|
|
|
|
|
if e, ok := err.(*fiber.Error); ok {
|
|
|
|
code = e.Code
|
|
|
|
}
|
|
|
|
|
|
|
|
err = ctx.Status(code).Render("error", fiber.Map{
|
|
|
|
"error": err,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
app.Use(cache.New(cache.Config{
|
2022-11-30 01:59:04 +09:00
|
|
|
Expiration: 5 * time.Minute,
|
2022-11-06 04:34:34 +09:00
|
|
|
}))
|
|
|
|
|
|
|
|
app.Get("/", func(c *fiber.Ctx) error {
|
|
|
|
return c.Render("index", fiber.Map{
|
|
|
|
"host": c.Hostname(),
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2022-11-30 01:59:04 +09:00
|
|
|
app.Use(compress.New(compress.Config{
|
|
|
|
Level: compress.LevelBestSpeed, // 1
|
|
|
|
}))
|
|
|
|
|
|
|
|
app.Use(recover.New())
|
|
|
|
|
|
|
|
ratelimiter := limiter.New(limiter.Config{
|
|
|
|
Max: 5,
|
|
|
|
Expiration: 5 * time.Minute,
|
|
|
|
LimitReached: func(c *fiber.Ctx) error {
|
|
|
|
return c.Status(429).Render("ratelimit_gt", fiber.Map{
|
|
|
|
"Title": "Rate limit exceeded",
|
|
|
|
})
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2022-11-06 04:34:34 +09:00
|
|
|
app.Static("/css", "./public/css")
|
|
|
|
app.Static("/fonts", "./public/fonts")
|
|
|
|
app.Static("/robots.txt", "./public/robots.txt")
|
2022-11-30 01:59:04 +09:00
|
|
|
app.Static("/favicon.ico", "./public/assets/favicon.ico")
|
|
|
|
app.Static("/logo.svg", "./public/assets/logo.svg")
|
|
|
|
app.Get("/explore", ratelimiter, pages.HandleExplore)
|
|
|
|
app.Get("/:user", ratelimiter, pages.HandleUser)
|
2022-11-30 23:08:16 +09:00
|
|
|
app.Get("/:user/:repo", ratelimiter, pages.HandleRepo)
|
2022-12-01 01:37:27 +09:00
|
|
|
app.Get("/file/:user/:repo/:branch/:file", func(c *fiber.Ctx) error {
|
|
|
|
var file string
|
|
|
|
url := "https://raw.githubusercontent.com/" + c.Params("user") + "/" + c.Params("repo") + "/" + c.Params("branch") + "/" + c.Params("file")
|
|
|
|
err := requests.
|
|
|
|
URL(url).
|
|
|
|
ToString(&file).
|
|
|
|
Fetch(context.Background())
|
|
|
|
if err != nil {
|
|
|
|
return c.Status(404).Render("error", fiber.Map{
|
|
|
|
"error": err,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return c.Render("file", fiber.Map{
|
|
|
|
"file": file,
|
|
|
|
"fullname": c.Params("user") + "/" + c.Params("repo"),
|
|
|
|
"name": c.Params("file"),
|
2022-12-01 02:32:15 +09:00
|
|
|
"branch": c.Params("branch"),
|
2022-12-01 01:37:27 +09:00
|
|
|
})
|
|
|
|
})
|
2022-11-06 04:34:34 +09:00
|
|
|
app.Get("/avatar/:id", func(c *fiber.Ctx) error {
|
|
|
|
url := "https://avatars.githubusercontent.com/u/" + c.Params("id") + "?v=4"
|
|
|
|
if err := proxy.Do(c, url); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// Remove Server header from response
|
|
|
|
c.Response().Header.Del(fiber.HeaderServer)
|
|
|
|
return nil
|
|
|
|
})
|
2022-11-30 23:08:16 +09:00
|
|
|
app.Get("/download/:user/:repo/:branch", ratelimiter, func(c *fiber.Ctx) error {
|
|
|
|
url := "https://github.com/" + c.Params("user") + "/" + c.Params("repo") + "/archive/" + c.Params("branch") + ".zip"
|
|
|
|
if err := proxy.Do(c, url); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// Remove Server header from response
|
|
|
|
c.Response().Header.Del(fiber.HeaderServer)
|
|
|
|
return nil
|
|
|
|
})
|
2022-12-01 02:32:15 +09:00
|
|
|
app.Get("/raw/:user/:repo/:branch/:file", ratelimiter, func(c *fiber.Ctx) error {
|
|
|
|
url := "https://raw.githubusercontent.com/" + c.Params("user") + "/" + c.Params("repo") + "/" + c.Params("branch") + "/" + c.Params("file")
|
|
|
|
if err := proxy.Do(c, url); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// Remove Server header from response
|
|
|
|
c.Response().Header.Del(fiber.HeaderServer)
|
|
|
|
return nil
|
|
|
|
})
|
2022-12-01 00:17:45 +09:00
|
|
|
val, ok := os.LookupEnv("GOTHUB_PORT")
|
|
|
|
if !ok {
|
|
|
|
val = "3000"
|
|
|
|
} else {
|
|
|
|
log.Println("Using port from env variable")
|
|
|
|
}
|
|
|
|
log.Fatal(app.Listen(":" + val))
|
2022-11-06 04:34:34 +09:00
|
|
|
}
|