loglevel change endpoint
This commit is contained in:
@@ -1,19 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log/slog"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *Server) handlerRefresh(w http.ResponseWriter, req *http.Request) {
|
|
||||||
if req.Header.Get("Authorization") != "Bearer "+s.cfg.Auth.Token {
|
|
||||||
http.Error(w, "unauthorized", http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := s.c.Refresh(); err != nil {
|
|
||||||
slog.Error("refresh failed", "err", err)
|
|
||||||
http.Error(w, "refresh failed", http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusNoContent)
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"log/slog"
|
|
||||||
"net/http"
|
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/ewpt3ch/pkgstash/internal/cache"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *Server) handlePackage(w http.ResponseWriter, req *http.Request) {
|
|
||||||
|
|
||||||
// db files are not signed so we ignore as to not spam mirrors
|
|
||||||
if strings.HasSuffix(req.PathValue("file"), ".db.sig") {
|
|
||||||
w.WriteHeader(http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// record the useragent from requestor
|
|
||||||
slog.Debug("Requestors User Agent", "UA", req.Header.Get("User-Agent"))
|
|
||||||
|
|
||||||
// build file paths from the request, they follow archlinux repo
|
|
||||||
// <mirrorroot>/[core, extra, etc]/os/[x86_64, arm, etc]/package.pkg.tar.zst[.sig]
|
|
||||||
repo := req.PathValue("repo")
|
|
||||||
arch := req.PathValue("arch")
|
|
||||||
file := req.PathValue("file")
|
|
||||||
repoPath := filepath.Join(repo, "os", arch, file) //path from mirror root to requested file
|
|
||||||
|
|
||||||
cachedFile, err := s.c.Fetch(repoPath)
|
|
||||||
if err != nil {
|
|
||||||
if upstreamErr, ok := errors.AsType[*cache.UpstreamError](err); ok {
|
|
||||||
slog.Warn("upstream error", "err", upstreamErr.Error())
|
|
||||||
http.Error(w, "Not found upstream", upstreamErr.StatusCode)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
slog.Warn("fetch error", "err", err)
|
|
||||||
http.Error(w, "Failed to fetch from upstream", http.StatusBadGateway)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer cachedFile.Reader.Close()
|
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/octet-stream")
|
|
||||||
w.Header().Set("Content-Disposition", "attachment; filename="+cachedFile.Filename)
|
|
||||||
w.Header().Set("Content-Length", strconv.FormatInt(cachedFile.Size, 10))
|
|
||||||
_, err = io.Copy(w, cachedFile.Reader)
|
|
||||||
if err != nil {
|
|
||||||
slog.Warn("streaming error", "err", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+35
-1
@@ -1,8 +1,10 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) handlerRefresh(w http.ResponseWriter, req *http.Request) {
|
func (s *Server) handlerRefresh(w http.ResponseWriter, req *http.Request) {
|
||||||
@@ -10,6 +12,8 @@ func (s *Server) handlerRefresh(w http.ResponseWriter, req *http.Request) {
|
|||||||
http.Error(w, "unauthorized", http.StatusInternalServerError)
|
http.Error(w, "unauthorized", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer req.Body.Close()
|
||||||
|
|
||||||
if err := s.c.Refresh(); err != nil {
|
if err := s.c.Refresh(); err != nil {
|
||||||
slog.Error("refresh failed", "err", err)
|
slog.Error("refresh failed", "err", err)
|
||||||
http.Error(w, "refresh failed", http.StatusInternalServerError)
|
http.Error(w, "refresh failed", http.StatusInternalServerError)
|
||||||
@@ -20,8 +24,38 @@ func (s *Server) handlerRefresh(w http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
func (s *Server) handlerLogLevel(w http.ResponseWriter, req *http.Request) {
|
func (s *Server) handlerLogLevel(w http.ResponseWriter, req *http.Request) {
|
||||||
if req.Header.Get("Authorization") != "Bearer "+s.cfg.Auth.Token {
|
if req.Header.Get("Authorization") != "Bearer "+s.cfg.Auth.Token {
|
||||||
http.Error(w, "unauthorized", http.StatusInternalServerError)
|
respondWithError(w, http.StatusUnauthorized, "unauthorized")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer req.Body.Close()
|
||||||
|
|
||||||
|
type reqParameters struct {
|
||||||
|
NewLevel string `json:"loglevel"`
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(req.Body)
|
||||||
|
reqParams := reqParameters{}
|
||||||
|
err := decoder.Decode(&reqParams)
|
||||||
|
if err != nil {
|
||||||
|
slog.Debug("json decode erro", "err", err)
|
||||||
|
respondWithError(w, http.StatusBadRequest, "invalid request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch strings.ToLower(reqParams.NewLevel) {
|
||||||
|
case "debug":
|
||||||
|
s.logLevel.Set(slog.LevelDebug)
|
||||||
|
case "info":
|
||||||
|
s.logLevel.Set(slog.LevelInfo)
|
||||||
|
case "warn":
|
||||||
|
s.logLevel.Set(slog.LevelWarn)
|
||||||
|
case "error":
|
||||||
|
s.logLevel.Set(slog.LevelError)
|
||||||
|
default:
|
||||||
|
respondWithError(w, http.StatusBadRequest, "invalid log level")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
slog.Info("log level changed", "level", reqParams.NewLevel)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
type Server struct {
|
type Server struct {
|
||||||
cfg *Config
|
cfg *Config
|
||||||
c *cache.Cache
|
c *cache.Cache
|
||||||
|
logLevel *slog.LevelVar
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -29,10 +30,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//set log level from flag if available
|
//set log level from flag if available
|
||||||
var logLevel slog.Level
|
logLevel := new(slog.LevelVar)
|
||||||
if err := logLevel.UnmarshalText([]byte(*logFlag)); err != nil {
|
if err := logLevel.UnmarshalText([]byte(*logFlag)); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "invalid log level %q, defaulting to INFO\n", *logFlag)
|
fmt.Fprintf(os.Stderr, "invalid log level %q, defaulting to INFO\n", *logFlag)
|
||||||
logLevel = slog.LevelInfo
|
logLevel.Set(slog.LevelInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
|
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
|
||||||
@@ -47,11 +48,16 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c := cache.NewCache(cfg.CacheRoot, cfg.MirrorURLs, cfg.MirroredRepos)
|
c := cache.NewCache(cfg.CacheRoot, cfg.MirrorURLs, cfg.MirroredRepos)
|
||||||
srv := &Server{cfg: cfg, c: c}
|
srv := &Server{
|
||||||
|
cfg: cfg,
|
||||||
|
c: c,
|
||||||
|
logLevel: logLevel,
|
||||||
|
}
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.HandleFunc("GET /{repo}/os/{arch}/{file}", srv.handlePackage)
|
mux.HandleFunc("GET /{repo}/os/{arch}/{file}", srv.handlerPackage)
|
||||||
mux.HandleFunc("POST /api/refresh", srv.handlerRefresh)
|
mux.HandleFunc("POST /api/refresh", srv.handlerRefresh)
|
||||||
|
mux.HandleFunc("POST /api/loglevel", srv.handlerLogLevel)
|
||||||
|
|
||||||
if err := srv.c.Refresh(); err != nil {
|
if err := srv.c.Refresh(); err != nil {
|
||||||
slog.Error("failed to refesh db files", "err", err)
|
slog.Error("failed to refesh db files", "err", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user