nixshare/main.go

109 lines
2.1 KiB
Go
Raw Permalink Normal View History

2024-08-28 13:47:44 +03:00
package main
import (
"context"
"flag"
"io/fs"
"log"
2024-08-28 15:22:01 +03:00
"log/slog"
2024-08-28 13:47:44 +03:00
"net/http"
"os"
"os/signal"
"path/filepath"
"time"
2024-08-28 15:22:01 +03:00
"go.neonxp.ru/mux"
"go.neonxp.ru/mux/middleware"
2024-08-28 13:47:44 +03:00
"golang.org/x/sync/errgroup"
)
var (
2024-08-28 15:22:01 +03:00
host string
listen string
path string
htmlPath string
ttl time.Duration
2024-08-28 13:47:44 +03:00
)
func init() {
flag.StringVar(&host, "host", "https://nixshare.ru/", "host of nixshare")
flag.StringVar(&listen, "listen", ":8000", "port to listen")
2024-08-28 15:22:01 +03:00
flag.StringVar(&htmlPath, "html_path", "./html", "html directory")
2024-08-28 13:47:44 +03:00
flag.StringVar(&path, "path", "./storage", "storage directory")
flag.DurationVar(&ttl, "ttl", 24*time.Hour, "time to delete uploaded file")
}
func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancel()
flag.Parse()
r := http.NewServeMux()
r.Handle("POST /upload", http.HandlerFunc(uploadHandler))
2024-08-28 15:22:01 +03:00
r.Handle("/", http.FileServer(http.Dir("html")))
r.Handle("/s/", http.StripPrefix("/s/", http.FileServer(http.Dir(path))))
2024-08-28 13:47:44 +03:00
srv := http.Server{
2024-08-28 15:22:01 +03:00
Addr: listen,
Handler: mux.Use(r,
middleware.Recover(slog.Default()),
middleware.RequestID,
middleware.Logger(slog.Default()),
),
2024-08-28 13:47:44 +03:00
}
eg, egCtx := errgroup.WithContext(ctx)
eg.Go(func() error {
<-egCtx.Done()
srv.Close()
return nil
})
eg.Go(func() error {
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
return err
}
return nil
})
eg.Go(func() error {
timer := time.NewTimer(1 * time.Minute)
defer timer.Stop()
for {
select {
case <-timer.C:
now := time.Now()
err := filepath.Walk(path, func(p string, info fs.FileInfo, err error) error {
if info == nil {
return nil
}
if info.IsDir() {
return nil
}
if now.Sub(info.ModTime()).Seconds() > ttl.Seconds() {
log.Println("delete old file:", p)
if err := os.Remove(p); err != nil {
return err
}
}
return nil
})
if err != nil {
log.Println(err)
}
case <-egCtx.Done():
return nil
}
}
})
if err := eg.Wait(); err != nil {
log.Fatal(err)
}
}