From bab1f3be1cde079066fa13ef4b77b1952771698b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Je=C5=BEek?= Date: Sun, 4 Dec 2022 11:48:09 +0100 Subject: [PATCH] Fix wrong encoder used with `application/openmetrics-text` accept header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Radek Ježek --- prometheus_client/asgi.py | 2 +- tests/test_asgi.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/prometheus_client/asgi.py b/prometheus_client/asgi.py index 6f72838b..e1864b8b 100644 --- a/prometheus_client/asgi.py +++ b/prometheus_client/asgi.py @@ -12,7 +12,7 @@ async def prometheus_app(scope, receive, send): assert scope.get("type") == "http" # Prepare parameters params = parse_qs(scope.get('query_string', b'')) - accept_header = "Accept: " + ",".join([ + accept_header = ",".join([ value.decode("utf8") for (name, value) in scope.get('headers') if name.decode("utf8").lower() == 'accept' ]) diff --git a/tests/test_asgi.py b/tests/test_asgi.py index 50d76d6d..78e24193 100644 --- a/tests/test_asgi.py +++ b/tests/test_asgi.py @@ -75,6 +75,19 @@ def get_all_output(self): break return outputs + def get_all_response_headers(self): + outputs = self.get_all_output() + response_start = next(o for o in outputs if o["type"] == "http.response.start") + return response_start["headers"] + + def get_response_header_value(self, header_name): + response_headers = self.get_all_response_headers() + return next( + value.decode("utf-8") + for name, value in response_headers + if name.decode("utf-8") == header_name + ) + def increment_metrics(self, metric_name, help_text, increments): c = Counter(metric_name, help_text, registry=self.registry) for _ in range(increments): @@ -158,3 +171,22 @@ def test_gzip_disabled(self): # Assert outputs are not compressed. outputs = self.get_all_output() self.assert_outputs(outputs, metric_name, help_text, increments, compressed=False) + + def test_openmetrics_encoding(self): + """Response content type is application/openmetrics-text when appropriate Accept header is in request""" + app = make_asgi_app(self.registry) + self.seed_app(app) + self.scope["headers"] = [(b"Accept", b"application/openmetrics-text")] + self.send_input({"type": "http.request", "body": b""}) + + content_type = self.get_response_header_value('Content-Type').split(";")[0] + assert content_type == "application/openmetrics-text" + + def test_plaintext_encoding(self): + """Response content type is text/plain when Accept header is missing in request""" + app = make_asgi_app(self.registry) + self.seed_app(app) + self.send_input({"type": "http.request", "body": b""}) + + content_type = self.get_response_header_value('Content-Type').split(";")[0] + assert content_type == "text/plain"