mirror of
https://github.com/akyaiy/GoSally-mvp.git
synced 2026-01-03 08:32:24 +00:00
Enhance server functionality: add versioning support, implement command handling improvements, and introduce new Lua scripts for command execution
This commit is contained in:
@@ -4,5 +4,10 @@ http_server:
|
||||
address: "localhost:8080"
|
||||
timeout: 3s
|
||||
idle_timeout: 30s
|
||||
api:
|
||||
latest-version: v1
|
||||
layers:
|
||||
- b1
|
||||
- s2
|
||||
|
||||
com_dir: "com/"
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"regexp"
|
||||
|
||||
"github.com/akyaiy/GoSally-mvp/config"
|
||||
gs "github.com/akyaiy/GoSally-mvp/general_server"
|
||||
"github.com/akyaiy/GoSally-mvp/logs"
|
||||
"github.com/akyaiy/GoSally-mvp/sv1"
|
||||
|
||||
@@ -31,18 +32,18 @@ func main() {
|
||||
Config: cfg,
|
||||
AllowedCmd: regexp.MustCompile(`^[a-zA-Z0-9]+$`),
|
||||
ListAllowedCmd: regexp.MustCompile(`^[a-zA-Z0-9_-]+$`),
|
||||
Ver: "v1",
|
||||
})
|
||||
s := gs.InitGeneral(&gs.GeneralServerInit{
|
||||
Log: *logs.SetupLogger(cfg.Mode),
|
||||
Config: cfg,
|
||||
}, serverv1)
|
||||
r := chi.NewRouter()
|
||||
r.Route("/v1/com", func(r chi.Router) {
|
||||
r.Get("/", serverv1.HandleList)
|
||||
r.Get("/{cmd}", serverv1.Handle)
|
||||
r.Route("/{ver}/com", func(r chi.Router) {
|
||||
r.Get("/", s.HandleList)
|
||||
r.Get("/{cmd}", s.Handle)
|
||||
})
|
||||
// r.Route("/v2/com", func(r chi.Router) {
|
||||
// r.Get("/", handleV1ComList)
|
||||
// r.Get("/{cmd}", handleV1)
|
||||
// })
|
||||
r.NotFound(serverv1.ErrNotFound)
|
||||
log.Info("Server started", slog.String("address", cfg.Address))
|
||||
http.ListenAndServe(cfg.Address, r)
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,3 @@ Params = {}
|
||||
|
||||
---@type AnyTable
|
||||
Result = {}
|
||||
|
||||
---@type AnyTable
|
||||
Me = {}
|
||||
5
com/_prepare.lua
Normal file
5
com/_prepare.lua
Normal file
@@ -0,0 +1,5 @@
|
||||
print = function() end
|
||||
io.write = function(...) end
|
||||
io.stdout = function() return nil end
|
||||
io.stderr = function() return nil end
|
||||
io.read = function(...) return nil end
|
||||
@@ -1,4 +1,4 @@
|
||||
--- #description = "Echoes back the message provided in the 'msg' parameter."
|
||||
--- #description = "Echoes back the message provided in the 'msg' parameter. b1"
|
||||
|
||||
if not Params.msg then
|
||||
Result.status = "error"
|
||||
@@ -15,9 +15,15 @@ type ConfigConf struct {
|
||||
}
|
||||
|
||||
type HTTPServer struct {
|
||||
Address string `yaml:"address" env-default:"0.0.0.0:8080"`
|
||||
Timeout time.Duration `yaml:"timeout" env-default:"5s"`
|
||||
IdleTimeout time.Duration `yaml:"idle_timeout" env-default:"60s"`
|
||||
Address string `yaml:"address" env-default:"0.0.0.0:8080"`
|
||||
Timeout time.Duration `yaml:"timeout" env-default:"5s"`
|
||||
IdleTimeout time.Duration `yaml:"idle_timeout" env-default:"60s"`
|
||||
HTTPServer_Api `yaml:"api"`
|
||||
}
|
||||
|
||||
type HTTPServer_Api struct {
|
||||
LatestVer string `yaml:"latest-version" env-required:"true"`
|
||||
Layers []string `yaml:"layers"`
|
||||
}
|
||||
|
||||
type ConfigEnv struct {
|
||||
|
||||
159
general_server/hanle_multi.go
Normal file
159
general_server/hanle_multi.go
Normal file
@@ -0,0 +1,159 @@
|
||||
package general_server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"slices"
|
||||
|
||||
"github.com/akyaiy/GoSally-mvp/config"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
type serversApiVer string
|
||||
|
||||
type GeneralServerApiContract interface {
|
||||
GetVersion() string
|
||||
|
||||
Handle(w http.ResponseWriter, r *http.Request)
|
||||
HandleList(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
type GeneralServerContarct interface {
|
||||
GeneralServerApiContract
|
||||
AppendToArray(GeneralServerApiContract) error
|
||||
}
|
||||
|
||||
type GeneralServer struct {
|
||||
w http.ResponseWriter
|
||||
r *http.Request
|
||||
|
||||
servers map[serversApiVer]GeneralServerApiContract
|
||||
|
||||
log slog.Logger
|
||||
cfg *config.ConfigConf
|
||||
}
|
||||
|
||||
// structure only for initialization
|
||||
type GeneralServerInit struct {
|
||||
Log slog.Logger
|
||||
Config *config.ConfigConf
|
||||
}
|
||||
|
||||
func InitGeneral(o *GeneralServerInit, servers ...GeneralServerApiContract) *GeneralServer {
|
||||
general := &GeneralServer{
|
||||
servers: make(map[serversApiVer]GeneralServerApiContract),
|
||||
cfg: o.Config,
|
||||
log: o.Log,
|
||||
}
|
||||
for _, s := range servers {
|
||||
general.servers[serversApiVer(s.GetVersion())] = s
|
||||
}
|
||||
return general
|
||||
}
|
||||
|
||||
func (s *GeneralServer) GetVersion() string {
|
||||
return "general"
|
||||
}
|
||||
|
||||
func (s *GeneralServer) AppendToArray(server GeneralServerApiContract) error {
|
||||
if _, exist := s.servers[serversApiVer(server.GetVersion())]; !exist {
|
||||
s.servers[serversApiVer(server.GetVersion())] = server
|
||||
return nil
|
||||
}
|
||||
return errors.New("server with this version is already exist")
|
||||
}
|
||||
|
||||
func (s *GeneralServer) Handle(w http.ResponseWriter, r *http.Request) {
|
||||
s.w = w
|
||||
s.r = r
|
||||
serverReqApiVer := chi.URLParam(r, "ver")
|
||||
|
||||
s.log.Info("Received request",
|
||||
slog.String("remote", r.RemoteAddr),
|
||||
slog.String("method", r.Method),
|
||||
slog.String("url", r.URL.String()),
|
||||
slog.String("requested-version", serverReqApiVer),
|
||||
)
|
||||
|
||||
if srv, ok := s.servers[serversApiVer(serverReqApiVer)]; ok {
|
||||
srv.Handle(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if slices.Contains(s.cfg.Layers, serverReqApiVer) {
|
||||
if srv, ok := s.servers[serversApiVer(s.cfg.LatestVer)]; ok {
|
||||
s.log.Info("Using latest version under custom layer",
|
||||
slog.String("layer", serverReqApiVer),
|
||||
slog.String("fallback-version", s.cfg.LatestVer),
|
||||
)
|
||||
srv.Handle(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
s.log.Error("HTTP request error: unsupported API version",
|
||||
slog.String("remote", s.r.RemoteAddr),
|
||||
slog.String("method", s.r.Method),
|
||||
slog.String("url", s.r.URL.String()),
|
||||
slog.Int("status", http.StatusBadRequest))
|
||||
s.writeJSONError(http.StatusBadRequest, "unsupported API version")
|
||||
}
|
||||
|
||||
func (s *GeneralServer) HandleList(w http.ResponseWriter, r *http.Request) {
|
||||
s.w = w
|
||||
s.r = r
|
||||
serverReqApiVer := chi.URLParam(r, "ver")
|
||||
|
||||
s.log.Info("Received request",
|
||||
slog.String("remote", r.RemoteAddr),
|
||||
slog.String("method", r.Method),
|
||||
slog.String("url", r.URL.String()),
|
||||
slog.String("requested-version", serverReqApiVer),
|
||||
)
|
||||
|
||||
if srv, ok := s.servers[serversApiVer(serverReqApiVer)]; ok {
|
||||
srv.HandleList(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if slices.Contains(s.cfg.Layers, serverReqApiVer) {
|
||||
if srv, ok := s.servers[serversApiVer(s.cfg.LatestVer)]; ok {
|
||||
s.log.Info("Using latest version under custom layer",
|
||||
slog.String("layer", serverReqApiVer),
|
||||
slog.String("fallback-version", s.cfg.LatestVer),
|
||||
)
|
||||
srv.HandleList(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
s.log.Error("HTTP request error: unsupported API version",
|
||||
slog.String("remote", s.r.RemoteAddr),
|
||||
slog.String("method", s.r.Method),
|
||||
slog.String("url", s.r.URL.String()),
|
||||
slog.Int("status", http.StatusBadRequest))
|
||||
s.writeJSONError(http.StatusBadRequest, "unsupported API version")
|
||||
}
|
||||
|
||||
func (s *GeneralServer) _errNotFound() {
|
||||
s.writeJSONError(http.StatusBadRequest, "invalid request")
|
||||
s.log.Error("HTTP request error",
|
||||
slog.String("remote", s.r.RemoteAddr),
|
||||
slog.String("method", s.r.Method),
|
||||
slog.String("url", s.r.URL.String()),
|
||||
slog.Int("status", http.StatusBadRequest))
|
||||
}
|
||||
|
||||
func (s *GeneralServer) writeJSONError(status int, msg string) {
|
||||
s.w.Header().Set("Content-Type", "application/json")
|
||||
s.w.WriteHeader(status)
|
||||
resp := map[string]interface{}{
|
||||
"status": "error",
|
||||
"error": msg,
|
||||
"code": status,
|
||||
}
|
||||
json.NewEncoder(s.w).Encode(resp)
|
||||
}
|
||||
@@ -13,23 +13,51 @@ import (
|
||||
|
||||
func (h *HandlerV1) _handle() {
|
||||
uuid16 := h.newUUID()
|
||||
h.log.Info("Received request", slog.String("version", "v1"), slog.String("connection-uuid", uuid16), slog.String("remote", h.r.RemoteAddr), slog.String("method", h.r.Method), slog.String("url", h.r.URL.String()))
|
||||
h.log.Info("Received request",
|
||||
slog.String("version", "v1"),
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("remote", h.r.RemoteAddr),
|
||||
slog.String("method", h.r.Method),
|
||||
slog.String("url", h.r.URL.String()))
|
||||
|
||||
cmd := chi.URLParam(h.r, "cmd")
|
||||
var scriptPath string
|
||||
if !h.allowedCmd.MatchString(string([]rune(cmd)[0])) {
|
||||
h.log.Error("HTTP request error",
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("error", "invalid command"),
|
||||
slog.String("cmd", cmd),
|
||||
slog.Int("status", http.StatusBadRequest))
|
||||
h.writeJSONError(http.StatusBadRequest, "invalid command")
|
||||
h.log.Error("HTTP request error", slog.String("connection-uuid", uuid16), slog.String("error", "invalid command"), slog.String("cmd", cmd), slog.Int("status", http.StatusBadRequest))
|
||||
return
|
||||
}
|
||||
if !h.listAllowedCmd.MatchString(cmd) {
|
||||
h.log.Error("HTTP request error",
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("error", "invalid command"),
|
||||
slog.String("cmd", cmd),
|
||||
slog.Int("status", http.StatusBadRequest))
|
||||
h.writeJSONError(http.StatusBadRequest, "invalid command")
|
||||
h.log.Error("HTTP request error", slog.String("connection-uuid", uuid16), slog.String("error", "invalid command"), slog.String("cmd", cmd), slog.Int("status", http.StatusBadRequest))
|
||||
return
|
||||
}
|
||||
scriptPath := filepath.Join(h.cfg.ComDir, cmd+".lua")
|
||||
if _, err := os.Stat(scriptPath); err != nil {
|
||||
if scriptPath = h.comMatch(chi.URLParam(h.r, "ver"), cmd); scriptPath == "" {
|
||||
h.log.Error("HTTP request error",
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("error", "command not found"),
|
||||
slog.String("cmd", cmd),
|
||||
slog.Int("status", http.StatusNotFound))
|
||||
h.writeJSONError(http.StatusNotFound, "command not found")
|
||||
return
|
||||
}
|
||||
|
||||
scriptPath = filepath.Join(h.cfg.ComDir, scriptPath)
|
||||
if _, err := os.Stat(scriptPath); err != nil {
|
||||
h.log.Error("HTTP request error",
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("error", "command not found"),
|
||||
slog.String("cmd", cmd),
|
||||
slog.Int("status", http.StatusNotFound))
|
||||
h.writeJSONError(http.StatusNotFound, "command not found")
|
||||
h.log.Error("HTTP request error", slog.String("connection-uuid", uuid16), slog.String("error", "command not found"), slog.String("cmd", cmd), slog.Int("status", http.StatusNotFound))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -48,17 +76,24 @@ func (h *HandlerV1) _handle() {
|
||||
L.SetGlobal("Params", tbl)
|
||||
L.SetGlobal("Result", L.NewTable())
|
||||
|
||||
L.DoString(`
|
||||
print = function() end
|
||||
io.write = function(...) end
|
||||
io.stdout = function() return nil end
|
||||
io.stderr = function() return nil end
|
||||
io.read = function(...) return nil end
|
||||
`)
|
||||
prepareLuaEnv := filepath.Join(h.cfg.ComDir, "_prepare"+".lua")
|
||||
if _, err := os.Stat(prepareLuaEnv); err == nil {
|
||||
if err := L.DoFile(prepareLuaEnv); err != nil {
|
||||
h.log.Error("Failed to prepare lua environment",
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("error", err.Error()))
|
||||
h.writeJSONError(http.StatusInternalServerError, "lua error: "+err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
h.log.Error("No environment preparation script found, skipping preparation", slog.String("connection-uuid", uuid16), slog.String("error", err.Error()))
|
||||
}
|
||||
|
||||
if err := L.DoFile(scriptPath); err != nil {
|
||||
h.log.Error("Failed to execute lua script",
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("error", err.Error()))
|
||||
h.writeJSONError(http.StatusInternalServerError, "lua error: "+err.Error())
|
||||
h.log.Error("Failed to execute lua script", slog.String("connection-uuid", uuid16), slog.String("error", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -82,11 +117,23 @@ func (h *HandlerV1) _handle() {
|
||||
json.NewEncoder(h.w).Encode(out)
|
||||
switch out["status"] {
|
||||
case "error":
|
||||
h.log.Info("Command executed with error", slog.String("connection-uuid", uuid16), slog.String("cmd", cmd), slog.Any("result", out))
|
||||
h.log.Info("Command executed with error",
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("cmd", cmd),
|
||||
slog.Any("result", out))
|
||||
case "ok":
|
||||
h.log.Info("Command executed successfully", slog.String("connection-uuid", uuid16), slog.String("cmd", cmd), slog.Any("result", out))
|
||||
h.log.Info("Command executed successfully",
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("cmd", cmd), slog.Any("result", out))
|
||||
default:
|
||||
h.log.Info("Command executed and returned an unknown status", slog.String("connection-uuid", uuid16), slog.String("cmd", cmd), slog.Any("result", out))
|
||||
h.log.Info("Command executed and returned an unknown status",
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("cmd", cmd),
|
||||
slog.Any("result", out))
|
||||
}
|
||||
h.log.Info("Session completed", slog.String("connection-uuid", uuid16), slog.String("remote", h.r.RemoteAddr), slog.String("method", h.r.Method), slog.String("url", h.r.URL.String()))
|
||||
h.log.Info("Session completed",
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("remote", h.r.RemoteAddr),
|
||||
slog.String("method", h.r.Method),
|
||||
slog.String("url", h.r.URL.String()))
|
||||
}
|
||||
|
||||
@@ -6,50 +6,103 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
_ "github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func (h *HandlerV1) _handleList() {
|
||||
uuid16 := h.newUUID()
|
||||
h.log.Info("Received request", slog.String("version", "v1"), slog.String("connection-uuid", uuid16), slog.String("remote", h.r.RemoteAddr), slog.String("method", h.r.Method), slog.String("url", h.r.URL.String()))
|
||||
h.log.Info("Received request",
|
||||
slog.String("version", "v1"),
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("remote", h.r.RemoteAddr),
|
||||
slog.String("method", h.r.Method),
|
||||
slog.String("url", h.r.URL.String()))
|
||||
|
||||
type ComMeta struct {
|
||||
Description string
|
||||
}
|
||||
|
||||
var (
|
||||
files []os.DirEntry
|
||||
err error
|
||||
com ComMeta
|
||||
commands = make(map[string]ComMeta)
|
||||
files []os.DirEntry
|
||||
err error
|
||||
commands = make(map[string]ComMeta)
|
||||
cmdsProcessed = make(map[string]bool)
|
||||
)
|
||||
|
||||
if files, err = os.ReadDir(h.cfg.ComDir); err != nil {
|
||||
h.log.Error("Failed to read commands directory",
|
||||
slog.String("error", err.Error()))
|
||||
h.writeJSONError(http.StatusInternalServerError, "failed to read commands directory: "+err.Error())
|
||||
h.log.Error("Failed to read commands directory", slog.String("error", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
apiVer := chi.URLParam(h.r, "ver")
|
||||
|
||||
// Сначала ищем версионные
|
||||
for _, file := range files {
|
||||
if file.IsDir() || filepath.Ext(file.Name()) != ".lua" {
|
||||
continue
|
||||
}
|
||||
cmdName := file.Name()[:len(file.Name())-4] // remove .lua extension
|
||||
cmdFull := file.Name()[:len(file.Name())-4]
|
||||
cmdParts := strings.SplitN(cmdFull, "?", 2)
|
||||
cmdName := cmdParts[0]
|
||||
|
||||
if !h.allowedCmd.MatchString(string([]rune(cmdName)[0])) {
|
||||
continue
|
||||
}
|
||||
if !h.listAllowedCmd.MatchString(cmdName) {
|
||||
continue
|
||||
}
|
||||
if com.Description, err = h.extractDescriptionStatic(filepath.Join(h.cfg.ComDir, file.Name())); err != nil {
|
||||
h.writeJSONError(http.StatusInternalServerError, "failed to read command: "+err.Error())
|
||||
h.log.Error("Failed to read command", slog.String("error", err.Error()))
|
||||
return
|
||||
|
||||
if len(cmdParts) == 2 && cmdParts[1] == apiVer {
|
||||
description, _ := h.extractDescriptionStatic(filepath.Join(h.cfg.ComDir, file.Name()))
|
||||
if description == "" {
|
||||
description = "description missing"
|
||||
}
|
||||
commands[cmdName] = ComMeta{Description: description}
|
||||
cmdsProcessed[cmdName] = true
|
||||
}
|
||||
if com.Description == "" {
|
||||
com.Description = "description missing"
|
||||
}
|
||||
commands[cmdName] = ComMeta{Description: com.Description}
|
||||
}
|
||||
|
||||
// Потом фоллбеки
|
||||
for _, file := range files {
|
||||
if file.IsDir() || filepath.Ext(file.Name()) != ".lua" {
|
||||
continue
|
||||
}
|
||||
cmdFull := file.Name()[:len(file.Name())-4]
|
||||
cmdParts := strings.SplitN(cmdFull, "?", 2)
|
||||
cmdName := cmdParts[0]
|
||||
|
||||
if !h.allowedCmd.MatchString(string([]rune(cmdName)[0])) {
|
||||
continue
|
||||
}
|
||||
if !h.listAllowedCmd.MatchString(cmdName) {
|
||||
continue
|
||||
}
|
||||
if cmdsProcessed[cmdName] {
|
||||
continue
|
||||
}
|
||||
if len(cmdParts) == 1 {
|
||||
description, _ := h.extractDescriptionStatic(filepath.Join(h.cfg.ComDir, file.Name()))
|
||||
if description == "" {
|
||||
description = "description missing"
|
||||
}
|
||||
commands[cmdName] = ComMeta{Description: description}
|
||||
cmdsProcessed[cmdName] = true
|
||||
}
|
||||
}
|
||||
|
||||
h.log.Info("Command list prepared",
|
||||
slog.String("connection-uuid", uuid16))
|
||||
|
||||
h.log.Info("Session completed",
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("remote", h.r.RemoteAddr),
|
||||
slog.String("method", h.r.Method),
|
||||
slog.String("url", h.r.URL.String()))
|
||||
|
||||
h.w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(h.w).Encode(commands)
|
||||
h.log.Info("Command executed successfully", slog.String("connection-uuid", uuid16))
|
||||
h.log.Info("Session completed", slog.String("connection-uuid", uuid16), slog.String("remote", h.r.RemoteAddr), slog.String("method", h.r.Method), slog.String("url", h.r.URL.String()))
|
||||
}
|
||||
|
||||
@@ -17,18 +17,9 @@ type ServerV1UtilsContract interface {
|
||||
ErrNotFound(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
type ServerV1Contract interface {
|
||||
ServerV1UtilsContract
|
||||
|
||||
Handle(w http.ResponseWriter, r *http.Request)
|
||||
HandleList(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
_handle()
|
||||
_handleList()
|
||||
}
|
||||
|
||||
// structure only for initialization
|
||||
type HandlerV1InitStruct struct {
|
||||
Ver string
|
||||
Log slog.Logger
|
||||
Config *config.ConfigConf
|
||||
AllowedCmd *regexp.Regexp
|
||||
@@ -45,6 +36,8 @@ type HandlerV1 struct {
|
||||
|
||||
allowedCmd *regexp.Regexp
|
||||
listAllowedCmd *regexp.Regexp
|
||||
|
||||
ver string
|
||||
}
|
||||
|
||||
func InitV1Server(o *HandlerV1InitStruct) *HandlerV1 {
|
||||
@@ -53,6 +46,7 @@ func InitV1Server(o *HandlerV1InitStruct) *HandlerV1 {
|
||||
cfg: o.Config,
|
||||
allowedCmd: o.AllowedCmd,
|
||||
listAllowedCmd: o.ListAllowedCmd,
|
||||
ver: o.Ver,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,3 +61,7 @@ func (h *HandlerV1) HandleList(w http.ResponseWriter, r *http.Request) {
|
||||
h.r = r
|
||||
h._handleList()
|
||||
}
|
||||
|
||||
func (h *HandlerV1) GetVersion() string {
|
||||
return h.ver
|
||||
}
|
||||
|
||||
37
sv1/utils.go
37
sv1/utils.go
@@ -28,7 +28,11 @@ func (h *HandlerV1) newUUID() string {
|
||||
|
||||
func (h *HandlerV1) _errNotFound() {
|
||||
h.writeJSONError(http.StatusBadRequest, "invalid request")
|
||||
h.log.Error("HTTP request error", slog.String("remote", h.r.RemoteAddr), slog.String("method", h.r.Method), slog.String("url", h.r.URL.String()), slog.Int("status", http.StatusBadRequest))
|
||||
h.log.Error("HTTP request error",
|
||||
slog.String("remote", h.r.RemoteAddr),
|
||||
slog.String("method", h.r.Method),
|
||||
slog.String("url", h.r.URL.String()),
|
||||
slog.Int("status", http.StatusBadRequest))
|
||||
}
|
||||
|
||||
func (h *HandlerV1) writeJSONError(status int, msg string) {
|
||||
@@ -55,3 +59,34 @@ func (h *HandlerV1) extractDescriptionStatic(path string) (string, error) {
|
||||
}
|
||||
return m[1], nil
|
||||
}
|
||||
|
||||
func (h *HandlerV1) comMatch(ver string, comName string) string {
|
||||
files, err := os.ReadDir(h.cfg.ComDir)
|
||||
if err != nil {
|
||||
h.log.Error("Failed to read com dir",
|
||||
slog.String("error", err.Error()))
|
||||
return ""
|
||||
}
|
||||
|
||||
baseName := comName + ".lua"
|
||||
verName := comName + "?" + ver + ".lua"
|
||||
|
||||
var baseFileFound string
|
||||
|
||||
for _, f := range files {
|
||||
if f.IsDir() {
|
||||
continue
|
||||
}
|
||||
fname := f.Name()
|
||||
|
||||
if fname == verName {
|
||||
return fname
|
||||
}
|
||||
|
||||
if fname == baseName {
|
||||
baseFileFound = fname
|
||||
}
|
||||
}
|
||||
|
||||
return baseFileFound
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user