121 lines
3.1 KiB
Go
121 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
duihttp "dwelling-upload/internal/http"
|
|
"dwelling-upload/pkg/utils"
|
|
"dwelling-upload/pkg/watcher"
|
|
"dwelling-upload/web"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"path"
|
|
"syscall"
|
|
|
|
"git.arav.su/Arav/httpr"
|
|
)
|
|
|
|
var (
|
|
listenAddress = flag.String("listen", "/var/run/dwelling-upload/sock", "listen address (ip:port|unix_path)")
|
|
uploadDir = flag.String("dir", "/srv/upload", "directory where uploaded files are stored")
|
|
expiry = flag.Int("expiry", 36, "keep files for this much hours")
|
|
storageSize = flag.Int64("storage", 102400, "storage size in MiB for uploads")
|
|
fileSize = flag.Int64("file", 128, "max. size in MiB for files")
|
|
|
|
showVersion *bool = flag.Bool("v", false, "show version")
|
|
)
|
|
|
|
var version string
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
log.SetFlags(log.Llongfile)
|
|
|
|
if *showVersion {
|
|
fmt.Println("dwelling-upload Ver. ", version, "\nCopyright (c) 2022,2023 Alexander \"Arav\" Andreev <me@arav.su>")
|
|
return
|
|
}
|
|
|
|
hashSalt, err := os.ReadFile(path.Join(os.Getenv("CREDENTIALS_DIRECTORY"), "salt"))
|
|
if err != nil {
|
|
log.Fatalln("failed to read hash salt file:", err)
|
|
}
|
|
|
|
logFilePath := path.Join(os.Getenv("LOGS_DIRECTORY"), "file.log")
|
|
|
|
logFileFd, err := os.OpenFile(logFilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660)
|
|
if err != nil {
|
|
log.Fatalln("failed to open file.log:", err)
|
|
}
|
|
defer logFileFd.Close()
|
|
|
|
logFile := log.New(logFileFd, "", log.LstdFlags)
|
|
|
|
uploadDirSize, err := utils.DirectorySize(*uploadDir)
|
|
if err != nil {
|
|
log.Fatalf("failed to get initial size of %s: %s", *uploadDir, err)
|
|
}
|
|
|
|
hand := duihttp.NewUploadHandlers(logFile, *uploadDir, &uploadDirSize, string(hashSalt),
|
|
*expiry, *storageSize, *fileSize)
|
|
|
|
r := httpr.New()
|
|
|
|
r.NotFoundHandler = func(w http.ResponseWriter, r *http.Request) {
|
|
duihttp.Error(w, r, "", http.StatusNotFound)
|
|
}
|
|
|
|
r.Handler(http.MethodGet, "/", hand.Index)
|
|
r.Handler(http.MethodPost, "/", hand.Upload)
|
|
r.Handler(http.MethodGet, "/:hash/:name", hand.Download)
|
|
r.Handler(http.MethodPost, "/delete", hand.Delete)
|
|
r.Handler(http.MethodDelete, "/:hash", hand.Delete)
|
|
|
|
r.ServeStatic("/assets/*filepath", web.Assets())
|
|
r.Handler(http.MethodGet, "/robots.txt", duihttp.RobotsTxt)
|
|
r.Handler(http.MethodGet, "/favicon.svg", duihttp.Favicon)
|
|
|
|
srv := duihttp.NewHttpServer(r)
|
|
|
|
if err := srv.Start(*listenAddress); err != nil {
|
|
log.Fatalln("failed to start a server:", err)
|
|
}
|
|
defer func() {
|
|
if err := srv.Stop(); err != nil {
|
|
log.Fatalln("failed to properly shutdown a server:", err)
|
|
}
|
|
}()
|
|
|
|
doneSignal := make(chan os.Signal, 1)
|
|
signal.Notify(doneSignal, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
|
|
|
|
watcha, err := watcher.NewInotifyWatcher()
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
defer watcha.Close()
|
|
|
|
if err := watcha.AddWatch(*uploadDir, watcher.CrDelMask); err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
|
|
uploadDirNotify := make(chan uint32)
|
|
go watcha.WatchForMask(uploadDirNotify, watcher.CrDelMask)
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-uploadDirNotify:
|
|
uploadDirSize, err = utils.DirectorySize(*uploadDir)
|
|
if err != nil {
|
|
log.Println("failed to get uploads directory size:", err)
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
|
|
<-doneSignal
|
|
}
|