From 7523314ef8564e2c016168d4628f3ab11e27d7ba Mon Sep 17 00:00:00 2001
From: zeripath <art27@cantab.net>
Date: Sun, 24 Nov 2019 10:39:50 +0000
Subject: [PATCH] Graceful: Allow graceful restart for fcgi (#9112)

* Graceful: Allow graceful restart for fcgi

My previous interpretation was incorrect - we do not handle sockets
being passed in over stdin

* Update web.go
---
 cmd/web.go          | 17 +----------------
 cmd/web_graceful.go | 17 +++++++++++++++++
 2 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/cmd/web.go b/cmd/web.go
index e45e52be37..3c346ef87a 100644
--- a/cmd/web.go
+++ b/cmd/web.go
@@ -6,9 +6,7 @@ package cmd
 
 import (
 	"fmt"
-	"net"
 	"net/http"
-	"net/http/fcgi"
 	_ "net/http/pprof" // Used for debugging if enabled and a web server is running
 	"os"
 	"strings"
@@ -185,20 +183,7 @@ func runWeb(ctx *cli.Context) error {
 		err = runHTTPS("tcp", listenAddr, setting.CertFile, setting.KeyFile, context2.ClearHandler(m))
 	case setting.FCGI:
 		NoHTTPRedirector()
-		// FCGI listeners are provided as stdin - this is orthogonal to the LISTEN_FDS approach
-		// in graceful and systemD
-		NoMainListener()
-		var listener net.Listener
-		listener, err = net.Listen("tcp", listenAddr)
-		if err != nil {
-			log.Fatal("Failed to bind %s: %v", listenAddr, err)
-		}
-		defer func() {
-			if err := listener.Close(); err != nil {
-				log.Fatal("Failed to stop server: %v", err)
-			}
-		}()
-		err = fcgi.Serve(listener, context2.ClearHandler(m))
+		err = runFCGI(listenAddr, context2.ClearHandler(m))
 	case setting.UnixSocket:
 		NoHTTPRedirector()
 		err = runHTTP("unix", listenAddr, context2.ClearHandler(m))
diff --git a/cmd/web_graceful.go b/cmd/web_graceful.go
index 3907e843a2..e303f71510 100644
--- a/cmd/web_graceful.go
+++ b/cmd/web_graceful.go
@@ -6,9 +6,12 @@ package cmd
 
 import (
 	"crypto/tls"
+	"net"
 	"net/http"
+	"net/http/fcgi"
 
 	"code.gitea.io/gitea/modules/graceful"
+	"code.gitea.io/gitea/modules/log"
 )
 
 func runHTTP(network, listenAddr string, m http.Handler) error {
@@ -33,3 +36,17 @@ func NoHTTPRedirector() {
 func NoMainListener() {
 	graceful.Manager.InformCleanup()
 }
+
+func runFCGI(listenAddr string, m http.Handler) error {
+	// This needs to handle stdin as fcgi point
+	fcgiServer := graceful.NewServer("tcp", listenAddr)
+
+	err := fcgiServer.ListenAndServe(func(listener net.Listener) error {
+		return fcgi.Serve(listener, m)
+	})
+	if err != nil {
+		log.Fatal("Failed to start FCGI main server: %v", err)
+	}
+	log.Info("FCGI Listener: %s Closed", listenAddr)
+	return err
+}