Skip to content

Commit a73cd48

Browse files
committed
fix: handle limit_exceeded check for XML format responses
1 parent 58eb831 commit a73cd48

2 files changed

Lines changed: 40 additions & 7 deletions

File tree

domaintools/base_results.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
RequestUriTooLongException,
2626
)
2727

28-
2928
try: # pragma: no cover
3029
from collections.abc import MutableMapping, MutableSequence
3130
except ImportError: # pragma: no cover
@@ -111,7 +110,9 @@ def _make_request(self):
111110
if self.product == "iris-investigate" and "irisql" in self.kwargs:
112111
irisql_query = self.kwargs["irisql"]
113112
auth_keys = {"api_username", "timestamp", "signature", "api_key"}
114-
query_params = {k: v for k, v in self.kwargs.items() if k != "irisql" and k not in auth_keys}
113+
query_params = {
114+
k: v for k, v in self.kwargs.items() if k != "irisql" and k not in auth_keys
115+
}
115116
query_params.update(self.api.extra_request_params)
116117
return session.post(
117118
url=self.url,
@@ -164,21 +165,27 @@ def data(self):
164165
self._data = results.json()
165166
else:
166167
self._data = results.text
167-
168168
self.check_limit_exceeded()
169169

170170
return self._data
171171

172172
def check_limit_exceeded(self):
173173
limit_exceeded, reason = False, ""
174+
174175
if isinstance(self._data, dict) and (
175176
"response" in self._data
176177
and "limit_exceeded" in self._data["response"]
177178
and self._data["response"]["limit_exceeded"] is True
178179
):
179180
limit_exceeded, reason = True, self._data["response"]["message"]
180181
elif "response" in self._data and "limit_exceeded" in self._data:
181-
limit_exceeded = True
182+
# check for xml format, and return the actual error message
183+
if self.kwargs.get("format") == "xml" and isinstance(self._data, str):
184+
if re.search(r"<limit_exceeded>1</limit_exceeded>", self._data):
185+
msg = re.search(r"<message>(.*?)</message>", self._data)
186+
limit_exceeded, reason = True, msg.group(1) if msg else ""
187+
else:
188+
limit_exceeded = True
182189

183190
if limit_exceeded:
184191
raise ServiceException(503, f"Limit Exceeded {reason}")
@@ -354,9 +361,7 @@ def html(self):
354361
)
355362

356363
def as_list(self):
357-
return "\n".join(
358-
[json.dumps(item, indent=4, separators=(",", ": ")) for item in self._items()]
359-
)
364+
return "\n".join([json.dumps(item, indent=4, separators=(",", ": ")) for item in self._items()])
360365

361366
def __str__(self):
362367
return str(

tests/test_api.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,34 @@ def test_limit_exceeded():
602602
response.response()
603603

604604

605+
def test_limit_exceeded_xml():
606+
xml_response = """<response>
607+
<error>
608+
<code>413</code>
609+
<message>Maximum 10000 returned - you may need to refine your query.</message>
610+
</error>
611+
<limit_exceeded>1</limit_exceeded>
612+
<has_more_results>1</has_more_results>
613+
<message>Maximum 10000 returned - you may need to refine your query.</message>
614+
<missing_domains/>
615+
</response>"""
616+
617+
mock_response = MagicMock()
618+
mock_response.status_code = 200
619+
mock_response.text = xml_response
620+
621+
with patch("domaintools.base_results.Client") as mock_client:
622+
mock_session = MagicMock()
623+
mock_client.return_value.__enter__.return_value = mock_session
624+
mock_session.post.return_value = mock_response
625+
626+
with pytest.raises(exceptions.ServiceException) as exc_info:
627+
result = api.iris_investigate(ip="8.8.8.8", format="xml")
628+
result.data()
629+
630+
assert "Maximum 10000 returned" in str(exc_info.value)
631+
632+
605633
@vcr.use_cassette
606634
def test_newly_observed_domains_feed():
607635
results = feeds_api.nod(after="-60", top=5)

0 commit comments

Comments
 (0)