Skip to content

Commit 5b80432

Browse files
beniwohliColton Myers
andauthored
Use minimum of 5 seconds for interval between central config calls (#1652)
* Use minimum of 5 seconds for interval between central config calls Handling of negative values is not implemented, as this is not allowed per RFC: https://www.rfc-editor.org/rfc/rfc7234#section-5.2.2.8 closes #1645 * add test for negative values Co-authored-by: Colton Myers <colton@myers.fm>
1 parent 5447d49 commit 5b80432

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

‎elasticapm/transport/http.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,9 @@ def get_config(self, current_version=None, keys=None):
164164
logger.debug("HTTP error while fetching remote config: %s", str(e))
165165
return current_version, None, max_age
166166
body = response.read()
167-
if "Cache-Control" in response.headers:
168-
try:
169-
max_age = int(next(re.finditer(r"max-age=(\d+)", response.headers["Cache-Control"])).groups()[0])
170-
except StopIteration:
171-
logger.debug("Could not parse Cache-Control header: %s", response.headers["Cache-Control"])
167+
168+
max_age = self._get_cache_control_max_age(response.headers) or max_age
169+
172170
if response.status == 304:
173171
# config is unchanged, return
174172
logger.debug("Configuration unchanged")
@@ -187,6 +185,22 @@ def get_config(self, current_version=None, keys=None):
187185
logger.warning("Failed decoding APM Server response as JSON: %s", body)
188186
return current_version, None, max_age
189187

188+
def _get_cache_control_max_age(self, response_headers):
189+
max_age = None
190+
if "Cache-Control" in response_headers:
191+
try:
192+
cc_max_age = int(next(re.finditer(r"max-age=(\d+)", response_headers["Cache-Control"])).groups()[0])
193+
if cc_max_age <= 0:
194+
# max_age remains at default value
195+
pass
196+
elif cc_max_age < 5:
197+
max_age = 5
198+
else:
199+
max_age = cc_max_age
200+
except StopIteration:
201+
logger.debug("Could not parse Cache-Control header: %s", response_headers["Cache-Control"])
202+
return max_age
203+
190204
def _process_queue(self):
191205
if not self.client.server_version:
192206
self.fetch_server_info()

‎tests/transports/test_urllib3.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,39 @@ def test_get_config_bad_cache_control_header(waiting_httpserver, caplog, elastic
337337
assert record.message == "Could not parse Cache-Control header: max-age=fifty"
338338

339339

340+
def test_get_config_cache_control_zero(waiting_httpserver, caplog, elasticapm_client):
341+
waiting_httpserver.serve_content(
342+
code=200, content=b'{"x": "y"}', headers={"Cache-Control": "max-age=0", "Etag": "2"}
343+
)
344+
url = waiting_httpserver.url
345+
transport = Transport(url + "/" + constants.EVENTS_API_PATH, client=elasticapm_client)
346+
max_age = transport.get_config("1", {})[2]
347+
assert max_age == 300 # if max-age is 0, we use the default
348+
349+
350+
def test_get_config_cache_control_negative(waiting_httpserver, caplog, elasticapm_client):
351+
waiting_httpserver.serve_content(
352+
code=200, content=b'{"x": "y"}', headers={"Cache-Control": "max-age=-1", "Etag": "2"}
353+
)
354+
url = waiting_httpserver.url
355+
transport = Transport(url + "/" + constants.EVENTS_API_PATH, client=elasticapm_client)
356+
with caplog.at_level("DEBUG", "elasticapm.transport.http"):
357+
max_age = transport.get_config("1", {})[2]
358+
assert max_age == 300 # if max-age is negative, we use the default
359+
record = caplog.records[-1]
360+
assert record.message == "Could not parse Cache-Control header: max-age=-1"
361+
362+
363+
def test_get_config_cache_control_less_than_minimum(waiting_httpserver, caplog, elasticapm_client):
364+
waiting_httpserver.serve_content(
365+
code=200, content=b'{"x": "y"}', headers={"Cache-Control": "max-age=3", "Etag": "2"}
366+
)
367+
url = waiting_httpserver.url
368+
transport = Transport(url + "/" + constants.EVENTS_API_PATH, client=elasticapm_client)
369+
max_age = transport.get_config("1", {})[2]
370+
assert max_age == 5 # if max-age is less than 5, we use 5
371+
372+
340373
def test_get_config_empty_response(waiting_httpserver, caplog, elasticapm_client):
341374
waiting_httpserver.serve_content(code=200, content=b"", headers={"Cache-Control": "max-age=5"})
342375
url = waiting_httpserver.url

0 commit comments

Comments
 (0)
close