@@ -307,6 +307,22 @@ def __getitem__(self, k: str) -> threading.Lock:
307
307
return self ._locks [k ]
308
308
309
309
310
+ def _parse_basic_auth (url : str ) -> t .Tuple [str , str ]:
311
+ """Parse HTTP Basic username and password from URL.
312
+
313
+ Args:
314
+ url: URL to process
315
+
316
+ Returns:
317
+ Tuple containing the username and password
318
+ (or containing empty strings if the URL has no username and/or password)
319
+ """
320
+ parsed = urllib .parse .urlsplit (url )
321
+ username = parsed .username if parsed .username else ""
322
+ password = parsed .password if parsed .password else ""
323
+ return username , password
324
+
325
+
310
326
def _mask_password (url : str ) -> str :
311
327
"""Mask HTTP basic auth password in URL.
312
328
@@ -359,17 +375,31 @@ def __init__(self, index_url: str, ttl: int, session: requests.Session = None):
359
375
self ._index = {}
360
376
self ._packages = {}
361
377
self ._index_url_masked = _mask_password (index_url )
378
+ username , password = _parse_basic_auth (index_url )
379
+ if username :
380
+ # password either supplied or empty str
381
+ self ._auth = (username , password )
382
+ else :
383
+ self ._auth = None
362
384
363
385
def __repr__ (self ):
364
386
return f"{ self .__class__ .__name__ } ({ self ._index_url_masked !r} , { self .ttl !r} )"
365
387
388
+ def get (self , url , ** kwargs ):
389
+ """Wrapper for self.session.get to configure auth if provided."""
390
+ if self ._auth :
391
+ response = self .session .get (url , auth = self ._auth , ** kwargs )
392
+ else :
393
+ response = self .session .get (url , ** kwargs )
394
+ return response
395
+
366
396
def _list_packages (self ):
367
397
"""List projects using or updating cache."""
368
398
if self ._index_t is not None and _now () < self ._index_t + self .ttl :
369
399
return
370
400
371
401
logger .info (f"Listing packages in index '{ self ._index_url_masked } '" )
372
- response = self .session . get (self .index_url , headers = self ._headers )
402
+ response = self .get (self .index_url , headers = self ._headers )
373
403
response .raise_for_status ()
374
404
self ._index_t = _now ()
375
405
@@ -430,15 +460,15 @@ def _list_files(self, package_name: str):
430
460
if self ._index_t is None or _now () > self ._index_t + self .ttl :
431
461
url = urllib .parse .urljoin (self .index_url , package_name )
432
462
logger .debug (f"Refreshing '{ package_name } '" )
433
- response = self .session . get (url , headers = self ._headers )
463
+ response = self .get (url , headers = self ._headers )
434
464
if not response or not response .ok :
435
465
logger .debug (f"List-files response: { response } " )
436
466
package_name_normalised = _name_normalise_re .sub ("-" , package_name ).lower ()
437
467
if package_name_normalised not in self .list_projects ():
438
468
raise NotFound (package_name )
439
469
package_url = self ._index [package_name ]
440
470
url = urllib .parse .urljoin (self .index_url , package_url )
441
- response = self .session . get (url , headers = self ._headers )
471
+ response = self .get (url , headers = self ._headers )
442
472
response .raise_for_status ()
443
473
444
474
package = Package (package_name , files = {}, refreshed = _now ())
0 commit comments