mirror of
https://github.com/junegunn/fzf
synced 2026-06-09 10:03:17 +00:00
server: avoid O(n^2) body accumulation in HTTP listener
- handleHttpRequest used `body += text` per token, allocating a new backing array on every append (O(n^2) total copy work) - a single ~390 KB POST monopolised the single-threaded server for ~8 s, blocking all other --listen clients - switch to strings.Builder for amortised O(n) Reported with fix by Michal Majchrowicz and Marcin Wyczechowski (AFINE Team).
This commit is contained in:
+4
-3
@@ -153,7 +153,7 @@ func startHttpServer(address listenAddress, actionChannel chan []*action, getHan
|
||||
func (server *httpServer) handleHttpRequest(conn net.Conn) string {
|
||||
contentLength := 0
|
||||
apiKey := ""
|
||||
body := ""
|
||||
var bodyBuilder strings.Builder
|
||||
answer := func(code string, message string) string {
|
||||
message += "\n"
|
||||
return code + fmt.Sprintf("Content-Length: %d%s", len(message), crlf+crlf+message)
|
||||
@@ -175,7 +175,7 @@ func (server *httpServer) handleHttpRequest(conn net.Conn) string {
|
||||
token := data[:found+len(crlf)]
|
||||
return len(token), token, nil
|
||||
}
|
||||
if atEOF || len(body)+len(data) >= contentLength {
|
||||
if atEOF || bodyBuilder.Len()+len(data) >= contentLength {
|
||||
return 0, data, bufio.ErrFinalToken
|
||||
}
|
||||
return 0, nil, nil
|
||||
@@ -218,7 +218,7 @@ Loop:
|
||||
}
|
||||
}
|
||||
case 2: // Request body
|
||||
body += text
|
||||
bodyBuilder.WriteString(text)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,6 +234,7 @@ Loop:
|
||||
return answer(httpUnavailable+jsonContentType, `{"error":"timeout"}`)
|
||||
}
|
||||
|
||||
body := bodyBuilder.String()
|
||||
if len(body) < contentLength {
|
||||
return bad("incomplete request")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user