1616# You can download the latest version of this tool from:
1717# https://github.com/MiSTer-devel/Downloader_MiSTer
1818
19+ import socket
1920import ssl
2021import sys
2122import threading
@@ -183,7 +184,8 @@ def _take_connection(self, queue_id: '_QueueId') -> '_Connection':
183184 with self ._connections_lock :
184185 if queue_id not in self ._connections :
185186 self ._connections [queue_id ] = _ConnectionQueue (queue_id , self ._timeout , self ._ssl_ctx , self ._logger , self ._config )
186- return self ._connections [queue_id ].pull ()
187+ queue = self ._connections [queue_id ]
188+ return queue .pull ()
187189
188190 def _clean_timeout_connections (self , now : float ) -> None :
189191 if now - self ._clean_timeout_connections_timer < 30.0 :
@@ -416,21 +418,31 @@ def __init__(self, queue_id: _QueueId, timeout: float, ctx: ssl.SSLContext, logg
416418 self ._queue_swap : List [_Connection ] = []
417419 self ._lock = threading .Lock ()
418420 self ._last_conn_id = - 1
421+ self ._queue_cleared = False
419422
420423 def pull (self ) -> _Connection :
421424 with self ._lock :
422- if len (self ._queue ) == 0 :
425+ if len (self ._queue ) > 0 :
426+ return self ._queue .pop ()
427+ else :
423428 self ._last_conn_id += 1
424- http_conn = create_http_connection (self .id [0 ], self .id [1 ], self ._timeout , self ._ctx , self ._config )
425- return _Connection (conn_id = self ._last_conn_id , http = http_conn , connection_queue = self , logger = self ._logger )
426- return self ._queue .pop ()
429+ conn_id = self ._last_conn_id
430+
431+ http_conn = create_http_connection (self .id [0 ], self .id [1 ], self ._timeout , self ._ctx , self ._config )
432+ with self ._lock :
433+ if self ._queue_cleared :
434+ http_conn .close ()
435+ raise HttpGatewayException ('Connection queue is already cleared.' )
436+
437+ return _Connection (conn_id = conn_id , http = http_conn , connection_queue = self , logger = self ._logger )
427438
428439 def push (self , connection : _Connection ) -> None :
429440 with self ._lock :
430441 self ._queue .append (connection )
431442
432443 def clear_all (self ) -> int :
433444 with self ._lock :
445+ self ._queue_cleared = True
434446 size = len (self ._queue )
435447 for connection in self ._queue :
436448 connection .kill ()
@@ -454,36 +466,36 @@ def clear_timed_outs(self, now: float) -> int:
454466
455467 return expired_count
456468
457-
458469def create_http_connection (scheme : str , netloc : str , timeout : float , ctx : ssl .SSLContext , config : Optional [dict [str , Any ]]) -> HTTPConnection :
459470 if scheme == 'http' :
460471 if config and config ['http_proxy' ]:
461472 proxy = config ['http_proxy' ]
462473 proxy_host = proxy .hostname
463474 proxy_port = proxy .port or (443 if proxy .scheme == 'https' else 80 )
464475 if proxy .scheme == 'https' :
465- return HTTPSConnection (proxy_host , proxy_port , timeout = timeout , context = ctx )
466- return HTTPConnection (proxy_host , proxy_port , timeout = timeout )
467- return HTTPConnection (netloc , timeout = timeout )
476+ return _add_socket ( HTTPSConnection (proxy_host , proxy_port , timeout = timeout , context = ctx ), proxy_host , proxy_port , timeout , ssl_ctx = ctx )
477+ return _add_socket ( HTTPConnection (proxy_host , proxy_port , timeout = timeout ), proxy_host , proxy_port , timeout )
478+ return _add_socket ( HTTPConnection (netloc , timeout = timeout ), netloc , 80 , timeout )
468479
469480 elif scheme == 'https' :
470481 if config and config ['https_proxy' ]:
471482 proxy = config ['https_proxy' ]
472483 proxy_host = proxy .hostname
473484 proxy_port = proxy .port or (443 if proxy .scheme == 'https' else 80 )
474- parsed_netloc = urlparse (f'//{ netloc } ' )
475- target_host = parsed_netloc .hostname
476- target_port = parsed_netloc .port or 443
477- if not target_host :
478- raise HttpGatewayException (f"Invalid netloc: { netloc } " )
479-
480485 conn = HTTPSConnection (proxy_host , proxy_port , timeout = timeout , context = ctx )
481- conn .set_tunnel (target_host , target_port , headers = config .get ('https_proxy_headers' ))
482- return conn
483- return HTTPSConnection (netloc , timeout = timeout , context = ctx )
484-
485- else :
486- raise HttpGatewayException (f"Scheme { scheme } not supported" )
486+ conn .set_tunnel (netloc , 443 , headers = config .get ('https_proxy_headers' ))
487+ return _add_socket (conn , proxy_host , proxy_port , timeout , ssl_ctx = (ctx if proxy .scheme == 'https' else None ))
488+ return _add_socket (HTTPSConnection (netloc , timeout = timeout , context = ctx ), netloc , 443 , timeout , ssl_ctx = ctx )
489+
490+ raise HttpGatewayException (f"Scheme { scheme } not supported" )
491+
492+ def _add_socket (conn : HTTPConnection , host : str , port : int , timeout : float , ssl_ctx : Optional [ssl .SSLContext ] = None ) -> HTTPConnection :
493+ sock = socket .create_connection ((host , port ), timeout = 15 )
494+ sock .settimeout (timeout )
495+ if ssl_ctx :
496+ sock = ssl_ctx .wrap_socket (sock , server_hostname = host )
497+ conn .sock = sock
498+ return conn
487499
488500
489501class _ResponseHeaders :
0 commit comments