Skip to content

Commit 1241adb

Browse files
authored
Updated MSYS2 API endpoints to expose more types of installers and archives for download (#514)
* Updated MSYS2 API endpoints to expose more types of installers and archives for download * Deleted deprecated endpoints
1 parent 5e8def4 commit 1241adb

File tree

1 file changed

+23
-46
lines changed

1 file changed

+23
-46
lines changed

src/murfey/server/api/bootstrap.py

+23-46
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ def parse_cygwin_request(request_path: str):
260260

261261
# Variables used by the MSYS2 functions below
262262
msys2_url = "https://repo.msys2.org"
263-
msys2_setup_file = "msys2-x86_64-latest.exe"
263+
msys2_file_ext = (".exe", ".sig", ".tar.xz", "tar.zst")
264264
valid_envs = (
265265
# Tuple of systems and supported libraries/compilers/architectures within
266266
(
@@ -294,15 +294,25 @@ def parse_cygwin_request(request_path: str):
294294
)
295295

296296

297-
@msys2.get("/setup-x86_64.exe", response_class=Response)
298-
def get_msys2_setup():
297+
@msys2.get("/distrib/{setup_file}", response_class=Response)
298+
def get_msys2_setup(setup_file: str):
299299
"""
300300
Obtain and pass through an MSYS2 installer from an official source.
301301
This is used during client bootstrapping, and can download and install the
302302
MSYS2 distribution that then remains on the client machines.
303303
"""
304304

305-
installer = requests.get(f"{msys2_url}/distrib/{msys2_setup_file}")
305+
# Validate characters in sent path
306+
if not bool(re.fullmatch(r"^[\w\.\-]+$", setup_file)):
307+
raise ValueError("Unallowed characters present in requested setup file")
308+
309+
# Allow only '.exe', 'tar.xz', 'tar.zst', or '.sig' files
310+
if not setup_file.startswith("msys2") and not any(
311+
setup_file.endswith(ext) for ext in (msys2_file_ext)
312+
):
313+
raise ValueError(f"{setup_file!r} is not a valid executable")
314+
315+
installer = requests.get(f"{msys2_url}/distrib/{setup_file}")
306316
return Response(
307317
content=installer.content,
308318
media_type=installer.headers.get("Content-Type"),
@@ -319,24 +329,6 @@ def get_msys2_main_index(
319329
from the main MSYS2 repository.
320330
"""
321331

322-
def get_msys2_setup_html():
323-
"""
324-
Returns the HTML line for the latest MSYS2 installer for Windows from an official
325-
source.
326-
"""
327-
url = f"{msys2_url}/distrib"
328-
index = requests.get(url)
329-
content: bytes = index.content
330-
content_text: str = content.decode("latin1")
331-
332-
for line in content_text.splitlines():
333-
if line.startswith("<a href="):
334-
if f'"{msys2_setup_file}"' in line:
335-
return line
336-
else:
337-
pass
338-
return None
339-
340332
def _rewrite_url(match):
341333
"""
342334
Use regular expression matching to rewrite the package URLs and point them
@@ -363,35 +355,15 @@ def _rewrite_url(match):
363355
content_text_list = []
364356
for line in content_text.splitlines():
365357
if line.startswith("<a href"):
366-
# Mirror only lines related to MSYS2 environments
367-
if any(env[0] in line for env in valid_envs):
358+
# Mirror only lines related to MSYS2 environments or the distribution folder
359+
if any(env[0] in line for env in valid_envs) or "distrib" in line:
368360
line_new = re.sub(
369361
'^<a href="([^">]*)">([^<]*)</a>', # Regex search criteria
370362
_rewrite_url, # Function to apply search criteria to
371363
line,
372364
)
373365
content_text_list.append(line_new)
374366

375-
# Replace the "distrib/" hyperlink with one to the setup file
376-
elif "distrib" in line:
377-
# Set up URL to be requested on the Murfey server
378-
mirror_file_name = "setup-x86_64.exe"
379-
setup_url = f"{base_path}/{mirror_file_name}"
380-
381-
# Get request from the "distrib" page and rewrite it
382-
setup_html = get_msys2_setup_html()
383-
if setup_html is None:
384-
# Skip showing the setup file link if it fails to find it
385-
continue
386-
387-
line_new = " ".join( # Adjust spaces to align columns
388-
re.sub(
389-
'^<a href="([^">]*)">([^"<]*)</a>',
390-
f'<a href="{setup_url}">{mirror_file_name}</a>',
391-
setup_html,
392-
).split(" ", 1)
393-
)
394-
content_text_list.append(line_new)
395367
# Other URLs don't need to be mirrored
396368
else:
397369
pass
@@ -435,8 +407,8 @@ def _rewrite_url(match):
435407
path = request.url.path.strip("/")
436408
base_path = f"{base_url}/{path}"
437409

438-
# Validate provided system
439-
if any(system in env[0] for env in valid_envs) is False:
410+
# Validate provided system; use this endpoint to display 'distrib' folder too
411+
if not (any(system in env[0] for env in valid_envs) or system == "distrib"):
440412
raise ValueError(f"{system!r} is not a valid msys2 environment")
441413

442414
# Construct URL to main MSYS repo and get response
@@ -449,6 +421,11 @@ def _rewrite_url(match):
449421
content_text_list = []
450422
for line in content_text.splitlines():
451423
if line.startswith("<a href="):
424+
# Skip non-executable files when querying 'distrib' repo
425+
if system == "distrib":
426+
if not any(ext in line for ext in msys2_file_ext):
427+
continue
428+
452429
# Rewrite URL to point explicitly to current server
453430
line_new = re.sub(
454431
'^<a href="([^">]*)">([^<]*)</a>', # Regex search criteria

0 commit comments

Comments
 (0)