Changed routing framework from mux to Gin.

Swagger doc is now included in the application.
A fronted can now be hosted from the application.
This commit is contained in:
2022-01-29 17:52:33 +01:00
parent 512fcd0c4f
commit f9d6c24a97
43 changed files with 28760 additions and 210 deletions

16
pkg/helpers/error.go Normal file
View File

@@ -0,0 +1,16 @@
package helpers
import "github.com/gin-gonic/gin"
func NewError(ctx *gin.Context, status int, err error) {
er := HTTPError{
Code: status,
Message: err.Error(),
}
ctx.JSON(status, er)
}
type HTTPError struct {
Code int `json:"code" example:"400"`
Message string `json:"message" example:"status bad request"`
}

View File

@@ -1,46 +1,73 @@
package helpers
import (
"embed"
"fmt"
"github.com/gin-contrib/static"
"github.com/gin-gonic/gin"
"io"
"io/fs"
"net/http"
"os"
"strconv"
"time"
)
func SetCorsAndNoCacheHeaders(w *http.ResponseWriter, r *http.Request) {
var etagHeaders = []string{
"ETag",
"If-Modified-Since",
"If-Match",
"If-None-Match",
"If-Range",
"If-Unmodified-Since",
}
func SetCorsAndNoCacheHeaders() gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT")
(*w).Header().Set("Expires", "Tue, 03 Jul 2001 06:00:00 GMT")
(*w).Header().Set("Last-Modified", time.Now().String()+" GMT")
(*w).Header().Set("Cache-Control", "no-cache, no-store, private, max-age=0")
(*w).Header().Set("Pragma", "no-cache")
(*w).Header().Set("X-Accel-Expires", "0")
(*w).Header().Set("Access-Control-Allow-Origin", "*")
for _, v := range etagHeaders {
if r.Header.Get(v) != "" {
r.Header.Del(v)
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
}
}
func SendSong(writer http.ResponseWriter, Filename string) {
type embedFileSystem struct {
http.FileSystem
indexes bool
}
func (e embedFileSystem) Exists(prefix string, path string) bool {
f, err := e.Open(path)
if err != nil {
return false
}
// check if indexing is allowed
s, _ := f.Stat()
if s.IsDir() && !e.indexes {
return false
}
return true
}
func EmbedFolder(fsEmbed embed.FS, targetPath string, index bool) static.ServeFileSystem {
subFS, err := fs.Sub(fsEmbed, targetPath)
if err != nil {
panic(err)
}
return embedFileSystem{
FileSystem: http.FS(subFS),
indexes: index,
}
}
func SendSong(ctx *gin.Context, Filename string) {
fmt.Println("Client requests: " + Filename)
//Check if file exists and open
openFile, err := os.Open(Filename)
if err != nil {
//File not found, send 404
http.Error(writer, "Song not found.", 404)
http.Error(ctx.Writer, "Song not found.", 404)
return
}
defer func(openFile *os.File) {
@@ -63,12 +90,32 @@ func SendSong(writer http.ResponseWriter, Filename string) {
//Send the headers
//writer.Header().Set("Content-Disposition", "attachment; filename="+Filename)
writer.Header().Set("Content-Type", "audio/mpeg")
writer.Header().Set("Content-Length", FileSize)
ctx.Writer.Header().Set("Content-Type", "audio/mpeg")
ctx.Writer.Header().Set("Content-Length", FileSize)
ctx.Writer.Header().Set("Expires", "Tue, 03 Jul 2001 06:00:00 GMT")
ctx.Writer.Header().Set("Last-Modified", time.Now().String()+" GMT")
ctx.Writer.Header().Set("Cache-Control", "no-cache, no-store, private, max-age=0")
ctx.Writer.Header().Set("Pragma", "no-cache")
ctx.Writer.Header().Set("X-Accel-Expires", "0")
var etagHeaders = []string{
"ETag",
"If-Modified-Since",
"If-Match",
"If-None-Match",
"If-Range",
"If-Unmodified-Since",
}
for _, v := range etagHeaders {
if ctx.Request.Header.Get(v) != "" {
ctx.Request.Header.Del(v)
}
}
//Send the file
//We read 512 bytes from the file already, so we reset the offset back to 0
_, _ = openFile.Seek(0, 0)
_, _ = io.Copy(writer, openFile) //'Copy' the file to the client
_, _ = io.Copy(ctx.Writer, openFile) //'Copy' the file to the client
return
}