aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Numerlor <[email protected]>2021-09-11 15:09:33 +0200
committerGravatar Numerlor <[email protected]>2021-09-11 18:23:22 +0200
commit13e53790515da14703c204908513be33ab28539c (patch)
tree45fd8042bf8ef232f603eb9e7946097b71dedeb8
parentMerge pull request #1788 from python-discord/Only-check-domain-filters-agains... (diff)
Raise InvalidHeaderError if inventory has invalid header
If the requested inventory file has an invalid header, the resource has most likely moved or the url was invalid. In case of adding a new inventory, this error can be handled and displayed to the user. For automatic fetching it'll stop the rescheduling as the request succeeded but returned invalid content.
-rw-r--r--bot/exts/info/doc/_cog.py9
-rw-r--r--bot/exts/info/doc/_inventory_parser.py22
2 files changed, 24 insertions, 7 deletions
diff --git a/bot/exts/info/doc/_cog.py b/bot/exts/info/doc/_cog.py
index a2119a53d..ce3f4c95b 100644
--- a/bot/exts/info/doc/_cog.py
+++ b/bot/exts/info/doc/_cog.py
@@ -21,7 +21,7 @@ from bot.utils.lock import SharedEvent, lock
from bot.utils.messages import send_denial, wait_for_deletion
from bot.utils.scheduling import Scheduler
from . import NAMESPACE, PRIORITY_PACKAGES, _batch_parser, doc_cache
-from ._inventory_parser import InventoryDict, fetch_inventory
+from ._inventory_parser import InvalidHeaderError, InventoryDict, fetch_inventory
log = logging.getLogger(__name__)
@@ -135,7 +135,12 @@ class DocCog(commands.Cog):
The first attempt is rescheduled to execute in `FETCH_RESCHEDULE_DELAY.first` minutes, the subsequent attempts
in `FETCH_RESCHEDULE_DELAY.repeated` minutes.
"""
- package = await fetch_inventory(inventory_url)
+ try:
+ package = await fetch_inventory(inventory_url)
+ except InvalidHeaderError as e:
+ # Do not reschedule if the header is invalid, as the request went through but the contents are invalid.
+ log.warning(f"Invalid inventory header at {inventory_url}. Reason: {e}")
+ return
if not package:
if api_package_name in self.inventory_scheduler:
diff --git a/bot/exts/info/doc/_inventory_parser.py b/bot/exts/info/doc/_inventory_parser.py
index 80d5841a0..61924d070 100644
--- a/bot/exts/info/doc/_inventory_parser.py
+++ b/bot/exts/info/doc/_inventory_parser.py
@@ -16,6 +16,10 @@ _V2_LINE_RE = re.compile(r'(?x)(.+?)\s+(\S*:\S*)\s+(-?\d+)\s+?(\S*)\s+(.*)')
InventoryDict = DefaultDict[str, List[Tuple[str, str]]]
+class InvalidHeaderError(Exception):
+ """Raised when an inventory file has an invalid header."""
+
+
class ZlibStreamReader:
"""Class used for decoding zlib data of a stream line by line."""
@@ -80,19 +84,25 @@ async def _fetch_inventory(url: str) -> InventoryDict:
stream = response.content
inventory_header = (await stream.readline()).decode().rstrip()
- inventory_version = int(inventory_header[-1:])
- await stream.readline() # skip project name
- await stream.readline() # skip project version
+ try:
+ inventory_version = int(inventory_header[-1:])
+ except ValueError:
+ raise InvalidHeaderError("Unable to convert inventory version header.")
+
+ has_project_header = (await stream.readline()).startswith(b"# Project")
+ has_version_header = (await stream.readline()).startswith(b"# Version")
+ if not (has_project_header and has_version_header):
+ raise InvalidHeaderError("Inventory missing project or version header.")
if inventory_version == 1:
return await _load_v1(stream)
elif inventory_version == 2:
if b"zlib" not in await stream.readline():
- raise ValueError(f"Invalid inventory file at url {url}.")
+ raise InvalidHeaderError("'zlib' not found in header of compressed inventory.")
return await _load_v2(stream)
- raise ValueError(f"Invalid inventory file at url {url}.")
+ raise InvalidHeaderError("Incompatible inventory version.")
async def fetch_inventory(url: str) -> Optional[InventoryDict]:
@@ -115,6 +125,8 @@ async def fetch_inventory(url: str) -> Optional[InventoryDict]:
f"Failed to get inventory from {url}; "
f"trying again ({attempt}/{FAILED_REQUEST_ATTEMPTS})."
)
+ except InvalidHeaderError:
+ raise
except Exception:
log.exception(
f"An unexpected error has occurred during fetching of {url}; "