Skip to content

Commit 090ddbd

Browse files
Base64-encode "." and ".." in Pushgateway URL path segments (#1251)
A job or grouping key value of "." or ".." was put into the URL path as is. These are dot segments: the Pushgateway router cleans the path and answers with a 307 redirect to a different group (".." points at the parent), so push_to_gateway, pushadd_to_gateway and delete_from_gateway fail with "HTTP Error 307". Encode such values with base64, as client_golang does. Signed-off-by: sarankumar1325 <120080287+sarankumar1325@users.noreply.github.com>
1 parent c3c6ed6 commit 090ddbd

2 files changed

Lines changed: 15 additions & 2 deletions

File tree

‎prometheus_client/exposition.py‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -822,9 +822,11 @@ def _escape_grouping_key(k, v):
822822
if v == "":
823823
# Per https://github.com/prometheus/pushgateway/pull/346.
824824
return k + "@base64", "="
825-
elif '/' in v or ' ' in v:
825+
elif '/' in v or ' ' in v or v in ('.', '..'):
826826
# Added in Pushgateway 0.9.0.
827-
# Use base64 encoding for values containing slashes or spaces
827+
# Use base64 encoding for values containing slashes or spaces, and
828+
# for "." and "..", which would otherwise be removed from the URL
829+
# path as dot segments (the Pushgateway answers with a redirect).
828830
return k + "@base64", base64.urlsafe_b64encode(v.encode("utf-8")).decode("utf-8")
829831
else:
830832
return k, quote_plus(v)

‎tests/test_exposition.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,17 @@ def test_push_with_complex_groupingkey(self):
317317
self.assertEqual(self.requests[0][0].headers.get('content-type'), CONTENT_TYPE_PLAIN_0_0_4)
318318
self.assertEqual(self.requests[0][1], b'# HELP g help\n# TYPE g gauge\ng 0.0\n')
319319

320+
def test_push_with_groupingkey_dot_segments(self):
321+
push_to_gateway(self.address, "my_job", self.registry, {'a': '.', 'b': '..'})
322+
self.assertEqual(self.requests[0][0].command, 'PUT')
323+
self.assertEqual(self.requests[0][0].path, '/metrics/job/my_job/a@base64/Lg==/b@base64/Li4=')
324+
self.assertEqual(self.requests[0][1], b'# HELP g help\n# TYPE g gauge\ng 0.0\n')
325+
326+
def test_push_with_dot_segment_job(self):
327+
push_to_gateway(self.address, "..", self.registry)
328+
self.assertEqual(self.requests[0][0].command, 'PUT')
329+
self.assertEqual(self.requests[0][0].path, '/metrics/job@base64/Li4=')
330+
320331
def test_push_with_complex_job(self):
321332
push_to_gateway(self.address, "my/job", self.registry)
322333
self.assertEqual(self.requests[0][0].command, 'PUT')

0 commit comments

Comments
 (0)