Files
GoSally/core/general_server/hanle_multi.go
alex d442871950 Refactor configuration and update handling:
- Modify .luarc.json to include global Lua scripts.
- Update Makefile to include LDFLAGS for versioning.
- Enhance node.go to implement version checking and update handling.
- Refactor Lua global variables in _globals.lua and echo.lua to use new structures.
- Remove deprecated http.lua and update config.yaml for TLS and update settings.
- Introduce new update.go for version management and update checking.
- Add tests for version comparison in update_test.go.
- Improve error handling in various server methods.
2025-07-03 22:38:05 +03:00

170 lines
4.1 KiB
Go

package general_server
import (
"encoding/json"
"errors"
"log/slog"
"net/http"
"slices"
"github.com/akyaiy/GoSally-mvp/core/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")
log := s.log.With(
slog.Group("request",
slog.String("version", serverReqApiVer),
slog.String("url", s.r.URL.String()),
slog.String("method", s.r.Method),
),
slog.Group("connection",
slog.String("remote", s.r.RemoteAddr),
),
)
s.log.Debug("Received request")
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.Debug("Using latest version under custom layer",
slog.String("layer", serverReqApiVer),
slog.String("fallback-version", s.cfg.LatestVer),
)
srv.Handle(w, r)
return
}
}
log.Error("HTTP request error: unsupported API version",
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")
log := s.log.With(
slog.Group("request",
slog.String("version", serverReqApiVer),
slog.String("url", s.r.URL.String()),
slog.String("method", s.r.Method),
),
slog.Group("connection",
slog.String("remote", s.r.RemoteAddr),
),
)
log.Debug("Received request")
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 {
log.Debug("Using latest version under custom layer",
slog.String("layer", serverReqApiVer),
slog.String("fallback-version", s.cfg.LatestVer),
)
srv.HandleList(w, r)
return
}
}
log.Error("HTTP request error: unsupported API version",
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,
}
if err := json.NewEncoder(s.w).Encode(resp); err != nil {
s.log.Error("Failed to write JSON error response",
slog.String("error", err.Error()),
slog.Int("status", status))
return
}
}