mozhi/serve/serve.go

135 lines
4 KiB
Go
Raw Normal View History

2023-06-24 18:40:57 +00:00
package serve
import (
"html/template"
"log"
2023-09-10 12:45:46 +00:00
"net/http"
2023-06-24 18:40:57 +00:00
"os"
"runtime"
"strings"
2023-06-24 18:40:57 +00:00
"codeberg.org/aryak/libmozhi"
2023-08-29 09:20:56 +00:00
_ "codeberg.org/aryak/mozhi/docs"
"codeberg.org/aryak/mozhi/pages"
2023-09-10 12:45:46 +00:00
"codeberg.org/aryak/mozhi/public"
2023-10-11 10:27:28 +00:00
"codeberg.org/aryak/mozhi/utils"
"codeberg.org/aryak/mozhi/views"
2023-06-24 18:40:57 +00:00
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/compress"
2023-09-10 12:45:46 +00:00
"github.com/gofiber/fiber/v2/middleware/filesystem"
2023-06-24 18:40:57 +00:00
//"github.com/gofiber/fiber/v2/middleware/limiter"
// For debugging purposes
// "github.com/gofiber/fiber/v2/middleware/logger"
"github.com/gofiber/fiber/v2/middleware/recover"
2023-08-27 15:57:46 +00:00
"github.com/gofiber/swagger"
2023-06-24 18:40:57 +00:00
"github.com/gofiber/template/html"
_ "github.com/joho/godotenv/autoload"
)
2023-08-29 09:20:56 +00:00
// @title Mozhi API
// @version 1.0
// @description API for Mozhi, the alternative-frontend for many translation engines.
// @license.name AGPL 3.0
// @license.url https://www.gnu.org/licenses/agpl-3.0.txt
// @BasePath /api
2023-06-24 18:40:57 +00:00
func Serve(port string) {
2023-09-10 12:45:46 +00:00
views := http.FS(views.GetFiles())
engine := html.NewFileSystem(views, ".html")
2023-06-24 18:40:57 +00:00
engine.AddFunc(
2023-11-29 15:28:26 +00:00
"newlinetobr", func(s string) template.HTML {
return template.HTML(strings.ReplaceAll(strings.ReplaceAll(s, "\n", "<br>"), "\r", ""))
2023-06-24 18:40:57 +00:00
},
)
app := fiber.New(fiber.Config{
Views: engine,
Prefork: false,
AppName: "Mozhi",
2023-06-24 18:40:57 +00:00
// kind of screwed up way to fix rate limits
EnableTrustedProxyCheck: true,
TrustedProxies: []string{"0.0.0.0/0"},
ProxyHeader: fiber.HeaderXForwardedFor,
})
// For debugging purposes
// app.Use(logger.New(logger.Config{
// Format: "[${ip}]:${port} ${status} - ${method} ${path} ${queryParams}\n",
// }))
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",
// })
// },
//})
// add global headers
app.Use(func(c *fiber.Ctx) error {
c.Set("X-Frame-Options", "SAMEORIGIN")
c.Set("X-XSS-Protection", "1; mode=block")
c.Set("X-Content-Type-Options", "nosniff")
c.Set("Referrer-Policy", "no-referrer")
2023-09-21 18:12:28 +00:00
c.Set("Content-Security-Policy", "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; script-src 'self' 'unsafe-inline'; frame-ancestors 'self'; form-action 'self'; base-uri 'self'; connect-src 'self';")
2023-06-24 18:40:57 +00:00
c.Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
return c.Next()
})
api := app.Group("/api")
2023-10-05 16:01:23 +00:00
api.All("/translate", pages.HandleTranslate)
2024-04-14 13:11:18 +00:00
api.All("/image", pages.HandleImg)
api.Get("/source_languages", pages.HandleSourceLanguages)
api.Get("/target_languages", pages.HandleTargetLanguages)
api.Get("/engines", pages.HandleEngines)
api.Get("/tts", pages.HandleTTS)
api.Get("/version", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{
"fiberversion": fiber.Version,
"goversion": runtime.Version(),
})
})
api.Get("/swagger/*", swagger.HandlerDefault) // default
2023-10-05 16:01:23 +00:00
app.All("/", pages.HandleIndex)
2023-10-11 10:27:28 +00:00
app.All("/switchlanguages", func(c *fiber.Ctx) error {
engine := utils.Sanitize(utils.GetQueryOrFormValue(c, "engine"), "alpha")
from := utils.Sanitize(utils.GetQueryOrFormValue(c, "from"), "alpha")
to := utils.Sanitize(utils.GetQueryOrFormValue(c, "to"), "alpha")
text := utils.GetQueryOrFormValue(c, "text")
var swapText string
if engine != "all" && text != "" {
translation, tlerr := libmozhi.Translate(engine, to, from, text)
if tlerr == nil {
swapText = translation.OutputText
} else {
swapText = text
}
}
return c.Redirect("/?engine="+engine+"&from="+to+"&to="+from+"&text="+swapText+"&redirected=true", 301)
2023-09-10 11:57:22 +00:00
})
2023-10-11 10:27:28 +00:00
app.Get("/about", pages.HandleAbout)
2023-09-10 12:45:46 +00:00
app.Use("/", filesystem.New(filesystem.Config{
MaxAge: 2592000,
Root: http.FS(public.GetFiles()),
}))
2023-06-24 18:40:57 +00:00
val, ok := os.LookupEnv("MOZHI_PORT")
2023-06-24 18:40:57 +00:00
if !ok {
val = "3000"
}
if port != "" {
val = port
}
log.Fatal(app.Listen(":" + val))
}