108 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
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
 | 
						|
}
 |