From a2d9b0ad9f49745d50e36c3ffed212ec26506628 Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Thu, 5 Jun 2025 22:18:21 -0500 Subject: [PATCH] major rewrite work 1 --- config/config.go | 8 ++-- http/server.go | 103 +++++++++++----------------------------------- main.go | 105 +++++++++++++++++++++++++++++++++++++++++++++++ moonshark.go | 36 ---------------- 4 files changed, 132 insertions(+), 120 deletions(-) create mode 100644 main.go diff --git a/config/config.go b/config/config.go index 43300e4..f8a065d 100644 --- a/config/config.go +++ b/config/config.go @@ -12,7 +12,7 @@ type Config struct { Port int Debug bool HTTPLogging bool - StaticPrefix string + PublicPrefix string } Runner struct { @@ -21,7 +21,7 @@ type Config struct { Dirs struct { Routes string - Static string + Public string FS string Data string Override string @@ -40,12 +40,12 @@ func New(data *fin.Data) *Config { config.Server.Port = data.GetOr("server.port", 3117).(int) config.Server.Debug = data.GetOr("server.debug", false).(bool) config.Server.HTTPLogging = data.GetOr("server.http_logging", true).(bool) - config.Server.StaticPrefix = data.GetOr("server.static_prefix", "public").(string) + config.Server.PublicPrefix = data.GetOr("server.public_prefix", "public").(string) config.Runner.PoolSize = data.GetOr("runner.pool_size", runtime.GOMAXPROCS(0)).(int) config.Dirs.Routes = data.GetOr("dirs.routes", "routes").(string) - config.Dirs.Static = data.GetOr("dirs.static", "public").(string) + config.Dirs.Public = data.GetOr("dirs.public", "public").(string) config.Dirs.FS = data.GetOr("dirs.fs", "fs").(string) config.Dirs.Data = data.GetOr("dirs.data", "data").(string) config.Dirs.Override = data.GetOr("dirs.override", "override").(string) diff --git a/http/server.go b/http/server.go index a371a4f..815c2a5 100644 --- a/http/server.go +++ b/http/server.go @@ -2,17 +2,14 @@ package http import ( - "bytes" "context" "strings" - "sync" "time" "Moonshark/color" "Moonshark/config" "Moonshark/logger" "Moonshark/metadata" - "Moonshark/router" "Moonshark/runner" "Moonshark/sessions" "Moonshark/utils" @@ -20,69 +17,11 @@ import ( "github.com/valyala/fasthttp" ) -var ( - debugPath = []byte("/debug/stats") - staticMethods = map[string]bool{"GET": true, "HEAD": true, "OPTIONS": true} - cached404, cached500 []byte - cacheMu sync.RWMutex - emptyMap = make(map[string]any) -) +var emptyMap = make(map[string]any) -type Server struct { - luaRouter *router.Router - staticHandler fasthttp.RequestHandler - luaRunner *runner.Runner - fasthttpServer *fasthttp.Server - sessionManager *sessions.SessionManager - cfg *config.Config - debugMode bool - staticPrefixBytes []byte -} - -func New(luaRouter *router.Router, runner *runner.Runner, cfg *config.Config, debugMode bool) *Server { - staticPrefix := cfg.Server.StaticPrefix - if !strings.HasPrefix(staticPrefix, "/") { - staticPrefix = "/" + staticPrefix - } - if !strings.HasSuffix(staticPrefix, "/") { - staticPrefix += "/" - } - - s := &Server{ - luaRouter: luaRouter, - luaRunner: runner, - debugMode: debugMode, - cfg: cfg, - sessionManager: sessions.GlobalSessionManager, - staticPrefixBytes: []byte(staticPrefix), - } - - // Cache error pages - errorConfig := utils.ErrorPageConfig{ - OverrideDir: cfg.Dirs.Override, - DebugMode: debugMode, - } - cacheMu.Lock() - cached404 = []byte(utils.NotFoundPage(errorConfig, "")) - cached500 = []byte(utils.InternalErrorPage(errorConfig, "", "Internal Server Error")) - cacheMu.Unlock() - - // Setup static file serving - if cfg.Dirs.Static != "" { - staticFS := &fasthttp.FS{ - Root: cfg.Dirs.Static, - IndexNames: []string{"index.html"}, - AcceptByteRange: true, - Compress: true, - CompressedFileSuffix: ".gz", - CompressBrotli: true, - PathRewrite: fasthttp.NewPathPrefixStripper(len(staticPrefix) - 1), - } - s.staticHandler = staticFS.NewRequestHandler() - } - - s.fasthttpServer = &fasthttp.Server{ - Handler: s.handleRequest, +func NewHttpServer(cfg *config.Config, handler fasthttp.RequestHandler, dbg bool) *fasthttp.Server { + return &fasthttp.Server{ + Handler: handler, Name: "Moonshark/" + metadata.Version, ReadTimeout: 30 * time.Second, WriteTimeout: 30 * time.Second, @@ -93,8 +32,26 @@ func New(luaRouter *router.Router, runner *runner.Runner, cfg *config.Config, de StreamRequestBody: true, NoDefaultServerHeader: true, } +} - return s +func NewPublicHandler(pubDir, prefix string) fasthttp.RequestHandler { + if !strings.HasPrefix(prefix, "/") { + prefix = "/" + prefix + } + if !strings.HasSuffix(prefix, "/") { + prefix += "/" + } + + fs := &fasthttp.FS{ + Root: pubDir, + IndexNames: []string{"index.html"}, + AcceptByteRange: true, + Compress: true, + CompressedFileSuffix: ".gz", + CompressBrotli: true, + PathRewrite: fasthttp.NewPathPrefixStripper(len(prefix) - 1), + } + return fs.NewRequestHandler() } func (s *Server) ListenAndServe(addr string) error { @@ -111,20 +68,6 @@ func (s *Server) handleRequest(ctx *fasthttp.RequestCtx) { method := string(ctx.Method()) path := string(ctx.Path()) - // Debug stats endpoint - if s.debugMode && bytes.Equal(ctx.Path(), debugPath) { - s.handleDebugStats(ctx) - s.logRequest(ctx, method, path, time.Since(start)) - return - } - - // Static file serving - if s.staticHandler != nil && bytes.HasPrefix(ctx.Path(), s.staticPrefixBytes) { - s.staticHandler(ctx) - s.logRequest(ctx, method, path, time.Since(start)) - return - } - // Route lookup bytecode, params, found := s.luaRouter.Lookup(method, path) if !found { diff --git a/main.go b/main.go new file mode 100644 index 0000000..e02a53d --- /dev/null +++ b/main.go @@ -0,0 +1,105 @@ +package main + +import ( + "Moonshark/color" + "Moonshark/config" + "Moonshark/http" + "Moonshark/logger" + "Moonshark/metadata" + "Moonshark/router" + "Moonshark/runner" + "Moonshark/sessions" + "bytes" + "flag" + "fmt" + "os" + "time" + + fin "git.sharkk.net/Sharkk/Fin" + "github.com/valyala/fasthttp" +) + +var ( + cfg *config.Config // Server config from Fin file + rtr *router.Router // Lua file router + rnr *runner.Runner // Lua runner + svr *fasthttp.Server // FastHTTP server + pub fasthttp.RequestHandler // Public asset handler + snm *sessions.SessionManager // Session data manager + dbg bool // Debug mode flag + pubPfx []byte // Cached public asset prefix +) + +func main() { + cfgPath := flag.String("config", "config", "Path to Fin config file") + dbgFlag := flag.Bool("debug", false, "Force debug mode") + sptPath := flag.String("script", "", "Path to Lua script to execute once") + flag.Parse() + + sptMode := *sptPath != "" + color.SetColors(color.DetectShellColors()) + banner(sptMode) + + cfg = config.New(readConfig(*cfgPath)) + dbg = *dbgFlag || cfg.Server.Debug + logger.Debug(dbg) + if dbg { + logger.Debugf("Debug logging enabled") + } + + svr = http.NewHttpServer(cfg, requestMux, dbg) + pub = http.NewPublicHandler(cfg.Dirs.Public, cfg.Server.PublicPrefix) + pubPfx = []byte(cfg.Server.PublicPrefix) +} + +// This is the primary request handler mux - determines whether we need to handle a Lua +// route or if we're serving a static file. +func requestMux(ctx *fasthttp.RequestCtx) { + start := time.Now() + method := ctx.Method() + path := ctx.Path() + + // Handle static file request + if bytes.HasPrefix(path, pubPfx) { + pub(ctx) + if cfg.Server.HTTPLogging { + logger.Request(ctx.Response.StatusCode(), string(method), string(path), time.Since(start)) + } + return + } +} + +// Attempt to read the given path for config, or return an empty struct for defaults +func readConfig(path string) *fin.Data { + file, err := os.Open(path) + if err != nil { + logger.Errorf("Failed to open config file %s, using defaults", color.Yellow(path)) + return fin.NewData() + } + defer file.Close() + + cfg, err := fin.Load(file) + if err != nil { + logger.Errorf("Failed to load config file %s, using defaults", color.Yellow(path)) + } + + return cfg +} + +// Print our super-awesome banner with the current version! +func banner(scriptMode bool) { + if scriptMode { + fmt.Println(color.Blue(fmt.Sprintf("Moonshark %s << Script Mode >>", metadata.Version))) + return + } + + banner := ` + _____ _________.__ __ + / \ ____ ____ ____ / _____/| |__ _____ _______| | __ + / \ / \ / _ \ / _ \ / \ \_____ \ | | \\__ \\_ __ \ |/ / +/ Y ( <_> | <_> ) | \/ \| Y \/ __ \| | \/ < +\____|__ /\____/ \____/|___| /_______ /|___| (____ /__| |__|_ \ %s + \/ \/ \/ \/ \/ \/ + ` + fmt.Println(color.Blue(fmt.Sprintf(banner, metadata.Version))) +} diff --git a/moonshark.go b/moonshark.go index feac7bb..7decf16 100644 --- a/moonshark.go +++ b/moonshark.go @@ -17,14 +17,11 @@ import ( "Moonshark/config" "Moonshark/http" "Moonshark/logger" - "Moonshark/metadata" "Moonshark/router" "Moonshark/runner" "Moonshark/runner/lualibs" "Moonshark/sessions" "Moonshark/watchers" - - fin "git.sharkk.net/Sharkk/Fin" ) type Moonshark struct { @@ -282,36 +279,3 @@ func dirExists(path string) bool { info, err := os.Stat(path) return err == nil && info.IsDir() } - -func banner(scriptMode bool) { - if scriptMode { - fmt.Println(color.Blue(fmt.Sprintf("Moonshark %s << Script Mode >>", metadata.Version))) - return - } - - banner := ` - _____ _________.__ __ - / \ ____ ____ ____ / _____/| |__ _____ _______| | __ - / \ / \ / _ \ / _ \ / \ \_____ \ | | \\__ \\_ __ \ |/ / -/ Y ( <_> | <_> ) | \/ \| Y \/ __ \| | \/ < -\____|__ /\____/ \____/|___| /_______ /|___| (____ /__| |__|_ \ %s - \/ \/ \/ \/ \/ \/ - ` - fmt.Println(color.Blue(fmt.Sprintf(banner, metadata.Version))) -} - -func readConfig(path string) *fin.Data { - file, err := os.Open(path) - if err != nil { - logger.Errorf("Failed to open config file %s, using defaults", color.Yellow(path)) - return fin.NewData() - } - defer file.Close() - - cfg, err := fin.Load(file) - if err != nil { - logger.Errorf("Failed to load config file %s, using defaults", color.Yellow(path)) - } - - return cfg -}