From 27634d016b6d6030a4dd14e94a120527a4db3ece Mon Sep 17 00:00:00 2001 From: guochao Date: Sat, 22 Feb 2025 23:27:41 +0800 Subject: [PATCH] reset tcp connection if error happens --- server.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/server.go b/server.go index 65218c7..bb5e249 100644 --- a/server.go +++ b/server.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "log/slog" + "net" "net/http" "os" "path/filepath" @@ -332,7 +333,30 @@ func (server *Server) streamOnline(w http.ResponseWriter, r *http.Request, mtime } if err != nil { - slog.With("error", err, "upstreamIdx", selectedIdx).Error("something happened during download. will not cache this response") + logger := slog.With("upstreamIdx", selectedIdx) + logger.Error("something happened during download. will not cache this response. setting lingering to reset the connection.") + hijacker, ok := w.(http.Hijacker) + if !ok { + logger.Warn("response writer is not a hijacker. failed to set lingering") + return + } + conn, _, err := hijacker.Hijack() + if err != nil { + logger.With("error", err).Warn("hijack failed. failed to set lingering") + return + } + defer conn.Close() + + tcpConn, ok := conn.(*net.TCPConn) + if !ok { + logger.With("error", err).Warn("connection is not a *net.TCPConn. failed to set lingering") + return + } + if err := tcpConn.SetLinger(0); err != nil { + logger.With("error", err).Warn("failed to set lingering") + return + } + logger.Debug("connection set to linger. it will be reset once the conn.Close is called") } go func() { defer func() {