Files
learn-file-storage-s3-golan…/main.go
2025-03-15 23:35:24 +02:00

144 lines
3.5 KiB
Go

package main
import (
"context"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
"log"
"net/http"
"os"
"github.com/bootdotdev/learn-file-storage-s3-golang-starter/internal/database"
"github.com/joho/godotenv"
_ "github.com/lib/pq"
)
type apiConfig struct {
db database.Client
jwtSecret string
platform string
filepathRoot string
assetsRoot string
s3Client *s3.Client
s3Bucket string
s3Region string
s3CfDistribution string
port string
}
type thumbnail struct {
data []byte
mediaType string
}
func main() {
godotenv.Load(".env")
pathToDB := os.Getenv("DB_PATH")
if pathToDB == "" {
log.Fatal("DB_URL must be set")
}
db, err := database.NewClient(pathToDB)
if err != nil {
log.Fatalf("Couldn't connect to database: %v", err)
}
jwtSecret := os.Getenv("JWT_SECRET")
if jwtSecret == "" {
log.Fatal("JWT_SECRET environment variable is not set")
}
platform := os.Getenv("PLATFORM")
if platform == "" {
log.Fatal("PLATFORM environment variable is not set")
}
filepathRoot := os.Getenv("FILEPATH_ROOT")
if filepathRoot == "" {
log.Fatal("FILEPATH_ROOT environment variable is not set")
}
assetsRoot := os.Getenv("ASSETS_ROOT")
if assetsRoot == "" {
log.Fatal("ASSETS_ROOT environment variable is not set")
}
s3Bucket := os.Getenv("S3_BUCKET")
if s3Bucket == "" {
log.Fatal("S3_BUCKET environment variable is not set")
}
s3Region := os.Getenv("S3_REGION")
if s3Region == "" {
log.Fatal("S3_REGION environment variable is not set")
}
s3CfDistribution := os.Getenv("S3_CF_DISTRO")
if s3CfDistribution == "" {
log.Fatal("S3_CF_DISTRO environment variable is not set")
}
port := os.Getenv("PORT")
if port == "" {
log.Fatal("PORT environment variable is not set")
}
cfg := apiConfig{
db: db,
jwtSecret: jwtSecret,
platform: platform,
filepathRoot: filepathRoot,
assetsRoot: assetsRoot,
s3Bucket: s3Bucket,
s3Region: s3Region,
s3CfDistribution: s3CfDistribution,
port: port,
}
err = cfg.ensureAssetsDir()
if err != nil {
log.Fatalf("Couldn't create assets directory: %v", err)
}
awsCfg, err := config.LoadDefaultConfig(context.Background(), config.WithRegion(cfg.s3Region))
if err != nil {
log.Fatal(err)
}
client := s3.NewFromConfig(awsCfg)
cfg.s3Client = client
mux := http.NewServeMux()
appHandler := http.StripPrefix("/app", http.FileServer(http.Dir(filepathRoot)))
mux.Handle("/app/", appHandler)
assetsHandler := http.StripPrefix("/assets", http.FileServer(http.Dir(assetsRoot)))
mux.Handle("/assets/", cacheMiddleware(assetsHandler))
mux.HandleFunc("POST /api/login", cfg.handlerLogin)
mux.HandleFunc("POST /api/refresh", cfg.handlerRefresh)
mux.HandleFunc("POST /api/revoke", cfg.handlerRevoke)
mux.HandleFunc("POST /api/users", cfg.handlerUsersCreate)
mux.HandleFunc("POST /api/videos", cfg.handlerVideoMetaCreate)
mux.HandleFunc("POST /api/thumbnail_upload/{videoID}", cfg.handlerUploadThumbnail)
mux.HandleFunc("POST /api/video_upload/{videoID}", cfg.handlerUploadVideo)
mux.HandleFunc("GET /api/videos", cfg.handlerVideosRetrieve)
mux.HandleFunc("GET /api/videos/{videoID}", cfg.handlerVideoGet)
mux.HandleFunc("DELETE /api/videos/{videoID}", cfg.handlerVideoMetaDelete)
mux.HandleFunc("POST /admin/reset", cfg.handlerReset)
srv := &http.Server{
Addr: ":" + port,
Handler: mux,
}
log.Printf("Serving on: http://localhost:%s/app/\n", port)
log.Fatal(srv.ListenAndServe())
}