From 38ad4ef49329cd0c10e506452ab11b7a21e04bae Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 19 Jan 2024 13:17:28 +0300 Subject: [PATCH 1/2] Fix timeout for prometheus exporter for HTTP/1.1 (due to keep-alive) Before: $ time curl -s --http1.1 127.1:9363/metrics > /dev/null real 0m10.018s # default keep_alive_timeout is 10 seconds user 0m0.005s sys 0m0.001s After $ time curl -s --http1.1 127.1:9363/metrics > /dev/null real 0m0.008s user 0m0.006s sys 0m0.000s And if you will look at the test_prometheus_endpoint, you will see that it takes > 30 seconds (it obtains metrics 3 times), after this patch it should be finished more or less instantly. Signed-off-by: Azat Khuzhin --- src/Server/PrometheusRequestHandler.cpp | 4 ++++ tests/integration/test_prometheus_endpoint/test.py | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/Server/PrometheusRequestHandler.cpp b/src/Server/PrometheusRequestHandler.cpp index 12caad5eea1..8690ec9121e 100644 --- a/src/Server/PrometheusRequestHandler.cpp +++ b/src/Server/PrometheusRequestHandler.cpp @@ -23,6 +23,10 @@ void PrometheusRequestHandler::handleRequest(HTTPServerRequest & request, HTTPSe const auto & config = server.config(); unsigned keep_alive_timeout = config.getUInt("keep_alive_timeout", DEFAULT_HTTP_KEEP_ALIVE_TIMEOUT); + /// In order to make keep-alive works. + if (request.getVersion() == HTTPServerRequest::HTTP_1_1) + response.setChunkedTransferEncoding(true); + setResponseDefaultHeaders(response, keep_alive_timeout); response.setContentType("text/plain; version=0.0.4; charset=UTF-8"); diff --git a/tests/integration/test_prometheus_endpoint/test.py b/tests/integration/test_prometheus_endpoint/test.py index 4eedc84b6c4..f140ebdfbe7 100644 --- a/tests/integration/test_prometheus_endpoint/test.py +++ b/tests/integration/test_prometheus_endpoint/test.py @@ -40,6 +40,8 @@ def get_and_check_metrics(retries): response = requests.get( "http://{host}:{port}/metrics".format(host=node.ip_address, port=8001), allow_redirects=False, + # less then default keep-alive timeout (10 seconds) + timeout=5, ) if response.status_code != 200: From d940afd6cdaad3fbcf50581491717b0559702221 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 19 Jan 2024 14:42:52 +0300 Subject: [PATCH 2/2] Fix timeouts for HTTP/1.1 non-chunked requests (missing Connection: close) Signed-off-by: Azat Khuzhin --- src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp b/src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp index 8072c09fe27..8098671a903 100644 --- a/src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp +++ b/src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp @@ -19,6 +19,13 @@ void WriteBufferFromHTTPServerResponse::startSendHeaders() if (response.getChunkedTransferEncoding()) setChunked(); + else if (response.getContentLength() == Poco::Net::HTTPMessage::UNKNOWN_CONTENT_LENGTH) + { + /// In case there is no Content-Length we cannot use keep-alive, + /// since there is no way to know when the server send all the + /// data, so "Connection: close" should be sent. + response.setKeepAlive(false); + } if (add_cors_header) response.set("Access-Control-Allow-Origin", "*");