
    i                        U d dl Zd dlmZ d dlZd dlZd dlZd dlmZ d dl	Z	d dl
Z
d dlmZ d dlmZmZmZmZ d dlmZ eeeef   z  eeeef   z  Zeedz  edz  eef   Z ej2                  d      Zdaej6                  ed<   i Zeeef   ed	<   d
efdZ	 d(dedz  dedz  dededef
dZ  G d de
jB                        Z" G d de      Z#dedededede
jH                  de%fdZ&dededededz  de
jH                  de%fdZ'dededede%de%d e(d!eeef   dede%d"e%d#ejR                  d$ejT                  f   dz  de
jV                  fd%Z,dej6                  fd&Z-d' Z. e.        y))    N)TracebackType)
SSLContext)AsyncProxyTransport)parse_proxy_urlProxyConnectionErrorProxyTimeoutError
ProxyError)loggerzsearx.network.clientLOOPSSLCONTEXTSssl_contextc                     | j                         D cg c]  }|d   	 }}|dd |dd }}t        j                  |       | j                  dj	                  ||z                yc c}w )a  Shuffle httpx's default ciphers of a SSL context randomly.

    From `What Is TLS Fingerprint and How to Bypass It`_

    > When implementing TLS fingerprinting, servers can't operate based on a
    > locked-in whitelist database of fingerprints.  New fingerprints appear
    > when web clients or TLS libraries release new versions. So, they have to
    > live off a blocklist database instead.
    > ...
    > It's safe to leave the first three as is but shuffle the remaining ciphers
    > and you can bypass the TLS fingerprint check.

    .. _What Is TLS Fingerprint and How to Bypass It:
       https://www.zenrows.com/blog/what-is-tls-fingerprint#how-to-bypass-tls-fingerprinting

    nameN   :)get_ciphersrandomshuffleset_ciphersjoin)r   cipherc_listsc_lists       %/root/searxng/searx/network/client.pyshuffle_ciphersr      sg    " ,7+B+B+DEfVnEFERaj&*VG
NN6CHHWv%567 Fs   A$	proxy_urlcertverify	trust_envreturnc                     | |||f}|t         vrt        j                  |||      t         |<   t        t         |          t         |   S N)r   httpxcreate_ssl_contextr   )r   r   r   r   keys        r   get_sslcontextsr&   3   sK     (vyAC
+ 33FD)LCK$%s    c            	       |    e Zd ZdZd Zdej                  fdZddZd Z		 	 	 dd	e
e   dz  d
edz  dedz  ddfdZy)AsyncHTTPTransportNoHttpa  Block HTTP request

    The constructor is blank because httpx.AsyncHTTPTransport.__init__ creates an SSLContext unconditionally:
    https://github.com/encode/httpx/blob/0f61aa58d66680c239ce43c8cdd453e7dc532bfc/httpx/_transports/default.py#L271

    Each SSLContext consumes more than 500kb of memory, since there is about one network per engine.

    In consequence, this class overrides all public methods

    For reference: https://github.com/encode/httpx/issues/2298
    c                      y r"    )selfargskwargss      r   __init__z!AsyncHTTPTransportNoHttp.__init__J   s     	r'   requestc                 4   K   t        j                  d      w)NzHTTP protocol is disabled)r#   UnsupportedProtocol)r,   r0   s     r   handle_async_requestz-AsyncHTTPTransportNoHttp.handle_async_requestO   s     ''(CDDs   r    Nc                    K   y wr"   r+   r,   s    r   aclosezAsyncHTTPTransportNoHttp.acloseR   s	        c                    K   | S wr"   r+   r5   s    r   
__aenter__z#AsyncHTTPTransportNoHttp.__aenter__U   s     s   exc_type	exc_value	tracebackc                    K   y wr"   r+   )r,   r:   r;   r<   s       r   	__aexit__z"AsyncHTTPTransportNoHttp.__aexit__X   s      	r7   )r    N)NNN)__name__
__module____qualname____doc__r/   r#   Requestr3   r6   r9   typeBaseExceptionr   r>   r+   r'   r   r)   r)   =   sr    

E%-- E
 04*.*.	}%, !4' !4'	
 
r'   r)   c                   <     e Zd ZdZdej
                  f fdZ xZS )AsyncProxyTransportFixedzhFix httpx_socks.AsyncProxyTransport

    Map python_socks exceptions to httpx.ProxyError exceptions
    r0   c                   K   	 t         |   |       d {   S 7 # t        $ r3}t        j                  dt        |j                        z   |      |d }~wt        $ r6}t        j                  dt        |j                  d         z   |      |d }~wt        $ r6}t        j                  dt        |j                  d         z   |      |d }~ww xY ww)NzProxyConnectionError: )r0   zProxyTimeoutError: r   zProxyError: )	superr3   r   r#   r	   strstrerrorr   r-   )r,   r0   e	__class__s      r   r3   z-AsyncProxyTransportFixed.handle_async_requestg   s     	\5g>>>># 	g""#;c!**o#MW^_eff  	c""#83qvvay>#ISZ[abb 	\"">Cq	N#BGTZ[[	\sH   C  C 	C.AC!1BC1CCC)r?   r@   rA   rB   r#   rC   r3   __classcell__)rM   s   @r   rG   rG   a   s     
\%-- \ \r'   rG   http2local_addresslimitretriesc                     d}d}|j                  |      rd|t        |      d  z   }d}t        |      \  }}	}
}}| du rt        |d | d      n| }t	        ||	|
|||t               |||||      S )NF
socks5h://	socks5://T)
proxy_type
proxy_host
proxy_portusernamepasswordrdnsloopr   rO   rP   limitsrR   )
startswithlenr   r&   rG   get_loop)r   rO   rP   r   rQ   rR   r[   socks5hrV   rW   rX   proxy_usernameproxy_password_verifys                 r   get_transport_for_socks_proxyre   r   s     DGG$)CLN";;	IXYbIcFJ
J@F$oivt<TZG#Z# r'   c                     | du rt        d d | d      n| }t        j                  ||||rt        j                  j	                  |      nd ||      S )NT)r   rO   r]   proxyrP   rR   )r&   r#   AsyncHTTPTransport_configProxy)r   rO   rP   r   rQ   rR   rd   s          r   get_transportrk      sU     <BT>odD&$7vG##09emm!!),t# r'   enable_httpenable_http2max_connectionsmax_keepalive_connectionskeepalive_expiryproxiesmax_redirectshook_log_response.c           	         t        j                  |||      }i }i }|j                         D ]s  \  }}| s|j                  d      r|j                  d      s"|j                  d      s|j                  d      rt	        ||||||      ||<   at        ||||||      ||<   u | st               |d<   t        |||d ||      }d }|
rd|
gi}t        j                  |||	|      S )N)rn   ro   rp   zhttp://z	socks4://rU   rT   response)	transportmountsrr   event_hooks)r#   Limitsitemsr^   re   rk   r)   AsyncClient)rl   r   rm   rn   ro   rp   rq   rP   rR   rr   rs   rQ   rw   patternr   rv   rx   s                    r   
new_clientr}      s    LL'";)E F/1F%mmo lw11)<,	0D0D[0QU^UiUijvUw;mYwF7O ,FL-QZ\acjkF7Ol 46yflM4PWXIK!$5#67#	 r'   c                      t         S r"   )r   r+   r'   r   r`   r`      s    Kr'   c                      dD ]4  } t        j                  |       j                  t         j                         6 d }t	        j
                  |dd      }|j                          y )N)r#   zhttpcore.proxyzhttpcore.connectionzhttpcore.http11zhttpcore.http2zhpack.hpackzhpack.tablec                  T    t        j                         at        j                          y r"   )asyncionew_event_loopr   run_foreverr+   r'   r   loop_threadzinit.<locals>.loop_thread   s    %%'r'   asyncio_loopT)targetr   daemon)logging	getLoggersetLevelWARNING	threadingThreadstart)logger_namer   threads      r   initr      s_     	A 	+&//@	A
 F
 LLNr'   )NNTT)/typingttypesr   r   r   r   sslr   r   r#   httpx_socksr   python_socksr   r   r   r	   searxr
   rJ   tuple	CertTypesboolSslContextKeyTypegetChildr   AbstractEventLoop__annotations__r   dictr   r&   rh   r)   rG   ry   intre   rk   floatCallableAnyr{   r}   r`   r   r+   r'   r   <module>r      sA           + ] ] %S/!E#sC-$88	#*i$&6dBC 	/	0"&g &35T#Z/0 58 80 imTz(1D(8IMae!u77 !H\2 \".1>AJO,,ad>.1>ADjQVQ]Q]hk.. . 	.
 .  #. . #s(^. . . . zz#quu*-4. .b'++ 6 r'   