From 7484292e63f0dabca4cccdca136f6a6d105b3b79 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Sun, 21 Jan 2024 22:58:18 +0900 Subject: Avoid deadlocks by adding a 2 second timeout to GET / endpoint Because fzf processes HTTP GET requests in the main event loop, accessing the endpoint from within execute/transform actions would result in a deadlock and hang fzf indefinitely. This commit sets a 2 second timeout to avoid the deadlock. --- src/server.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server.go b/src/server.go index e655896f..d5a148df 100644 --- a/src/server.go +++ b/src/server.go @@ -30,7 +30,9 @@ const ( httpOk = "HTTP/1.1 200 OK" + crlf httpBadRequest = "HTTP/1.1 400 Bad Request" + crlf httpUnauthorized = "HTTP/1.1 401 Unauthorized" + crlf + httpUnavailable = "HTTP/1.1 503 Service Unavailable" + crlf httpReadTimeout = 10 * time.Second + jsonContentType = "Content-Type: application/json" + crlf maxContentLength = 1024 * 1024 ) @@ -141,7 +143,7 @@ func (server *httpServer) handleHttpRequest(conn net.Conn) string { return answer(httpBadRequest, message) } good := func(message string) string { - return answer(httpOk+"Content-Type: application/json"+crlf, message) + return answer(httpOk+jsonContentType, message) } conn.SetReadDeadline(time.Now().Add(httpReadTimeout)) scanner := bufio.NewScanner(conn) @@ -165,8 +167,16 @@ func (server *httpServer) handleHttpRequest(conn net.Conn) string { getMatch := getRegex.FindStringSubmatch(text) if len(getMatch) > 0 { server.actionChannel <- []*action{{t: actResponse, a: getMatch[1]}} - response := <-server.responseChannel - return good(response) + select { + case response := <-server.responseChannel: + return good(response) + case <-time.After(2 * time.Second): + go func() { + // Drain the channel + <-server.responseChannel + }() + return answer(httpUnavailable+jsonContentType, `{"error":"timeout"}`) + } } else if !strings.HasPrefix(text, "POST / HTTP") { return bad("invalid request method") } -- cgit v1.2.3