Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion scripts/mirror_plugin_archive_contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "httpx",
# "ida-hcli",
# "rich",
# ]
Expand All @@ -49,8 +50,10 @@
import hashlib
import logging
import shutil
import urllib.request
from pathlib import Path

import httpx
import rich.console
import rich.progress
from hcli.lib.ida.plugin import (
Expand All @@ -68,6 +71,25 @@
stderr_console = rich.console.Console(stderr=True)


def fetch_plugin_archive_with_redirects(url: str) -> bytes:
try:
return fetch_plugin_archive(url)
except httpx.HTTPStatusError as e:
if e.response.status_code not in {301, 302, 303, 307, 308}:
raise

logger.info(
"retrying with urllib.request to follow redirect (%s) for plugin archive: %s",
e.response.status_code,
url,
)
with urllib.request.urlopen(url, timeout=30) as response:
redirected_url = response.geturl()
if not redirected_url.startswith("https://"):
raise ValueError(f"redirected plugin archive URL is not HTTPS: {redirected_url}")
return response.read()


def do_cache(json_path: Path, out_path: Path, no_cache: bool = False):
repo = JSONFilePluginRepo.from_file(json_path)
plugins = repo.get_plugins()
Expand Down Expand Up @@ -104,7 +126,7 @@ def do_cache(json_path: Path, out_path: Path, no_cache: bool = False):

assert location.url.startswith("https://")

zip_data = fetch_plugin_archive(location.url)
zip_data = fetch_plugin_archive_with_redirects(location.url)

metadata_path, metadata = get_metadata_from_plugin_archive(zip_data, plugin.name)
validate_metadata_in_plugin_archive(zip_data, metadata_path, metadata)
Expand Down