package app import ( "context" "database/sql" "fmt" "html/template" "log" "net/http" "time" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" _ "modernc.org/sqlite" ) const filePath = "goshare.db" type App struct { router http.Handler db *sql.DB } func New() *App { db, err := sql.Open("sqlite", filePath) if err != nil { log.Fatalf("failed to open db: %s", err) } app := &App{ db: db, } app.loadRoutes() return app } func (a *App) loadRoutes() { router := chi.NewRouter() router.Use(middleware.Recoverer) fs := http.FileServer(http.Dir("static")) router.Handle("/static/*", http.StripPrefix("/static/", fs)) router.Get("/", func(w http.ResponseWriter, r *http.Request) { t, err := template.ParseFiles("templates/index.html") if err != nil { fmt.Println(err) return } err = t.Execute(w, nil) if err != nil { fmt.Println(err) return } }) router.Post("/api/upload", uploadFile) a.router = router } func uploadFile(w http.ResponseWriter, r *http.Request) { err := r.ParseMultipartForm(10 << 20) if err != nil { log.Fatal(err) return } file, handler, err := r.FormFile("file") if err != nil { log.Fatal(err) return } defer file.Close() fmt.Printf("%s %d %s", handler.Filename, handler.Size, handler.Header) } func (a *App) Start(ctx context.Context) error { server := &http.Server{ Addr: ":5454", Handler: a.router, } fmt.Println("Starting server") ch := make(chan error, 1) go func () { err := server.ListenAndServe() if err != nil { ch <- fmt.Errorf("failed to start server: %w", err) } close(ch) }() select { case err := <-ch: return err case <-ctx.Done(): timeout, cancel := context.WithTimeout(context.Background(), time.Second*10) defer cancel() return server.Shutdown(timeout) } }