U
    g,>                     @  s  d dl mZ d dlZd dlZd dlZd dlZd dlZd dl	Zd dl
Zd dlZd dlZd dl
mZmZmZmZmZmZmZ ddlmZmZmZmZmZmZmZ ddlmZmZmZm Z  ddl!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( dd	l)m*Z* dd
l+m%Z, ddl-m.Z. ddl/m0Z0 ddgZ1ej2e3gZ4e*r6e15d e45e*j2 dd Z6G dd dej7j8Z9dd Z:G dd dej7j;Z<G dd dej7j=Z>G dd dej7j?Z@G dd dej7j?ZAd*ddZBG d d! d!eZCd"d#d$d%ZDd&d' ZEe G d(d) d)eeZFdS )+    )annotationsN)DataHandlerFileHandler
FTPHandlerHTTPCookieProcessorHTTPDefaultErrorHandlerHTTPErrorProcessorUnknownHandler   )InstanceStoreMixinadd_accept_encoding_headercreate_connectioncreate_socks_proxy_socketget_redirect_methodmake_socks_proxy_optsselect_proxy)FeaturesRequestHandlerResponseregister_rh)CertificateVerifyError	HTTPErrorIncompleteRead
ProxyErrorRequestErrorSSLErrorTransportError   )brotli)r   )update_url_query)normalize_urlgzipdeflatebrc                 O  s0   | ||}t |drt|_|d k	r,|df|_|S )N_create_connectionr   )hasattrr   r$   source_address)
http_classr&   argskwargsZhc r*   =/tmp/pip-unpacked-wheel-q5ljy6pj/yt_dlp/networking/_urllib.py_create_http_connection6   s    


r,   c                      s~   e Zd ZdZd fdd	Zedd Zdd Zd	d
 Zedd Z	edd Z
edd Z fddZdd ZeZeZ  ZS )HTTPHandlera  Handler for HTTP requests and responses.

    This class, when installed with an OpenerDirector, automatically adds
    the standard headers to every HTTP request and handles gzipped, deflated and
    brotli responses from web servers.

    Part of this code was copied from:

    http://techknack.net/python-urllib2-handlers/

    Andrew Rowls, the author of that code, agreed to release it to the
    public domain.
    Nc                   s   t  j|| || _|| _d S N)super__init___source_address_context)selfcontextr&   r(   r)   	__class__r*   r+   r0   Q   s    zHTTPHandler.__init__c                 C  s$   | }|j dd }|r t||}|S )NYtdl-socks-proxy)headerspopmake_socks_conn_class)basereq
conn_classsocks_proxyr*   r*   r+   _make_conn_classV   s
    
zHTTPHandler._make_conn_classc                 C  s(   |  tjj|}| tt|| j|S r.   )	r?   httpclientHTTPConnectiondo_open	functoolspartialr,   r1   r3   r<   r=   r*   r*   r+   	http_open^   s      zHTTPHandler.http_openc                 C  s.   |  tjj|}| jtt|| j|| j	dS )N)r4   )
r?   r@   rA   HTTPSConnectionrC   rD   rE   r,   r1   r2   rF   r*   r*   r+   
https_openc   s       zHTTPHandler.https_openc                 C  s@   | s| S zt | t j W S  t jk
r:   t |  Y S X d S r.   )zlib
decompress	MAX_WBITSerrordatar*   r*   r+   r"   j   s    zHTTPHandler.deflatec                 C  s   | s| S t | S r.   )r   rK   rN   r*   r*   r+   r   s   s    zHTTPHandler.brotlic                 C  s   | s| S t j| t jdB dS )N   )wbits)rJ   rK   rL   rN   r*   r*   r+   gzy   s    zHTTPHandler.gzc                   s0   |  }t|}||kr$t||d}t |S )N)url)get_full_urlr    update_Requestr/   do_request_)r3   r<   rS   Zurl_escapedr5   r*   r+   http_request   s
    	zHTTPHandler.http_requestc                 C  s  |}d }dd t |jdddD D ]Z}|dkrJ| |pD| }q*|dkrf| |p`| }q*|dkr*tr*| |p| }q*|d k	rtj	
t||j|j|j}|j|_d	|j  krd
k rn nD|jd}|r|d }t|}||kr|jd= ||jd< |S )Nc                 s  s   | ]}|  V  qd S r.   )strip).0er*   r*   r+   	<genexpr>   s     z,HTTPHandler.http_response.<locals>.<genexpr>zContent-encoding ,r!   r"   r#   i,  i  ZLocationz
iso-8859-1)reversedr8   getsplitrR   readr"   r   urllibrequest
addinfourlioBytesIOrS   codemsgencodedecoder    )r3   r<   respZold_respZdecoded_responseencodinglocationZlocation_escapedr*   r*   r+   http_response   s*    &

zHTTPHandler.http_response)NN)__name__
__module____qualname____doc__r0   staticmethodr?   rG   rI   r"   r   rR   rW   rn   https_requesthttps_response__classcell__r*   r*   r5   r+   r-   B   s    



r-   c                   s:   t | tjjtjjfstt| G  fddd| }|S )Nc                      s   e Zd ZeZ fddZdS )z.make_socks_conn_class.<locals>.SocksConnectionc              	     s\   t  d  d f| j| jtt| j| jf d| _t	| t
jjrX| jj| j| jd| _d S )Naddrport)timeoutr&   Z_create_socket_func)server_hostname)r   ry   r&   rD   rE   r   hostrx   sock
isinstancer@   rA   rH   r2   wrap_socketr3   Z
proxy_argsr*   r+   connect   s     
 z6make_socks_conn_class.<locals>.SocksConnection.connectN)ro   rp   rq   r   r$   r   r*   r   r*   r+   SocksConnection   s   r   )
issubclassr@   rA   rB   rH   AssertionErrorr   )Z
base_classr>   r   r*   r   r+   r:      s     
r:   c                   @  s.   e Zd ZdZejjj Z Z	 Z
Zdd ZdS )RedirectHandlera  YoutubeDL redirect handler

    The code is based on HTTPRedirectHandler implementation from CPython [1].

    This redirect handler fixes and improves the logic to better align with RFC7261
     and what browsers tend to do [2][3]

    1. https://github.com/python/cpython/blob/master/Lib/urllib/request.py
    2. https://datatracker.ietf.org/doc/html/rfc7231
    3. https://github.com/python/cpython/issues/91306
    c           
        s   |dkrt j|j|||||j}dg t| |}|| krVd } ddg  fdd|j	 D }	t j
j||	|jd||dS )	N)i-  i.  i/  i3  i4  CookiezContent-LengthzContent-Typec                   s"   i | ]\}}|   kr||qS r*   )title)rY   kvZremove_headersr*   r+   
<dictcomp>   s       z4RedirectHandler.redirect_request.<locals>.<dictcomp>T)r8   origin_req_hostunverifiablemethodrO   )rb   rM   r   full_urlrO   r   
get_methodextendr8   itemsrc   Requestr   )
r3   r<   fprg   rh   r8   newurlZnew_dataZ
new_methodnew_headersr*   r   r+   redirect_request   s"        z RedirectHandler.redirect_requestN)ro   rp   rq   rr   rb   rc   HTTPRedirectHandlerhttp_error_302http_error_301http_error_303http_error_307Zhttp_error_308r   r*   r*   r*   r+   r      s   r   c                   @  s"   e Zd ZdZdddZdd ZdS )ProxyHandlerd   Nc                 C  s0   || _ dD ] }t| | d| jfdd q
d S )N)r@   httpsftp_openc                 S  s   || S r.   r*   )rmethr*   r*   r+   <lambda>       z'ProxyHandler.__init__.<locals>.<lambda>)proxiessetattr
proxy_open)r3   r   schemer*   r*   r+   r0      s    zProxyHandler.__init__c                 C  sV   t | | j}|d krd S tj|j dkrB|d| d S tj	j
| ||d S )N)socks4socks4asocks5socks5hr7   )r   rT   r   rb   parseurlparser   lower
add_headerrc   r   r   )r3   r<   proxyr*   r*   r+   r      s       zProxyHandler.proxy_open)N)ro   rp   rq   handler_orderr0   r   r*   r*   r*   r+   r      s   
r   c                   @  s   e Zd Zdd ZdS )
PUTRequestc                 C  s   dS )NPUTr*   r   r*   r*   r+   r   	  s    zPUTRequest.get_methodNro   rp   rq   r   r*   r*   r*   r+   r     s   r   c                   @  s   e Zd Zdd ZdS )HEADRequestc                 C  s   dS )NHEADr*   r   r*   r*   r+   r     s    zHEADRequest.get_methodNr   r*   r*   r*   r+   r     s   r   c                 C  s   | j  }||pi  |d k	r$|n| j}t|p6|  |}|  }|dkrRt}	n|dkr`t}	nt	j
j}	|	|||| j| jd}
t| dr| j|
_|
S )Nr   r   )rO   r8   r   r   ry   )r8   copyupdaterO   r   rT   r   r   r   rb   rc   r   r   r   r%   ry   )r<   rS   rO   r8   queryZreq_headersZreq_dataZreq_urlZreq_get_methodZreq_typeZnew_reqr*   r*   r+   rU     s(    
   
rU   c                      s0   e Zd ZdZdd fddZd	ddZ  ZS )
UrllibResponseAdapterzX
    HTTP Response adapter class for urllib addinfourl and http.client.HTTPResponse
    z5http.client.HTTPResponse | urllib.response.addinfourl)resc              	     s6   t  j||j|jt|dd p"| t|dd d d S )Nstatusreason)r   r8   rS   r   r   )r/   r0   r8   rS   getattrgetcode)r3   r   r5   r*   r+   r0   +  s       
zUrllibResponseAdapter.__init__Nc              
   C  sB   z| j |W S  tk
r< } zt| |W 5 d }~X Y nX d S r.   )r   ra   	Exceptionhandle_response_read_exceptions)r3   amtrZ   r*   r*   r+   ra   4  s
    zUrllibResponseAdapter.read)N)ro   rp   rq   rr   r0   ra   rv   r*   r*   r5   r+   r   &  s   	r   zssl.SSLErrorrZ   c                 C  s8   t | tjsd S t | tjr(t| d| t| d| d S )Ncause)r}   sslr   SSLCertVerificationErrorr   r   r*   r*   r+   handle_sslerror<  s
    r   c                 C  sf   t | tjjr(tt| j| | jd| n:t | tjr>t	|  n$t | t
ttjjftrbt| d| d S )N)rE   r   expectedr   )r}   r@   rA   r   lenrE   r   r   r   r   OSErrorEOFErrorHTTPExceptionCONTENT_DECODE_ERRORSr   r   r*   r*   r+   r   D  s    
r   c                      s^   e Zd ZdZdZejejfZdZ	dddd fddZ
 fd	d
ZdddZdd Z  ZS )UrllibRH)r@   r   rO   r   )r@   r   r   r   r   rb   F)enable_file_urlsboolc                  s*   t  jf | || _| jr&| jd| _d S )Nfile)r   )r/   r0   r   _SUPPORTED_URL_SCHEMES)r3   r   r)   r5   r*   r+   r0   U  s    zUrllibRH.__init__c                   s4   t  | |dd  |dd  |dd  d S )N	cookiejarry   
legacy_ssl)r/   _check_extensionsr9   )r3   
extensionsr5   r*   r+   r   [  s    zUrllibRH._check_extensionsNc              	   C  s   t j }t|ttt| j| j|d| j	dt
|t t t t t t g	}| jrd|t  |D ]}|| qhg |_|S )N)legacy_ssl_support)
debuglevelr4   r&   )rb   rc   OpenerDirectorr   r-   intr   verboseZ_make_sslcontextr&   r   r   r	   r   r   r   r   r   appendr   add_handler
addheaders)r3   r   r   r   openerhandlershandlerr*   r*   r+   _create_instancea  s*    

zUrllibRH._create_instancec              
   C  s  |  |j}t|t tjj|j|jt	||j
d}| j| || ||jdd}z|j|| |d}W n0 tjjk
r } zBt|jtjjtjjfrd|j_tt|jdt|kd| W 5 d }~X Y n tjjk
r@ } zH|j }dt|! kst|t"rt#|d	|t$| t%|d	|W 5 d }~X Y nd tjj&t'fk
rv } zt(|d	|W 5 d }~X Y n. t)k
r } zt$|  W 5 d }~X Y nX t|S )
N)rS   rO   r8   r   r   )r   r   r   )ry   Tzredirect error)Zredirect_loopztunnel connection failedr   )*Z_merge_headersr8   r   SUPPORTED_ENCODINGSrb   rc   r   rS   rO   dictr   Z_get_instanceZ_get_proxiesZ_get_cookiejarr   r_   openZ_calculate_timeoutrM   r   r}   r   r@   rA   HTTPResponseresponserd   _closerclose_calledr   strURLErrorr   r   SocksProxyErrorr   r   r   
InvalidURL
ValueErrorr   r   )r3   rc   r8   Z
urllib_reqr   r   rZ   r   r*   r*   r+   _send~  s@    

zUrllibRH._send)N)ro   rp   rq   r   Z_SUPPORTED_PROXY_SCHEMESr   ZNO_PROXYZ	ALL_PROXYZ_SUPPORTED_FEATURESZRH_NAMEr0   r   r   r   rv   r*   r*   r5   r+   r   N  s   
r   )NNNN)G
__future__r   rD   http.clientr@   re   r   urllib.errorrb   urllib.parseurllib.requesturllib.responserJ   r   r   r   r   r   r   r	   Z_helperr   r   r   r   r   r   r   commonr   r   r   r   
exceptionsr   r   r   r   r   r   r   Zdependenciesr   socksr   utilsr   Zutils.networkingr    r   rM   r   r   r   r,   rc   AbstractHTTPHandlerr-   r:   r   r   BaseHandlerr   r   r   r   rU   r   r   r   r   r*   r*   r*   r+   <module>   sF   $
$	$	

t'

