Configure HTTP server timeouts and graceful shutdown

This commit is contained in:
2026-08-29 00:45:27 +02:00
parent b81d74220e
commit b774e23ac0
+34 -1
View File
@@ -1,6 +1,7 @@
package main
import (
"context"
"crypto/rand"
"encoding/json"
"errors"
@@ -12,8 +13,10 @@ import (
"mime"
"net/http"
"os"
"os/signal"
"path/filepath"
"strings"
"syscall"
"time"
)
@@ -60,8 +63,38 @@ func main() {
log.Print("Cleaning old files is disabled")
}
if err := http.ListenAndServe(":"+port, nil); err != nil {
// Note: ReadTimeout/WriteTimeout are intentionally not set since they
// would cap the total duration of large file uploads/downloads.
// ReadHeaderTimeout and IdleTimeout still protect against slow-loris
// style attacks on connection/header handling.
srv := &http.Server{
Addr: ":" + port,
ReadHeaderTimeout: 10 * time.Second,
IdleTimeout: 120 * time.Second,
}
serverErr := make(chan error, 1)
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
serverErr <- err
}
close(serverErr)
}()
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
select {
case err := <-serverErr:
log.Fatalf("Server failed: %v", err)
case <-ctx.Done():
log.Print("Shutdown signal received, shutting down gracefully...")
shutdownCtx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
if err := srv.Shutdown(shutdownCtx); err != nil {
log.Fatalf("Graceful shutdown failed: %v", err)
}
log.Print("Server stopped")
}
}