package main import ( "context" "fmt" "log" "net/http" "os" "time" "atp.pics/internal/fetch" "atp.pics/internal/handler" "atp.pics/internal/resolve" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" ) type responseRecorder struct { http.ResponseWriter status int } func (r *responseRecorder) WriteHeader(status int) { r.status = status r.ResponseWriter.WriteHeader(status) } func logMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() rec := &responseRecorder{ResponseWriter: w, status: http.StatusOK} next.ServeHTTP(rec, r) log.Printf("%s %s %d %dms", r.Method, r.URL.Path, rec.status, time.Since(start).Milliseconds()) }) } func main() { bucket := requireEnv("BUCKET_NAME") publicHost := envOr("BUCKET_PUBLIC_HOST", "") addr := envOr("LISTEN_ADDR", ":8080") ctx := context.Background() cfg, err := config.LoadDefaultConfig(ctx) if err != nil { log.Fatalf("loading AWS config: %v", err) } s3Client := s3.NewFromConfig(cfg) store := fetch.New(s3Client, bucket, publicHost) resolver := resolve.New() mux := http.NewServeMux() handler.New(resolver, store).Register(mux) log.Printf("atp.pics listening on %s", addr) if err := http.ListenAndServe(addr, logMiddleware(mux)); err != nil { log.Fatalf("server error: %v", err) } } func requireEnv(key string) string { v := os.Getenv(key) if v == "" { fmt.Fprintf(os.Stderr, "required environment variable %s is not set\n", key) os.Exit(1) } return v } func envOr(key, fallback string) string { if v := os.Getenv(key); v != "" { return v } return fallback }