mirror of
https://github.com/akyaiy/GoSally-mvp.git
synced 2026-01-05 14:32:26 +00:00
Project structure refactor:
- Change package name general_server to gateway - Changing the structure of directories and packages - Adding vendor to the project
This commit is contained in:
342
internal/server/sv1/handle.go
Normal file
342
internal/server/sv1/handle.go
Normal file
@@ -0,0 +1,342 @@
|
||||
package sv1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
||||
)
|
||||
|
||||
func (h *HandlerV1) Handle(w http.ResponseWriter, r *http.Request, req rpc.RPCRequest) {
|
||||
w.Write([]byte("Sigmas"))
|
||||
}
|
||||
|
||||
// func (h *HandlerV1) Handle(w http.ResponseWriter, r *http.Request) {
|
||||
// var req PettiRequest
|
||||
// // server, ok := s.servers[serversApiVer(payload.PettiVer)]
|
||||
// // if !ok {
|
||||
// // WriteRouterError(w, &RouterError{
|
||||
// // Status: "error",
|
||||
// // StatusCode: http.StatusBadRequest,
|
||||
// // Payload: map[string]any{
|
||||
// // "Message": InvalidProtovolVersion,
|
||||
// // },
|
||||
// // })
|
||||
// // s.log.Info("invalid request received", slog.String("issue", InvalidProtovolVersion), slog.String("requested-version", payload.PettiVer))
|
||||
// // return
|
||||
// // }
|
||||
// if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
// utils.WriteJSONError(w, http.StatusBadRequest, "невалидный JSON: "+err.Error())
|
||||
// return
|
||||
// }
|
||||
|
||||
// if req.PettiVer == "" {
|
||||
// utils.WriteJSONError(w, http.StatusBadRequest, "отсутствует PettiVer")
|
||||
// return
|
||||
// }
|
||||
// if req.PettiVer != h.GetVersion() {
|
||||
// utils.WriteJSONError(w, http.StatusBadRequest, "неподдерживаемая версия PettiVer")
|
||||
// return
|
||||
// }
|
||||
// if req.PackageType.Request == "" {
|
||||
// utils.WriteJSONError(w, http.StatusBadRequest, "отсутствует PackageType.Request")
|
||||
// return
|
||||
// }
|
||||
// if req.Payload == nil {
|
||||
// utils.WriteJSONError(w, http.StatusBadRequest, "отсутствует Payload")
|
||||
// return
|
||||
// }
|
||||
// cmdRaw, ok := req.Payload["Exec"].(string)
|
||||
// if !ok || cmdRaw == "" {
|
||||
// utils.WriteJSONError(w, http.StatusBadRequest, "Payload.Exec отсутствует или некорректен")
|
||||
// return
|
||||
// }
|
||||
// cmd := cmdRaw
|
||||
|
||||
// if !h.allowedCmd.MatchString(string([]rune(cmd)[0])) || !h.listAllowedCmd.MatchString(cmd) {
|
||||
// utils.WriteJSONError(w, http.StatusBadRequest, "команда запрещена")
|
||||
// return
|
||||
// }
|
||||
|
||||
// // ===== Проверка скрипта
|
||||
// scriptPath := h.comMatch(h.GetVersion(), cmd)
|
||||
// if scriptPath == "" {
|
||||
// utils.WriteJSONError(w, http.StatusNotFound, "команда не найдена")
|
||||
// return
|
||||
// }
|
||||
// fullPath := filepath.Join(h.cfg.ComDir, scriptPath)
|
||||
// if _, err := os.Stat(fullPath); err != nil {
|
||||
// utils.WriteJSONError(w, http.StatusNotFound, "файл команды не найден")
|
||||
// return
|
||||
// }
|
||||
|
||||
// // ===== Запуск Lua
|
||||
// L := lua.NewState()
|
||||
// defer L.Close()
|
||||
|
||||
// inTable := L.NewTable()
|
||||
// paramsTable := L.NewTable()
|
||||
// if params, ok := req.Payload["PassedParameters"].(map[string]interface{}); ok {
|
||||
// for k, v := range params {
|
||||
// L.SetField(paramsTable, k, utils.ConvertGolangTypesToLua(L, v))
|
||||
// }
|
||||
// }
|
||||
// L.SetField(inTable, "Params", paramsTable)
|
||||
// L.SetGlobal("In", inTable)
|
||||
|
||||
// resultTable := L.NewTable()
|
||||
// outTable := L.NewTable()
|
||||
// L.SetField(outTable, "Result", resultTable)
|
||||
// L.SetGlobal("Out", outTable)
|
||||
|
||||
// prepareLua := filepath.Join(h.cfg.ComDir, "_prepare.lua")
|
||||
// if _, err := os.Stat(prepareLua); err == nil {
|
||||
// if err := L.DoFile(prepareLua); err != nil {
|
||||
// utils.WriteJSONError(w, http.StatusInternalServerError, "lua _prepare ошибка: "+err.Error())
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
// if err := L.DoFile(fullPath); err != nil {
|
||||
// utils.WriteJSONError(w, http.StatusInternalServerError, "lua exec ошибка: "+err.Error())
|
||||
// return
|
||||
// }
|
||||
|
||||
// lv := L.GetGlobal("Out")
|
||||
// tbl, ok := lv.(*lua.LTable)
|
||||
// if !ok {
|
||||
// utils.WriteJSONError(w, http.StatusInternalServerError, "'Out' не таблица")
|
||||
// return
|
||||
// }
|
||||
// resultVal := tbl.RawGetString("Result")
|
||||
// resultTbl, ok := resultVal.(*lua.LTable)
|
||||
// if !ok {
|
||||
// utils.WriteJSONError(w, http.StatusInternalServerError, "'Result' не таблица")
|
||||
// return
|
||||
// }
|
||||
|
||||
// out := make(map[string]any)
|
||||
// resultTbl.ForEach(func(key lua.LValue, value lua.LValue) {
|
||||
// out[key.String()] = utils.ConvertLuaTypesToGolang(value)
|
||||
// })
|
||||
|
||||
// uuid32, _ := corestate.GetNodeUUID(filepath.Join(config.MetaDir, "uuid"))
|
||||
|
||||
// resp := PettiResponse{
|
||||
// PettiVer: req.PettiVer,
|
||||
// ResponsibleAgentUUID: uuid32,
|
||||
// PackageType: struct {
|
||||
// AnswerOf string `json:"AnswerOf"`
|
||||
// }{AnswerOf: req.PackageType.Request},
|
||||
// Payload: map[string]any{
|
||||
// "RequestedCommand": cmd,
|
||||
// "Response": out,
|
||||
// },
|
||||
// }
|
||||
|
||||
// // ===== Финальная проверка на сериализацию (валидность сборки)
|
||||
// respData, err := json.Marshal(resp)
|
||||
// if err != nil {
|
||||
// utils.WriteJSONError(w, http.StatusInternalServerError, "внутренняя ошибка: пакет невалиден")
|
||||
// return
|
||||
// }
|
||||
|
||||
// w.Header().Set("Content-Type", "application/json")
|
||||
// w.WriteHeader(http.StatusOK)
|
||||
// if _, err := w.Write(respData); err != nil {
|
||||
// h.log.Error("Ошибка при отправке JSON", slog.String("err", err.Error()))
|
||||
// }
|
||||
|
||||
// // ===== Логгирование статуса
|
||||
// status, _ := out["status"].(string)
|
||||
// switch status {
|
||||
// case "ok":
|
||||
// h.log.Info("Успешно", slog.String("cmd", cmd), slog.Any("out", out))
|
||||
// case "error":
|
||||
// h.log.Warn("Ошибка в команде", slog.String("cmd", cmd), slog.Any("out", out))
|
||||
// default:
|
||||
// h.log.Info("Неизвестный статус", slog.String("cmd", cmd), slog.Any("out", out))
|
||||
// }
|
||||
// }
|
||||
|
||||
/*
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/akyaiy/GoSally-mvp/core/config"
|
||||
"github.com/akyaiy/GoSally-mvp/core/corestate"
|
||||
"github.com/akyaiy/GoSally-mvp/core/utils"
|
||||
"github.com/go-chi/chi/v5"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
)
|
||||
|
||||
// HandlerV1 is the main handler for version 1 of the API.
|
||||
// The function processes the HTTP request and runs Lua scripts,
|
||||
// preparing the environment and subsequently transmitting the execution result
|
||||
func (h *HandlerV1) Handle(w http.ResponseWriter, r *http.Request) {
|
||||
uuid16, err := utils.NewUUID(int(config.UUIDLength))
|
||||
if err != nil {
|
||||
h.log.Error("Failed to generate UUID",
|
||||
slog.String("error", err.Error()))
|
||||
|
||||
if err := utils.WriteJSONError(w, http.StatusInternalServerError, "failed to generate UUID: "+err.Error()); err != nil {
|
||||
h.log.Error("Failed to write JSON", slog.String("err", err.Error()))
|
||||
}
|
||||
return
|
||||
}
|
||||
log := h.log.With(
|
||||
slog.Group("request",
|
||||
slog.String("version", h.GetVersion()),
|
||||
slog.String("url", r.URL.String()),
|
||||
slog.String("method", r.Method),
|
||||
),
|
||||
slog.Group("connection",
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("remote", r.RemoteAddr),
|
||||
),
|
||||
)
|
||||
log.Info("Received request")
|
||||
|
||||
cmd := chi.URLParam(r, "cmd")
|
||||
if !h.allowedCmd.MatchString(string([]rune(cmd)[0])) || !h.listAllowedCmd.MatchString(cmd) {
|
||||
log.Error("HTTP request error",
|
||||
slog.String("error", "invalid command"),
|
||||
slog.String("cmd", cmd),
|
||||
slog.Int("status", http.StatusBadRequest))
|
||||
|
||||
if err := utils.WriteJSONError(w, http.StatusBadRequest, "invalid command"); err != nil {
|
||||
h.log.Error("Failed to write JSON", slog.String("err", err.Error()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
scriptPath := h.comMatch(chi.URLParam(r, "ver"), cmd)
|
||||
if scriptPath == "" {
|
||||
log.Error("HTTP request error",
|
||||
slog.String("error", "command not found"),
|
||||
slog.String("cmd", cmd),
|
||||
slog.Int("status", http.StatusNotFound))
|
||||
|
||||
if err := utils.WriteJSONError(w, http.StatusNotFound, "command not found"); err != nil {
|
||||
h.log.Error("Failed to write JSON", slog.String("err", err.Error()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
scriptPath = filepath.Join(h.cfg.ComDir, scriptPath)
|
||||
if _, err := os.Stat(scriptPath); err != nil {
|
||||
log.Error("HTTP request error",
|
||||
slog.String("error", "command not found"),
|
||||
slog.String("cmd", cmd),
|
||||
slog.Int("status", http.StatusNotFound))
|
||||
|
||||
if err := utils.WriteJSONError(w, http.StatusNotFound, "command not found"); err != nil {
|
||||
h.log.Error("Failed to write JSON", slog.String("err", err.Error()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
L := lua.NewState()
|
||||
defer L.Close()
|
||||
|
||||
paramsTable := L.NewTable()
|
||||
qt := r.URL.Query()
|
||||
for k, v := range qt {
|
||||
if len(v) > 0 {
|
||||
L.SetField(paramsTable, k, lua.LString(v[0]))
|
||||
}
|
||||
}
|
||||
inTable := L.NewTable()
|
||||
L.SetField(inTable, "Params", paramsTable)
|
||||
L.SetGlobal("In", inTable)
|
||||
|
||||
// Создаем таблицу Out с Result
|
||||
resultTable := L.NewTable()
|
||||
outTable := L.NewTable()
|
||||
L.SetField(outTable, "Result", resultTable)
|
||||
L.SetGlobal("Out", outTable)
|
||||
|
||||
prepareLuaEnv := filepath.Join(h.cfg.ComDir, "_prepare.lua")
|
||||
if _, err := os.Stat(prepareLuaEnv); err == nil {
|
||||
if err := L.DoFile(prepareLuaEnv); err != nil {
|
||||
log.Error("Failed to prepare lua environment",
|
||||
slog.String("error", err.Error()))
|
||||
|
||||
if err := utils.WriteJSONError(w, http.StatusInternalServerError, "lua error: "+err.Error()); err != nil {
|
||||
h.log.Error("Failed to write JSON", slog.String("err", err.Error()))
|
||||
}
|
||||
return
|
||||
}
|
||||
} else {
|
||||
log.Warn("No environment preparation script found, skipping preparation")
|
||||
}
|
||||
|
||||
if err := L.DoFile(scriptPath); err != nil {
|
||||
log.Error("Failed to execute lua script",
|
||||
slog.String("error", err.Error()))
|
||||
if err := utils.WriteJSONError(w, http.StatusInternalServerError, "lua error: "+err.Error()); err != nil {
|
||||
h.log.Error("Failed to write JSON", slog.String("err", err.Error()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
lv := L.GetGlobal("Out")
|
||||
tbl, ok := lv.(*lua.LTable)
|
||||
if !ok {
|
||||
log.Error("Lua global 'Out' is not a table")
|
||||
|
||||
if err := utils.WriteJSONError(w, http.StatusInternalServerError, "'Out' is not a table"); err != nil {
|
||||
h.log.Error("Failed to write JSON", slog.String("err", err.Error()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
resultVal := tbl.RawGetString("Result")
|
||||
resultTbl, ok := resultVal.(*lua.LTable)
|
||||
if !ok {
|
||||
log.Error("Lua global 'Result' is not a table")
|
||||
|
||||
if err := utils.WriteJSONError(w, http.StatusInternalServerError, "'Result' is not a table"); err != nil {
|
||||
h.log.Error("Failed to write JSON", slog.String("err", err.Error()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
out := make(map[string]any)
|
||||
resultTbl.ForEach(func(key lua.LValue, value lua.LValue) {
|
||||
out[key.String()] = utils.ConvertLuaTypesToGolang(value)
|
||||
})
|
||||
uuid32, _ := corestate.GetNodeUUID(filepath.Join(config.MetaDir, "uuid"))
|
||||
response := ResponseFormat{
|
||||
ResponsibleAgentUUID: uuid32,
|
||||
RequestedCommand: cmd,
|
||||
Response: out,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(response); err != nil {
|
||||
log.Error("Failed to encode JSON response",
|
||||
slog.String("error", err.Error()))
|
||||
}
|
||||
|
||||
status, _ := out["status"].(string)
|
||||
switch status {
|
||||
case "error":
|
||||
log.Info("Command executed with error",
|
||||
slog.String("cmd", cmd),
|
||||
slog.Any("result", out))
|
||||
case "ok":
|
||||
log.Info("Command executed successfully",
|
||||
slog.String("cmd", cmd),
|
||||
slog.Any("result", out))
|
||||
default:
|
||||
log.Info("Command executed and returned an unknown status",
|
||||
slog.String("cmd", cmd),
|
||||
slog.Any("result", out))
|
||||
}
|
||||
|
||||
log.Info("Session completed")
|
||||
}
|
||||
*/
|
||||
133
internal/server/sv1/handle_list.go
Normal file
133
internal/server/sv1/handle_list.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package sv1
|
||||
|
||||
/*
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/akyaiy/GoSally-mvp/core/config"
|
||||
"github.com/akyaiy/GoSally-mvp/core/corestate"
|
||||
"github.com/akyaiy/GoSally-mvp/core/utils"
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
// The function processes the HTTP request and returns a list of available commands.
|
||||
func (h *HandlerV1) HandleList(w http.ResponseWriter, r *http.Request) {
|
||||
uuid16, err := utils.NewUUID(int(config.UUIDLength))
|
||||
if err != nil {
|
||||
h.log.Error("Failed to generate UUID",
|
||||
slog.String("error", err.Error()))
|
||||
|
||||
if err := utils.WriteJSONError(w, http.StatusInternalServerError, "failed to generate UUID: "+err.Error()); err != nil {
|
||||
h.log.Error("Failed to write JSON", slog.String("err", err.Error()))
|
||||
}
|
||||
return
|
||||
}
|
||||
log := h.log.With(
|
||||
slog.Group("request",
|
||||
slog.String("version", h.GetVersion()),
|
||||
slog.String("url", r.URL.String()),
|
||||
slog.String("method", r.Method),
|
||||
),
|
||||
slog.Group("connection",
|
||||
slog.String("connection-uuid", uuid16),
|
||||
slog.String("remote", r.RemoteAddr),
|
||||
),
|
||||
)
|
||||
log.Info("Received request")
|
||||
type ComMeta struct {
|
||||
Description string `json:"Description"`
|
||||
Arguments map[string]string `json:"Arguments,omitempty"`
|
||||
}
|
||||
var (
|
||||
files []os.DirEntry
|
||||
commands = make(map[string]ComMeta)
|
||||
cmdsProcessed = make(map[string]bool)
|
||||
)
|
||||
|
||||
if files, err = os.ReadDir(h.cfg.ComDir); err != nil {
|
||||
log.Error("Failed to read commands directory",
|
||||
slog.String("error", err.Error()))
|
||||
|
||||
if err := utils.WriteJSONError(w, http.StatusInternalServerError, "failed to read commands directory: "+err.Error()); err != nil {
|
||||
h.log.Error("Failed to write JSON", slog.String("err", err.Error()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
apiVer := chi.URLParam(r, "ver")
|
||||
|
||||
// Сначала ищем версионные
|
||||
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 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
|
||||
}
|
||||
}
|
||||
|
||||
// Потом фоллбеки
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug("Command list prepared")
|
||||
|
||||
log.Info("Session completed")
|
||||
uuid32, _ := corestate.GetNodeUUID(filepath.Join(config.MetaDir, "uuid"))
|
||||
response := ResponseFormat{
|
||||
ResponsibleAgentUUID: uuid32,
|
||||
RequestedCommand: "list",
|
||||
Response: commands,
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(response); err != nil {
|
||||
h.log.Error("Failed to write JSON error response",
|
||||
slog.String("error", err.Error()))
|
||||
}
|
||||
}
|
||||
*/
|
||||
20
internal/server/sv1/petti.go
Normal file
20
internal/server/sv1/petti.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package sv1
|
||||
|
||||
// PETTI - Go Sally Protocol for Exchanging Technical Tasks and Information
|
||||
|
||||
type PettiRequest struct {
|
||||
PettiVer string `json:"PettiVer"`
|
||||
PackageType struct {
|
||||
Request string `json:"Request"`
|
||||
} `json:"PackageType"`
|
||||
Payload map[string]any `json:"Payload"`
|
||||
}
|
||||
|
||||
type PettiResponse struct {
|
||||
PettiVer string `json:"PettiVer"`
|
||||
PackageType struct {
|
||||
AnswerOf string `json:"AnswerOf"`
|
||||
} `json:"PackageType"`
|
||||
ResponsibleAgentUUID string `json:"ResponsibleAgentUUID"`
|
||||
Payload map[string]any `json:"Payload"`
|
||||
}
|
||||
51
internal/server/sv1/server.go
Normal file
51
internal/server/sv1/server.go
Normal file
@@ -0,0 +1,51 @@
|
||||
// Package sv1 provides the implementation of the Server V1 API handler.
|
||||
// It includes utilities for handling API requests, extracting descriptions, and managing UUIDs.
|
||||
package sv1
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"regexp"
|
||||
|
||||
"github.com/akyaiy/GoSally-mvp/internal/engine/config"
|
||||
)
|
||||
|
||||
// HandlerV1InitStruct structure is only for initialization
|
||||
type HandlerV1InitStruct struct {
|
||||
Ver string
|
||||
Log slog.Logger
|
||||
Config *config.Conf
|
||||
AllowedCmd *regexp.Regexp
|
||||
ListAllowedCmd *regexp.Regexp
|
||||
}
|
||||
|
||||
// HandlerV1 implements the ServerV1UtilsContract and serves as the main handler for API requests.
|
||||
type HandlerV1 struct {
|
||||
log *slog.Logger
|
||||
|
||||
cfg *config.Conf
|
||||
|
||||
// allowedCmd and listAllowedCmd are regular expressions used to validate command names.
|
||||
allowedCmd *regexp.Regexp
|
||||
listAllowedCmd *regexp.Regexp
|
||||
|
||||
ver string
|
||||
}
|
||||
|
||||
// InitV1Server initializes a new HandlerV1 with the provided configuration and returns it.
|
||||
// Should be carefull with giving to this function invalid parameters,
|
||||
// because there is no validation of parameters in this function.
|
||||
func InitV1Server(o *HandlerV1InitStruct) *HandlerV1 {
|
||||
return &HandlerV1{
|
||||
log: &o.Log,
|
||||
cfg: o.Config,
|
||||
allowedCmd: o.AllowedCmd,
|
||||
listAllowedCmd: o.ListAllowedCmd,
|
||||
ver: o.Ver,
|
||||
}
|
||||
}
|
||||
|
||||
// GetVersion returns the API version of the HandlerV1, which is set during initialization.
|
||||
// This version is used to identify the API version in the request routing.
|
||||
func (h *HandlerV1) GetVersion() string {
|
||||
return h.ver
|
||||
}
|
||||
60
internal/server/sv1/utils.go
Normal file
60
internal/server/sv1/utils.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package sv1
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
)
|
||||
|
||||
// func (h *HandlerV1) errNotFound(w http.ResponseWriter, r *http.Request) {
|
||||
// utils.WriteJSONError(h.w, 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))
|
||||
// }
|
||||
|
||||
// func (h *HandlerV1) extractDescriptionStatic(path string) (string, error) {
|
||||
// data, err := os.ReadFile(path)
|
||||
// if err != nil {
|
||||
// return "", err
|
||||
// }
|
||||
|
||||
// re := regexp.MustCompile(`---\s*#description\s*=\s*"([^"]+)"`)
|
||||
// m := re.FindStringSubmatch(string(data))
|
||||
// if len(m) <= 0 {
|
||||
// return "", nil
|
||||
// }
|
||||
// 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