Skip to content

Commit 278e83f

Browse files
committed
fix
1 parent 84e09fe commit 278e83f

File tree

4 files changed

+67
-33
lines changed

4 files changed

+67
-33
lines changed

api_app/analyzers_manager/classes.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,16 @@ class DockerBasedAnalyzer(BaseAnalyzerMixin, metaclass=ABCMeta):
278278
poll_distance: int
279279
key_not_found_max_retries: int = 10
280280

281+
@staticmethod
282+
def __get_response_json(resp: requests.Response) -> dict:
283+
try:
284+
data = resp.json()
285+
except ValueError:
286+
return {}
287+
if isinstance(data, dict):
288+
return data
289+
return {}
290+
281291
@staticmethod
282292
def __raise_in_case_bad_request(name, resp, params_to_check=None) -> bool:
283293
"""
@@ -289,14 +299,15 @@ def __raise_in_case_bad_request(name, resp, params_to_check=None) -> bool:
289299
# different error messages for different cases
290300
if resp.status_code == 404:
291301
raise AnalyzerConfigurationException(f"{name} docker container is not running.")
302+
resp_json = DockerBasedAnalyzer.__get_response_json(resp)
292303
if resp.status_code == 400:
293-
err = resp.json().get("error", "")
304+
err = resp_json.get("error") or resp.text or "Bad Request"
294305
raise AnalyzerRunException(err)
295306
if resp.status_code == 500:
296307
raise AnalyzerRunException(f"Internal Server Error in {name} docker container")
297308
# check to make sure there was a valid params in response
298309
for param in params_to_check:
299-
param_value = resp.json().get(param, None)
310+
param_value = resp_json.get(param, None)
300311
if not param_value:
301312
raise AnalyzerRunException(
302313
f"Unexpected Error. Please check log files under /var/log/intel_owl/{name.lower()}/"
@@ -310,12 +321,12 @@ def __raise_in_case_bad_request(name, resp, params_to_check=None) -> bool:
310321
def __query_for_result(url: str, key: str) -> Tuple[int, dict]:
311322
headers = {"Accept": "application/json"}
312323
resp = requests.get(f"{url}?key={key}", headers=headers)
313-
return resp.status_code, resp.json()
324+
return resp.status_code, DockerBasedAnalyzer.__get_response_json(resp)
314325

315326
def __polling(self, req_key: str, chance: int, re_poll_try: int = 0):
316327
try:
317328
status_code, json_data = self.__query_for_result(self.url, req_key)
318-
except (requests.RequestException, json.JSONDecodeError) as e:
329+
except (requests.RequestException, ValueError) as e:
319330
raise AnalyzerRunException(e)
320331
if status_code == 404:
321332
# This happens when they key does not exist.
@@ -398,17 +409,19 @@ def _docker_run(
398409
except requests.exceptions.ConnectionError:
399410
self._raise_container_not_running()
400411

412+
resp1_json = DockerBasedAnalyzer.__get_response_json(resp1)
413+
401414
# step #2: raise AnalyzerRunException in case of error
402415
# Modified to support synchronous analyzers that return results directly in the initial response, avoiding unnecessary polling.
403416
if avoid_polling:
404-
report = resp1.json().get("report", None)
405-
err = resp1.json().get("error", None)
417+
report = resp1_json.get("report", None)
418+
err = resp1_json.get("error", None)
406419
else:
407420
if not self.__raise_in_case_bad_request(self.name, resp1):
408421
raise AssertionError
409422

410423
# step #3: if no error, continue and try to fetch result
411-
key = resp1.json().get("key")
424+
key = resp1_json.get("key")
412425
final_resp = self.__poll_for_result(key)
413426
err = final_resp.get("error", None)
414427
report = final_resp.get("report", None)

api_app/helpers.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,16 @@ def get_default_requests_timeout() -> tuple[float, float]:
108108
def patch_requests_default_timeout() -> None:
109109
import requests
110110

111-
session_request = requests.sessions.Session.request
112-
if getattr(session_request, "_intelowl_default_timeout_patched", False):
111+
api_request = requests.api.request
112+
if getattr(api_request, "_intelowl_default_timeout_patched", False):
113113
return
114114

115-
@wraps(session_request)
116-
def request(self, method, url, **kwargs):
115+
@wraps(api_request)
116+
def wrapped(method, url, **kwargs):
117117
if "timeout" not in kwargs or kwargs["timeout"] is None:
118118
kwargs["timeout"] = get_default_requests_timeout()
119-
return request._intelowl_original(self, method, url, **kwargs)
119+
return wrapped._intelowl_original(method, url, **kwargs)
120120

121-
request._intelowl_default_timeout_patched = True
122-
request._intelowl_original = session_request
123-
requests.sessions.Session.request = request
121+
wrapped._intelowl_default_timeout_patched = True
122+
wrapped._intelowl_original = api_request
123+
requests.api.request = wrapped
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# This file is a part of IntelOwl https://github.com/intelowlproject/IntelOwl
2+
# See the file 'LICENSE' for copying permission.
3+
4+
from django.test import SimpleTestCase
5+
from requests import Response
6+
7+
from api_app.analyzers_manager.classes import DockerBasedAnalyzer
8+
from api_app.analyzers_manager.exceptions import AnalyzerRunException
9+
10+
11+
class DockerBasedAnalyzerHttpErrorsTests(SimpleTestCase):
12+
def test_bad_request_with_non_json_body_raises_analyzer_run_exception(self):
13+
resp = Response()
14+
resp.status_code = 400
15+
resp._content = b""
16+
17+
with self.assertRaises(AnalyzerRunException):
18+
DockerBasedAnalyzer._DockerBasedAnalyzer__raise_in_case_bad_request(
19+
"StringsInfo",
20+
resp,
21+
)

tests/api_app/test_requests_timeout.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,38 @@ def setUp(self):
1414
patch_requests_default_timeout()
1515

1616
def test_injects_default_timeout_when_missing(self):
17-
session_request = requests.sessions.Session.request
18-
original = session_request._intelowl_original
17+
api_request = requests.api.request
18+
original = api_request._intelowl_original
1919
captured = {}
2020

21-
def stub(self, method, url, **kwargs):
21+
def stub(method, url, **kwargs):
2222
captured["timeout"] = kwargs.get("timeout")
2323
return "ok"
2424

25-
session_request._intelowl_original = stub
25+
api_request._intelowl_original = stub
2626
try:
27-
result = requests.Session().request("GET", "http://example.com")
27+
result = requests.get("http://example.com")
2828
self.assertEqual(result, "ok")
2929
self.assertEqual(captured["timeout"], get_default_requests_timeout())
3030
finally:
31-
session_request._intelowl_original = original
31+
api_request._intelowl_original = original
3232

3333
def test_keeps_explicit_timeout(self):
34-
session_request = requests.sessions.Session.request
35-
original = session_request._intelowl_original
34+
api_request = requests.api.request
35+
original = api_request._intelowl_original
3636
captured = {}
3737

38-
def stub(self, method, url, **kwargs):
38+
def stub(method, url, **kwargs):
3939
captured["timeout"] = kwargs.get("timeout")
4040
return "ok"
4141

42-
session_request._intelowl_original = stub
42+
api_request._intelowl_original = stub
4343
try:
44-
result = requests.Session().request("GET", "http://example.com", timeout=5)
44+
result = requests.get("http://example.com", timeout=5)
4545
self.assertEqual(result, "ok")
4646
self.assertEqual(captured["timeout"], 5)
4747
finally:
48-
session_request._intelowl_original = original
48+
api_request._intelowl_original = original
4949

5050
def test_timeout_can_be_configured_via_env(self):
5151
old_connect = os.environ.get("INTELOWL_REQUESTS_CONNECT_TIMEOUT")
@@ -54,20 +54,20 @@ def test_timeout_can_be_configured_via_env(self):
5454
os.environ["INTELOWL_REQUESTS_READ_TIMEOUT"] = "2.5"
5555

5656
try:
57-
session_request = requests.sessions.Session.request
58-
original = session_request._intelowl_original
57+
api_request = requests.api.request
58+
original = api_request._intelowl_original
5959
captured = {}
6060

61-
def stub(self, method, url, **kwargs):
61+
def stub(method, url, **kwargs):
6262
captured["timeout"] = kwargs.get("timeout")
6363
return "ok"
6464

65-
session_request._intelowl_original = stub
65+
api_request._intelowl_original = stub
6666
try:
67-
requests.Session().request("GET", "http://example.com")
67+
requests.get("http://example.com")
6868
self.assertEqual(captured["timeout"], (1.5, 2.5))
6969
finally:
70-
session_request._intelowl_original = original
70+
api_request._intelowl_original = original
7171
finally:
7272
if old_connect is None:
7373
os.environ.pop("INTELOWL_REQUESTS_CONNECT_TIMEOUT", None)

0 commit comments

Comments
 (0)