@@ -260,7 +260,7 @@ def parse_cygwin_request(request_path: str):
260
260
261
261
# Variables used by the MSYS2 functions below
262
262
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" )
264
264
valid_envs = (
265
265
# Tuple of systems and supported libraries/compilers/architectures within
266
266
(
@@ -294,15 +294,25 @@ def parse_cygwin_request(request_path: str):
294
294
)
295
295
296
296
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 ):
299
299
"""
300
300
Obtain and pass through an MSYS2 installer from an official source.
301
301
This is used during client bootstrapping, and can download and install the
302
302
MSYS2 distribution that then remains on the client machines.
303
303
"""
304
304
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 } " )
306
316
return Response (
307
317
content = installer .content ,
308
318
media_type = installer .headers .get ("Content-Type" ),
@@ -319,24 +329,6 @@ def get_msys2_main_index(
319
329
from the main MSYS2 repository.
320
330
"""
321
331
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
-
340
332
def _rewrite_url (match ):
341
333
"""
342
334
Use regular expression matching to rewrite the package URLs and point them
@@ -363,35 +355,15 @@ def _rewrite_url(match):
363
355
content_text_list = []
364
356
for line in content_text .splitlines ():
365
357
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 :
368
360
line_new = re .sub (
369
361
'^<a href="([^">]*)">([^<]*)</a>' , # Regex search criteria
370
362
_rewrite_url , # Function to apply search criteria to
371
363
line ,
372
364
)
373
365
content_text_list .append (line_new )
374
366
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 )
395
367
# Other URLs don't need to be mirrored
396
368
else :
397
369
pass
@@ -435,8 +407,8 @@ def _rewrite_url(match):
435
407
path = request .url .path .strip ("/" )
436
408
base_path = f"{ base_url } /{ path } "
437
409
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" ) :
440
412
raise ValueError (f"{ system !r} is not a valid msys2 environment" )
441
413
442
414
# Construct URL to main MSYS repo and get response
@@ -449,6 +421,11 @@ def _rewrite_url(match):
449
421
content_text_list = []
450
422
for line in content_text .splitlines ():
451
423
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
+
452
429
# Rewrite URL to point explicitly to current server
453
430
line_new = re .sub (
454
431
'^<a href="([^">]*)">([^<]*)</a>' , # Regex search criteria
0 commit comments