11package gohpts
22
33import (
4+ "context"
45 "crypto/tls"
56 "fmt"
67 "io"
78 "log"
89 "net"
910 "net/http"
1011 "os"
12+ "os/signal"
1113 "slices"
1214 "strings"
1315 "sync"
@@ -174,7 +176,7 @@ func (p *proxyApp) handleForward(w http.ResponseWriter, r *http.Request) {
174176 }
175177 }
176178 defer resp .Body .Close ()
177- done := make (chan struct {} )
179+ done := make (chan bool )
178180 if chunked {
179181 rc := http .NewResponseController (w )
180182 go func () {
@@ -217,7 +219,6 @@ func (p *proxyApp) handleForward(w http.ResponseWriter, r *http.Request) {
217219 n , err := io .Copy (w , resp .Body )
218220 if err != nil {
219221 p .logger .Error ().Err (err ).Msgf ("Error during Copy() %s: %s" , r .URL .String (), err )
220- done <- struct {}{}
221222 close (done )
222223 return
223224 }
@@ -240,7 +241,6 @@ func (p *proxyApp) handleForward(w http.ResponseWriter, r *http.Request) {
240241 w .Header ().Add (key , v )
241242 }
242243 }
243- done <- struct {}{}
244244 close (done )
245245}
246246
@@ -318,16 +318,33 @@ func (p *proxyApp) handler() http.HandlerFunc {
318318}
319319
320320func (p * proxyApp ) Run () {
321+ done := make (chan bool )
322+ quit := make (chan os.Signal , 1 )
323+ signal .Notify (quit , os .Interrupt )
324+ go func () {
325+ <- quit
326+ p .logger .Info ().Msg ("Server is shutting down..." )
327+ ctx , cancel := context .WithTimeout (context .Background (), 30 * time .Second )
328+
329+ defer cancel ()
330+ p .httpServer .SetKeepAlivesEnabled (false )
331+ if err := p .httpServer .Shutdown (ctx ); err != nil {
332+ p .logger .Fatal ().Err (err ).Msg ("Could not gracefully shutdown the server" )
333+ }
334+ close (done )
335+ }()
321336 p .httpServer .Handler = p .handler ()
322337 if p .certFile != "" && p .keyFile != "" {
323- if err := p .httpServer .ListenAndServeTLS (p .certFile , p .keyFile ); err != nil {
338+ if err := p .httpServer .ListenAndServeTLS (p .certFile , p .keyFile ); err != nil && err != http . ErrServerClosed {
324339 p .logger .Fatal ().Err (err ).Msg ("Unable to start HTTPS server" )
325340 }
326341 } else {
327- if err := p .httpServer .ListenAndServe (); err != nil {
342+ if err := p .httpServer .ListenAndServe (); err != nil && err != http . ErrServerClosed {
328343 p .logger .Fatal ().Err (err ).Msg ("Unable to start HTTP server" )
329344 }
330345 }
346+ <- done
347+ p .logger .Info ().Msg ("Server stopped" )
331348}
332349
333350type Config struct {
0 commit comments