]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
manager: api: fixed config request race condition, added Content-Type to responses
authorVasek Sraier <git@vakabus.cz>
Sun, 30 Oct 2022 12:32:56 +0000 (13:32 +0100)
committerVasek Sraier <git@vakabus.cz>
Sat, 3 Dec 2022 10:31:10 +0000 (11:31 +0100)
manager/knot_resolver_manager/server.py

index fd18a9832de496874136aa44e19eeb8d4baf538f..c9d3892cf53bc63d4a28bff5546c831c926ea12f 100644 (file)
@@ -171,20 +171,22 @@ class Server:
         # pylint: disable=too-many-locals
 
         # parse the incoming data
+        if request.method == "GET":
+            update_with: Optional[ParsedTree] = None
+        else:
+            update_with = parse(await request.text(), request.content_type)
         document_path = request.match_info["path"]
         getheaders = ignore_exceptions_optional(List[str], None, KeyError)(request.headers.getall)
         etags = getheaders("if-match")
         not_etags = getheaders("if-none-match")
         current_config: ParsedTree = self.config_store.get().get_unparsed_data()
-        if request.method == "GET":
-            update_with: Optional[ParsedTree] = None
-        else:
-            update_with = parse(await request.text(), request.content_type)
 
         # stop processing if etags
         def strip_quotes(s: str) -> str:
             return s.strip('"')
 
+        # WARNING: this check is prone to race conditions. When changing, make sure that the current config
+        # is really the latest current config (i.e. no await in between obtaining the config and the checks)
         status = HTTPStatus.NOT_MODIFIED if request.method in ("GET", "HEAD") else HTTPStatus.PRECONDITION_FAILED
         if etags is not None and current_config.etag not in map(strip_quotes, etags):
             return web.Response(status=status)
@@ -204,7 +206,7 @@ class Server:
 
         # return success
         resp_text: Optional[str] = str(to_return) if to_return is not None else None
-        res = web.Response(status=HTTPStatus.OK, text=resp_text)
+        res = web.Response(status=HTTPStatus.OK, text=resp_text, content_type="application/json")
         res.headers.add("ETag", f'"{new_config.etag}"')
         return res