feat: updated server implementation
This commit is contained in:
parent
0d27f07a8b
commit
d56a9e452f
5 changed files with 348 additions and 75 deletions
|
|
@ -3,44 +3,91 @@ 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 = strings.TrimPrefix(r.URL.Path, "/download")
|
||||
path = s.PathForData() + strings.TrimPrefix(r.URL.Path, "/download")
|
||||
fileInfo os.FileInfo
|
||||
out *os.File
|
||||
contents []byte
|
||||
err error
|
||||
)
|
||||
|
||||
fmt.Printf("download path: %v\n", path)
|
||||
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(filepath.Clean(path)); err != nil {
|
||||
if fileInfo, err = os.Stat(path); err == nil {
|
||||
if fileInfo.IsDir() {
|
||||
// recursively walk dir acompressednd get all filenames
|
||||
// download directory as archive
|
||||
out, err = os.Create(fmt.Sprintf("%s.tar", path))
|
||||
if err != nil {
|
||||
// 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
|
||||
}
|
||||
err = util.CreateArchive([]string{path}, out)
|
||||
if err != nil {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -52,19 +99,54 @@ func (s *Service) Upload() http.HandlerFunc {
|
|||
|
||||
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")
|
||||
data := map[string]any{
|
||||
"code": 200,
|
||||
err := json.NewEncoder(w).Encode(map[string]any{
|
||||
"code": http.StatusOK,
|
||||
"message": "Configurator is healthy",
|
||||
}
|
||||
err := json.NewEncoder(w).Encode(data)
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Printf("failed to encode JSON: %v\n", err)
|
||||
fmt.Printf("failed to encode JSON response body: %v\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue