1313from concurrent .futures import ThreadPoolExecutor , as_completed
1414import urllib .request
1515import urllib .error
16+ import ssl
1617
1718# Configuration
1819TIMEOUT = 15 # seconds
1920MAX_RETRIES = 2
2021MAX_WORKERS = 20 # Number of concurrent checks
2122RATE_LIMIT_DELAY = 0.1 # Small delay between batches
23+ VERIFY_SSL = False # Set to False to bypass SSL certificate verification
2224
2325
2426class Colors :
@@ -52,6 +54,12 @@ def check_url(url: str, retries: int = MAX_RETRIES) -> Tuple[bool, str, int]:
5254 Returns:
5355 Tuple of (success: bool, message: str, status_code: int)
5456 """
57+ # Create SSL context
58+ if VERIFY_SSL :
59+ ssl_context = ssl .create_default_context ()
60+ else :
61+ ssl_context = ssl ._create_unverified_context ()
62+
5563 for attempt in range (retries ):
5664 try :
5765 # Try HEAD request first (faster, doesn't download content)
@@ -64,7 +72,7 @@ def check_url(url: str, retries: int = MAX_RETRIES) -> Tuple[bool, str, int]:
6472 }
6573 )
6674
67- with urllib .request .urlopen (req , timeout = TIMEOUT ) as response :
75+ with urllib .request .urlopen (req , timeout = TIMEOUT , context = ssl_context ) as response :
6876 status_code = response .getcode ()
6977 content_type = response .headers .get ('Content-Type' , '' )
7078 content_length = response .headers .get ('Content-Length' , 'unknown' )
@@ -86,7 +94,7 @@ def check_url(url: str, retries: int = MAX_RETRIES) -> Tuple[bool, str, int]:
8694 'Accept' : '*/*'
8795 }
8896 )
89- with urllib .request .urlopen (req , timeout = TIMEOUT ) as response :
97+ with urllib .request .urlopen (req , timeout = TIMEOUT , context = ssl_context ) as response :
9098 status_code = response .getcode ()
9199 content_length = response .headers .get ('Content-Length' , 'unknown' )
92100 # Read only first 512 bytes to verify
0 commit comments