Fix x-api-key header not required for GET requests
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Generate Sponsors README / deploy (push) Has been cancelled

Fix #4627
This commit is contained in:
Junegunn Choi
2026-01-17 15:13:11 +09:00
parent d1f037059a
commit aad805d0d3
2 changed files with 32 additions and 15 deletions

View File

@@ -183,23 +183,22 @@ func (server *httpServer) handleHttpRequest(conn net.Conn) string {
}) })
section := 0 section := 0
var getMatch []string
Loop:
for scanner.Scan() { for scanner.Scan() {
text := scanner.Text() text := scanner.Text()
switch section { switch section {
case 0: case 0: // Request line
getMatch := getRegex.FindStringSubmatch(text) getMatch = getRegex.FindStringSubmatch(text)
if len(getMatch) > 0 { if len(getMatch) == 0 && !strings.HasPrefix(text, "POST / HTTP") {
response := server.getHandler(parseGetParams(getMatch[1]))
if len(response) > 0 {
return good(response)
}
return answer(httpUnavailable+jsonContentType, `{"error":"timeout"}`)
} else if !strings.HasPrefix(text, "POST / HTTP") {
return bad("invalid request method") return bad("invalid request method")
} }
section++ section++
case 1: case 1: // Request headers
if text == crlf { if text == crlf { // End of headers
if len(getMatch) > 0 {
break Loop
}
if contentLength == 0 { if contentLength == 0 {
return bad("content-length header missing") return bad("content-length header missing")
} }
@@ -219,7 +218,7 @@ func (server *httpServer) handleHttpRequest(conn net.Conn) string {
apiKey = strings.TrimSpace(pair[1]) apiKey = strings.TrimSpace(pair[1])
} }
} }
case 2: case 2: // Request body
body += text body += text
} }
} }
@@ -228,6 +227,14 @@ func (server *httpServer) handleHttpRequest(conn net.Conn) string {
return unauthorized("invalid api key") return unauthorized("invalid api key")
} }
if len(getMatch) > 0 {
response := server.getHandler(parseGetParams(getMatch[1]))
if len(response) > 0 {
return good(response)
}
return answer(httpUnavailable+jsonContentType, `{"error":"timeout"}`)
}
if len(body) < contentLength { if len(body) < contentLength {
return bad("incomplete request") return bad("incomplete request")
} }

View File

@@ -31,22 +31,32 @@ class TestServer < TestInteractive
end end
def test_listen_with_api_key def test_listen_with_api_key
post_uri = URI('http://localhost:6266') uri = URI('http://localhost:6266')
tmux.send_keys 'seq 10 | FZF_API_KEY=123abc fzf --listen 6266', :Enter tmux.send_keys 'seq 10 | FZF_API_KEY=123abc fzf --listen 6266', :Enter
tmux.until { |lines| assert_equal 10, lines.match_count } tmux.until { |lines| assert_equal 10, lines.match_count }
# Incorrect API Key # Incorrect API Key
[nil, { 'x-api-key' => '' }, { 'x-api-key' => '124abc' }].each do |headers| [nil, { 'x-api-key' => '' }, { 'x-api-key' => '124abc' }].each do |headers|
res = Net::HTTP.post(post_uri, 'change-query(yo)+reload(seq 100)+change-prompt:hundred> ', headers) res = Net::HTTP.post(uri, 'change-query(yo)+reload(seq 100)+change-prompt:hundred> ', headers)
assert_equal '401', res.code
assert_equal 'Unauthorized', res.message
assert_equal "invalid api key\n", res.body
res = Net::HTTP.get_response(uri, headers)
assert_equal '401', res.code assert_equal '401', res.code
assert_equal 'Unauthorized', res.message assert_equal 'Unauthorized', res.message
assert_equal "invalid api key\n", res.body assert_equal "invalid api key\n", res.body
end end
# Valid API Key # Valid API Key
[{ 'x-api-key' => '123abc' }, { 'X-API-Key' => '123abc' }].each do |headers| [{ 'x-api-key' => '123abc' }, { 'X-API-Key' => '123abc' }].each do |headers|
res = Net::HTTP.post(post_uri, 'change-query(yo)+reload(seq 100)+change-prompt:hundred> ', headers) res = Net::HTTP.post(uri, 'change-query(yo)+reload(seq 100)+change-prompt:hundred> ', headers)
assert_equal '200', res.code assert_equal '200', res.code
tmux.until { |lines| assert_equal 100, lines.item_count } tmux.until { |lines| assert_equal 100, lines.item_count }
tmux.until { |lines| assert_equal 'hundred> yo', lines[-1] } tmux.until { |lines| assert_equal 'hundred> yo', lines[-1] }
res = Net::HTTP.get_response(uri, headers)
assert_equal '200', res.code
assert_equal 'yo', JSON.parse(res.body, symbolize_names: true)[:query]
end end
end end
end end