From 8b54d7ccd5ebe7aa8922d33917006288e5f49083 Mon Sep 17 00:00:00 2001 From: Jennifer Taylor Date: Sat, 8 May 2021 01:49:42 +0000 Subject: [PATCH] Fix parsing of API client content-type string. --- bemani/data/api/client.py | 19 ++++++++++++++++++- bemani/tests/test_APIClient.py | 21 +++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 bemani/tests/test_APIClient.py diff --git a/bemani/data/api/client.py b/bemani/data/api/client.py index 22687e5..2fe4286 100644 --- a/bemani/data/api/client.py +++ b/bemani/data/api/client.py @@ -42,6 +42,22 @@ class APIClient: self.allow_stats = allow_stats self.allow_scores = allow_scores + def __content_type_valid(self, content_type: str) -> bool: + if ';' in content_type: + left, right = content_type.split(';', 1) + left = left.strip().lower() + right = right.strip().lower() + + if left == 'application/json' and ('=' in right): + identifier, charset = right.split('=', 1) + identifier = identifier.strip() + charset = charset.strip() + + if identifier == 'charset' and charset == 'utf-8': + # This is valid. + return True + return False + def __exchange_data(self, request_uri: str, request_args: Dict[str, Any]) -> Dict[str, Any]: if self.base_uri[-1:] != '/': uri = f'{self.base_uri}/{request_uri}' @@ -66,7 +82,8 @@ class APIClient: except Exception: raise APIException('Failed to query remote server!') - if r.headers['content-type'] != 'application/json; charset=utf-8': + # Verify that content type is in the form of "application/json; charset=utf-8". + if not self.__content_type_valid(r.headers['content-type']): raise APIException(f'API returned invalid content type \'{r.headers["content-type"]}\'!') jsondata = r.json() diff --git a/bemani/tests/test_APIClient.py b/bemani/tests/test_APIClient.py new file mode 100644 index 0000000..ab88293 --- /dev/null +++ b/bemani/tests/test_APIClient.py @@ -0,0 +1,21 @@ +# vim: set fileencoding=utf-8 +import unittest + +from bemani.data.api.client import APIClient + + +class TestAPIClient(unittest.TestCase): + + def test_content_type(self) -> None: + client = APIClient('https://127.0.0.1', 'token', False, False) + self.assertFalse(client._APIClient__content_type_valid('application/text')) + self.assertFalse(client._APIClient__content_type_valid('application/json')) + self.assertFalse(client._APIClient__content_type_valid('application/json; charset=shift-jis')) + self.assertTrue(client._APIClient__content_type_valid('application/json; charset=utf-8')) + self.assertTrue(client._APIClient__content_type_valid('application/json;charset=utf-8')) + self.assertTrue(client._APIClient__content_type_valid('application/json;charset = utf-8')) + self.assertTrue(client._APIClient__content_type_valid('application/json; charset = utf-8')) + self.assertTrue(client._APIClient__content_type_valid('application/json; charset=UTF-8')) + self.assertTrue(client._APIClient__content_type_valid('application/json;charset=UTF-8')) + self.assertTrue(client._APIClient__content_type_valid('application/json;charset = UTF-8')) + self.assertTrue(client._APIClient__content_type_valid('application/json; charset = UTF-8'))