From 1a5659943eba747b05efe564ac57a942b0424f91 Mon Sep 17 00:00:00 2001
From: zeripath <art27@cantab.net>
Date: Fri, 14 May 2021 13:26:03 +0100
Subject: [PATCH] Add timeout to writing to responses (#15831)

In #15826 it has become apparent that there are a few occasions when a response can
hang during writing, and because there is no timeout go will happily just block
interminably. This PR adds a fixed 5 second timeout to all writes to a connection.

Fix #15826

Signed-off-by: Andrew Thornton <art27@cantab.net>
---
 modules/graceful/server.go | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/modules/graceful/server.go b/modules/graceful/server.go
index c5021a9ba5..26195c6322 100644
--- a/modules/graceful/server.go
+++ b/modules/graceful/server.go
@@ -28,6 +28,9 @@ var (
 	DefaultMaxHeaderBytes int
 )
 
+// PerWriteWriteTimeout timeout for writes
+const PerWriteWriteTimeout = 5 * time.Second
+
 func init() {
 	DefaultMaxHeaderBytes = 0 // use http.DefaultMaxHeaderBytes - which currently is 1 << 20 (1MB)
 }
@@ -250,6 +253,13 @@ type wrappedConn struct {
 	closed *int32
 }
 
+func (w wrappedConn) Write(p []byte) (n int, err error) {
+	if PerWriteWriteTimeout > 0 {
+		_ = w.Conn.SetWriteDeadline(time.Now().Add(PerWriteWriteTimeout))
+	}
+	return w.Conn.Write(p)
+}
+
 func (w wrappedConn) Close() error {
 	if atomic.CompareAndSwapInt32(w.closed, 0, 1) {
 		defer func() {