152 lines
3.8 KiB
Go
152 lines
3.8 KiB
Go
package service
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/fs"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.towk2.me/towk/configurator/pkg/util"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
func (s *Service) Download() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
path = s.PathForData() + strings.TrimPrefix(r.URL.Path, "/download")
|
|
fileInfo os.FileInfo
|
|
out *os.File
|
|
contents []byte
|
|
err error
|
|
)
|
|
|
|
log.Debug().
|
|
Str("path", path).
|
|
Str("client_host", r.Host).
|
|
Msg("Service.Download()")
|
|
|
|
// determine if path is directory, file, or exists
|
|
if fileInfo, err = os.Stat(path); err == nil {
|
|
if fileInfo.IsDir() {
|
|
// create an archive of the directory and download
|
|
log.Debug().
|
|
Str("type", "directory").
|
|
Msg("Service.Download()")
|
|
|
|
archivePath := fmt.Sprintf("%d.tar.gz", time.Now().Unix())
|
|
out, err = os.Create(archivePath)
|
|
if err != nil {
|
|
s.writeErrorResponse(w, fmt.Sprintf("failed to create named file: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
filesToArchive := []string{}
|
|
filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error {
|
|
if !d.IsDir() {
|
|
filesToArchive = append(filesToArchive, path)
|
|
}
|
|
return nil
|
|
})
|
|
log.Debug().Strs("files", filesToArchive).Send()
|
|
err = util.CreateArchive(filesToArchive, out)
|
|
if err != nil {
|
|
s.writeErrorResponse(w, fmt.Sprintf("failed to create archive: %v", err.Error()), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
contents, err = os.ReadFile(archivePath)
|
|
if err != nil {
|
|
s.writeErrorResponse(w, fmt.Sprintf("failed to read archive: %v", err.Error()), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Write(contents)
|
|
|
|
err = os.Remove(archivePath)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("failed to remove temporary archive")
|
|
return
|
|
}
|
|
|
|
} else {
|
|
// download individual file
|
|
log.Debug().
|
|
Str("type", "file").
|
|
Msg("Service.Download()")
|
|
contents, err = os.ReadFile(path)
|
|
if err != nil {
|
|
s.writeErrorResponse(w, fmt.Sprintf("failed to read file to download: %v", err.Error()), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.Write(contents)
|
|
}
|
|
} else {
|
|
s.writeErrorResponse(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *Service) Upload() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
}
|
|
}
|
|
|
|
func (s *Service) List() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
path = s.PathForData() + strings.TrimPrefix(r.URL.Path, "/list")
|
|
entries []string
|
|
body []byte
|
|
err error
|
|
)
|
|
|
|
// show what we're listing
|
|
log.Debug().Str("path", path).Msg("Service.List()")
|
|
|
|
// walk directory and show all entries "ls"
|
|
err = filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
entries = append(entries, d.Name())
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
switch err {
|
|
case fs.ErrNotExist, fs.ErrInvalid:
|
|
http.Error(w, "No such file or directory...", http.StatusBadRequest)
|
|
case fs.ErrPermission:
|
|
http.Error(w, "Invalid permissions...", http.StatusForbidden)
|
|
default:
|
|
http.Error(w, "Something went wrong (file or directory *probably* does not exist)...", http.StatusInternalServerError)
|
|
}
|
|
return
|
|
}
|
|
|
|
body, err = json.Marshal(entries)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Write(body)
|
|
}
|
|
}
|
|
|
|
func (s *Service) GetStatus(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
err := json.NewEncoder(w).Encode(map[string]any{
|
|
"code": http.StatusOK,
|
|
"message": "Configurator is healthy",
|
|
})
|
|
if err != nil {
|
|
fmt.Printf("failed to encode JSON response body: %v\n", err)
|
|
return
|
|
}
|
|
}
|