Skip to content

Commit a69d427

Browse files
authored
Prefer final_url over original URL for archive format detection in download paths
1 parent a8320d9 commit a69d427

3 files changed

Lines changed: 31 additions & 20 deletions

File tree

src/specify_cli/__init__.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2632,14 +2632,17 @@ def preset_add(
26322632
from .extensions import detect_archive_format as _det_fmt
26332633

26342634
with tempfile.TemporaryDirectory() as tmpdir:
2635-
archive_fmt = _det_fmt(from_url)
26362635
final_url = from_url
2636+
archive_fmt = ""
26372637
try:
26382638
with urllib.request.urlopen(from_url, timeout=60) as response:
26392639
final_url = response.geturl()
2640+
content_type = response.headers.get("Content-Type", "")
2641+
# Prefer the post-redirect URL for format detection;
2642+
# fall back to the original URL only as a last hint.
2643+
archive_fmt = _det_fmt(final_url, content_type)
26402644
if not archive_fmt:
2641-
content_type = response.headers.get("Content-Type", "")
2642-
archive_fmt = _det_fmt(final_url, content_type)
2645+
archive_fmt = _det_fmt(from_url)
26432646
archive_data = response.read()
26442647
except urllib.error.URLError as e:
26452648
console.print(f"[red]Error:[/red] Failed to download: {e}")
@@ -3657,18 +3660,22 @@ def extension_add(
36573660
console.print("Only install extensions from sources you trust.\n")
36583661
console.print(f"Downloading from {from_url}...")
36593662

3660-
# Download archive to temp location; detect format from URL or Content-Type.
3663+
# Download archive to temp location; detect format from the
3664+
# post-redirect URL (with Content-Type fallback), only using
3665+
# the original URL as a last hint.
36613666
download_dir = project_root / ".specify" / "extensions" / ".cache" / "downloads"
36623667
download_dir.mkdir(parents=True, exist_ok=True)
3663-
archive_fmt = detect_archive_format(from_url)
3668+
final_url = from_url
3669+
archive_fmt = ""
36643670
archive_path = None
36653671

36663672
try:
36673673
with urllib.request.urlopen(from_url, timeout=60) as response:
36683674
final_url = response.geturl()
3675+
content_type = response.headers.get("Content-Type", "")
3676+
archive_fmt = detect_archive_format(final_url, content_type)
36693677
if not archive_fmt:
3670-
content_type = response.headers.get("Content-Type", "")
3671-
archive_fmt = detect_archive_format(final_url, content_type)
3678+
archive_fmt = detect_archive_format(from_url)
36723679
archive_data = response.read()
36733680

36743681
# Re-validate scheme after any redirect (scheme-downgrade guard).

src/specify_cli/extensions.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2156,17 +2156,19 @@ def download_extension(self, extension_id: str, target_dir: Optional[Path] = Non
21562156

21572157
version = ext_info.get("version", "unknown")
21582158

2159-
# Detect archive format from URL; resolve via Content-Type when needed.
2160-
# `final_url` may differ from `download_url` if the server redirects.
2161-
archive_fmt = detect_archive_format(download_url)
2162-
2163-
# Download the archive
2159+
# Download the archive. Determine the archive format from the
2160+
# post-redirect URL first (with Content-Type fallback); only use the
2161+
# original `download_url` as a last hint if the final URL gives no
2162+
# signal.
2163+
final_url = download_url
2164+
archive_fmt = ""
21642165
try:
21652166
with self._open_url(download_url, timeout=60) as response:
21662167
final_url = response.geturl()
2168+
content_type = response.headers.get("Content-Type", "")
2169+
archive_fmt = detect_archive_format(final_url, content_type)
21672170
if not archive_fmt:
2168-
content_type = response.headers.get("Content-Type", "")
2169-
archive_fmt = detect_archive_format(final_url, content_type)
2171+
archive_fmt = detect_archive_format(download_url)
21702172
archive_data = response.read()
21712173

21722174
except urllib.error.URLError as e:

src/specify_cli/presets.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2313,16 +2313,18 @@ def download_pack(
23132313

23142314
version = pack_info.get("version", "unknown")
23152315

2316-
# Detect archive format from URL; resolve via Content-Type when needed.
2317-
# `final_url` may differ from `download_url` if the server redirects.
2318-
archive_fmt = detect_archive_format(download_url)
2319-
2316+
# Determine the archive format from the post-redirect URL first
2317+
# (with Content-Type fallback); only use the original `download_url`
2318+
# as a last hint if the final URL gives no signal.
2319+
final_url = download_url
2320+
archive_fmt = ""
23202321
try:
23212322
with self._open_url(download_url, timeout=60) as response:
23222323
final_url = response.geturl()
2324+
content_type = response.headers.get("Content-Type", "")
2325+
archive_fmt = detect_archive_format(final_url, content_type)
23232326
if not archive_fmt:
2324-
content_type = response.headers.get("Content-Type", "")
2325-
archive_fmt = detect_archive_format(final_url, content_type)
2327+
archive_fmt = detect_archive_format(download_url)
23262328
archive_data = response.read()
23272329

23282330
except urllib.error.URLError as e:

0 commit comments

Comments
 (0)