summaryrefslogblamecommitdiff
path: root/main.go
blob: 2c15ed641eb93ae59bd949827752dc4fe0943e83 (plain) (tree)
1
2
3
4
5
6
7
8






                 
                  





                       

                                     



                                    




                              




                                                                                 
                                                                          












                                                                                        

                                                                                 

                           





                                                           





















































                                                                                                              
package main

import (
	"context"
	"flag"
	"io/fs"
	"log"
	"log/slog"
	"net/http"
	"os"
	"os/signal"
	"path/filepath"
	"time"

	"go.neonxp.ru/mux"
	"go.neonxp.ru/mux/middleware"
	"golang.org/x/sync/errgroup"
)

var (
	host     string
	listen   string
	path     string
	htmlPath string
	ttl      time.Duration
)

func init() {
	flag.StringVar(&host, "host", "https://nixshare.ru/", "host of nixshare")
	flag.StringVar(&listen, "listen", ":8000", "port to listen")
	flag.StringVar(&htmlPath, "html_path", "./html", "html directory")
	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))
	r.Handle("/", http.FileServer(http.Dir("html")))
	r.Handle("/s/", http.StripPrefix("/s/", http.FileServer(http.Dir(path))))

	srv := http.Server{
		Addr: listen,
		Handler: mux.Use(r,
			middleware.Recover(slog.Default()),
			middleware.RequestID,
			middleware.Logger(slog.Default()),
		),
	}

	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)
	}
}