package main import ( "crypto/tls" "database/sql" "flag" "log/slog" "net/http" "os" "text/template" "time" "git.32bit.cafe/32bitcafe/guestbook/internal/models" "github.com/alexedwards/scs/sqlite3store" "github.com/alexedwards/scs/v2" "github.com/gorilla/schema" _ "github.com/mattn/go-sqlite3" ) type application struct { sequence uint16 logger *slog.Logger templateCache map[string]*template.Template templateCacheHTMX map[string]*template.Template guestbooks *models.GuestbookModel users *models.UserModel guestbookComments *models.GuestbookCommentModel sessionManager *scs.SessionManager formDecoder *schema.Decoder } func main() { addr := flag.String("addr", ":3000", "HTTP network address") dsn := flag.String("dsn", "guestbook.db", "data source name") flag.Parse() logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})) db, err := openDB(*dsn) if err != nil { logger.Error(err.Error()) os.Exit(1) } defer db.Close() templateCache, err := newTemplateCache() if err != nil { logger.Error(err.Error()) os.Exit(1) } templateCacheHTMX, err := newHTMXTemplateCache() if err != nil { logger.Error(err.Error()) os.Exit(1) } sessionManager := scs.New() sessionManager.Store = sqlite3store.New(db) sessionManager.Lifetime = 12 * time.Hour formDecoder := schema.NewDecoder() formDecoder.IgnoreUnknownKeys(true) app := &application{ sequence: 0, templateCache: templateCache, templateCacheHTMX: templateCacheHTMX, logger: logger, sessionManager: sessionManager, guestbooks: &models.GuestbookModel{DB: db}, users: &models.UserModel{DB: db}, guestbookComments: &models.GuestbookCommentModel{DB: db}, formDecoder: formDecoder, } tlsConfig := &tls.Config{ CurvePreferences: []tls.CurveID{tls.X25519, tls.CurveP256}, } srv := &http.Server { Addr: *addr, Handler: app.routes(), ErrorLog: slog.NewLogLogger(logger.Handler(), slog.LevelError), TLSConfig: tlsConfig, IdleTimeout: time.Minute, ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, } logger.Info("Starting server", slog.Any("addr", *addr)) err = srv.ListenAndServeTLS("./tls/cert.pem", "./tls/key.pem") logger.Error(err.Error()) os.Exit(1) } func openDB(dsn string) (*sql.DB, error) { db, err := sql.Open("sqlite3", dsn) if err != nil { return nil, err } if err = db.Ping(); err != nil { return nil, err } return db, nil } func getUserId() int64 { return 1 }