| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- package controller
- import (
- "bytes"
- "errors"
- "io"
- "net/http"
- "os"
- "path"
- "strings"
- "time"
- "git.aetherial.dev/aeth/keiji/pkg/storage"
- "github.com/gin-gonic/gin"
- )
- // @Name ServeImage
- // @Summary serves image from the image store
- // @Tags cdn
- // @Router /images/{file} [get]
- func (c *Controller) ServeImage(ctx *gin.Context) {
- id, exists := ctx.Params.Get("file")
- if !exists || id == "" {
- ctx.JSON(http.StatusNotFound, gin.H{"Error": "the requested file could not be found"})
- return
- }
- var image storage.Image
- var content io.ReadSeeker
- var file storage.ReadSeekCloser
- var err error
- if opener, ok := c.database.(interface {
- OpenImage(storage.Identifier) (storage.Image, storage.ReadSeekCloser, error)
- }); ok {
- image, file, err = opener.OpenImage(storage.Identifier(id))
- if err == nil && file == nil {
- err = errors.New("image stream is nil")
- }
- if file != nil {
- defer file.Close()
- content = file
- }
- } else {
- // Compatibility for repositories that only implement DocumentIO.
- image, err = c.database.GetImage(storage.Identifier(id))
- content = bytes.NewReader(image.Data)
- }
- if err != nil {
- if errors.Is(err, storage.ErrNotExists) || errors.Is(err, os.ErrNotExist) {
- ctx.JSON(http.StatusNotFound, gin.H{"Error": "the requested file could not be found"})
- } else {
- ctx.JSON(http.StatusInternalServerError, gin.H{"Error": "Could not serve the requested file"})
- }
- return
- }
- mediaType := image.MediaType
- if mediaType == "" {
- mediaType = "application/octet-stream"
- }
- ctx.Header("Content-Type", mediaType)
- ctx.Header("X-Content-Type-Options", "nosniff")
- http.ServeContent(ctx.Writer, ctx.Request, "", time.Time{}, content)
- }
- // @Name ServeAsset
- // @Summary serves file from the html file
- // @Tags cdn
- // @Router /api/v1/assets/{file} [get]
- func (c *Controller) ServeAsset(ctx *gin.Context) {
- f, exist := ctx.Params.Get("file")
- if !exist {
- ctx.JSON(404, map[string]string{
- "Error": "the requested file could not be found",
- })
- return
- }
- var assets []storage.Asset
- if reader, ok := c.database.(storage.DocumentListReader); ok {
- var err error
- assets, err = reader.GetAssetsWithError()
- if err != nil {
- htmlListError(ctx, err)
- return
- }
- } else {
- assets = c.database.GetAssets()
- }
- for i := range assets {
- if strings.Contains(assets[i].Name, f) {
- ctx.Data(200, "image/png", assets[i].Data)
- return
- }
- }
- ctx.Data(http.StatusNotFound, "text", []byte("Couldnt find the image requested."))
- }
- // @Name ServeGeneric
- // @Summary serves file from the html file
- // @Tags cdn
- // @Router /api/v1/cdn/{file} [get]
- func (c *Controller) ServeGeneric(ctx *gin.Context) {
- f, exist := ctx.Params.Get("file")
- if !exist {
- ctx.JSON(404, map[string]string{
- "Error": "the requested file could not be found",
- })
- return
- }
- fext := strings.Split(f, ".")[len(strings.Split(f, "."))-1]
- var ctype string
- switch {
- case fext == "css":
- ctype = "text/css"
- case fext == "js":
- ctype = "text/javascript"
- case fext == "json" || fext == "map":
- ctype = "application/json"
- case fext == "png":
- ctype = "image/png"
- default:
- ctype = "text"
- }
- fh, err := c.FileIO.Open(path.Join("cdn", f))
- if err != nil {
- ctx.JSON(500, map[string]string{
- "Error": "Could not serve the requested file",
- "msg": err.Error(),
- })
- return
- }
- defer fh.Close()
- b, err := io.ReadAll(fh)
- if err != nil {
- ctx.JSON(500, map[string]string{
- "Error": "Could not serve the requested file",
- "msg": err.Error(),
- })
- return
- }
- ctx.Data(200, ctype, b)
- }
|