mirror of
https://codeberg.org/shroff/phylum.git
synced 2026-04-24 13:40:42 -05:00
114 lines
3.2 KiB
Go
114 lines
3.2 KiB
Go
package appcmd
|
|
|
|
import (
|
|
"bytes"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/fvbock/endless"
|
|
"github.com/gin-contrib/cors"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/shroff/phylum/server/internal/api"
|
|
"github.com/shroff/phylum/server/internal/api/errors"
|
|
"github.com/shroff/phylum/server/internal/core"
|
|
"github.com/shroff/phylum/server/internal/webdav"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
func setupServeCommand() *cobra.Command {
|
|
var cmdServe = &cobra.Command{
|
|
Use: "serve",
|
|
Short: "Run the server",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
config := viper.GetViper()
|
|
engine := createEngine(config.GetBool("log_body"), config.GetBool("cors_enabled"), config.GetStringSlice("cors_origins"))
|
|
engine.Use(errors.RecoverApiError)
|
|
|
|
webdav.SetupHandler(engine.Group(config.GetString("webdav_prefix")), core.Default)
|
|
|
|
api.Setup(engine.Group("/api/v1"), core.Default)
|
|
|
|
server := endless.NewServer(config.GetString("listen"), engine)
|
|
server.BeforeBegin = func(addr string) {
|
|
logrus.Info("Listening on " + addr)
|
|
}
|
|
|
|
if err := server.ListenAndServe(); err != nil {
|
|
logrus.Fatal(err.Error())
|
|
}
|
|
},
|
|
}
|
|
flags := cmdServe.Flags()
|
|
|
|
flags.StringP("listen", "l", ":1234", "Listen Addres")
|
|
viper.BindPFlag("listen", flags.Lookup("listen"))
|
|
|
|
flags.Bool("log-body", false, "Log Response Body (Must be used with --debug)")
|
|
viper.BindPFlag("log_body", flags.Lookup("log-body"))
|
|
|
|
flags.Bool("cors-enabled", false, "Enabled CORS")
|
|
viper.BindPFlag("cors_enabled", flags.Lookup("cors-enabled"))
|
|
|
|
flags.StringSlice("cors-origins", []string{"*"}, "CORS origins")
|
|
viper.BindPFlag("cors_origins", flags.Lookup("cors-origins"))
|
|
|
|
flags.String("webdav-prefix", "/webdav", "Listen Addres")
|
|
viper.BindPFlag("webdav_prefix", flags.Lookup("webdav-prefix"))
|
|
|
|
return cmdServe
|
|
}
|
|
|
|
func createEngine(logBody bool, corsEnabled bool, corsOrigins []string) *gin.Engine {
|
|
if !core.Default.Debug {
|
|
gin.SetMode(gin.ReleaseMode)
|
|
}
|
|
engine := gin.New()
|
|
engine.Use(gin.Logger(), gin.CustomRecovery(func(c *gin.Context, err any) {
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
|
|
"status": 500,
|
|
"code": "internal_server_error",
|
|
"msg": "Internal Server Error",
|
|
})
|
|
}))
|
|
if core.Default.Debug && logBody {
|
|
engine.Use(logBodyMiddleware)
|
|
}
|
|
|
|
if corsEnabled {
|
|
engine.Use(cors.New(cors.Config{
|
|
AllowOrigins: corsOrigins,
|
|
AllowHeaders: []string{"Origin", "Authorization", "Accept", "Accept-Language", "Content-Type"},
|
|
AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS", "PROPFIND", "PROPPATCH", "COPY", "MOVE"},
|
|
ExposeHeaders: []string{"Content-Length"},
|
|
AllowWebSockets: true,
|
|
AllowCredentials: true,
|
|
MaxAge: 24 * time.Hour,
|
|
}))
|
|
}
|
|
|
|
return engine
|
|
}
|
|
|
|
type logBodyWriter struct {
|
|
gin.ResponseWriter
|
|
body *bytes.Buffer
|
|
}
|
|
|
|
func (w logBodyWriter) Write(b []byte) (int, error) {
|
|
w.body.Write(b)
|
|
return w.ResponseWriter.Write(b)
|
|
}
|
|
|
|
func logBodyMiddleware(c *gin.Context) {
|
|
logBodyWriter := &logBodyWriter{
|
|
ResponseWriter: c.Writer,
|
|
body: bytes.NewBuffer(make([]byte, 0, 1024)),
|
|
}
|
|
c.Writer = logBodyWriter
|
|
c.Next()
|
|
logrus.Trace(c.Request.URL)
|
|
logrus.Trace(logBodyWriter.body.String())
|
|
}
|