Move HTTP handler logic out of main into internal api and server packages, slimming main to a thin entrypoint. Bundles bug fixes: login nil-panic, empty-password validation, chirp sort ordering, duplicate-email 409, and restricting the file server to the assets directory.
85 lines
1.7 KiB
Go
85 lines
1.7 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
_ "embed"
|
|
"errors"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"strings"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/StevanFreeborn/chirpy/internal/database"
|
|
"github.com/StevanFreeborn/chirpy/internal/server"
|
|
"github.com/joho/godotenv"
|
|
_ "github.com/lib/pq"
|
|
)
|
|
|
|
//go:embed index.html
|
|
var indexHTML []byte
|
|
|
|
func main() {
|
|
if err := godotenv.Load(); err != nil {
|
|
log.Fatal("Failed to load environment variables")
|
|
}
|
|
|
|
dbURL := os.Getenv("DB_URL")
|
|
platform := os.Getenv("PLATFORM")
|
|
jwtSecret := os.Getenv("JWT_SECRET")
|
|
polkaKey := os.Getenv("POLKA_KEY")
|
|
|
|
if strings.TrimSpace(jwtSecret) == "" {
|
|
log.Fatal("Failed to retrieve JWT_SECRET")
|
|
}
|
|
|
|
if strings.TrimSpace(polkaKey) == "" {
|
|
log.Fatal("Failed to retrieve POLKA_KEY")
|
|
}
|
|
|
|
db, err := sql.Open("postgres", dbURL)
|
|
|
|
if err != nil {
|
|
log.Fatalf("Failed to connect to database: %v", err)
|
|
}
|
|
|
|
if err := db.Ping(); err != nil {
|
|
log.Fatalf("Failed to ping database: %v", err)
|
|
}
|
|
|
|
srv := server.New(database.New(db), platform, []byte(jwtSecret), polkaKey, indexHTML)
|
|
|
|
port := ":8080"
|
|
|
|
httpServer := http.Server{
|
|
Handler: srv.Handler(),
|
|
Addr: port,
|
|
}
|
|
|
|
go func() {
|
|
log.Printf("Server started and listening on %s\n", port)
|
|
|
|
if err := httpServer.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
|
|
log.Fatalf("HTTP Server error: %v", err)
|
|
}
|
|
|
|
log.Println("Stopped serving new connections")
|
|
}()
|
|
|
|
sigChan := make(chan os.Signal, 1)
|
|
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
|
<-sigChan
|
|
|
|
shutdownCtx, shutdownRelease := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer shutdownRelease()
|
|
|
|
if err := httpServer.Shutdown(shutdownCtx); err != nil {
|
|
log.Fatalf("HTTP shutdown error: %v", err)
|
|
}
|
|
|
|
log.Println("Graceful shutdown complete")
|
|
}
|