o
    Qœ_ºk  ã                   @   s°  d dl mZ d dlmZmZ d dlmZmZmZm	Z	m
Z
mZ d dlmZ d dlmZmZ d dlmZ d dlmZmZ d dlmZmZmZmZ d d	lmZ 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( d dl)Z*d dl+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1 d dl2m3Z3 d dl+Z+e+j4r§d dl+m5Z5m6Z6m7Z7 G dd„ deƒZ8G dd„ deƒZ9G dd„ deƒZ:G dd„ dej;ƒZ<e=dkrÖe >e:¡ e	ƒ  dS dS )é    )Ú_unicode)ÚgenÚversion)ÚHTTPResponseÚ	HTTPErrorÚAsyncHTTPClientÚmainÚ_RequestProxyÚHTTPRequest)Úhttputil)ÚHTTP1ConnectionÚHTTP1ConnectionParameters)ÚIOLoop)ÚStreamClosedErrorÚIOStream)ÚResolverÚOverrideResolverÚ_client_ssl_defaultsÚis_valid_ip)Úgen_log)Ú	TCPClientN)ÚBytesIO)ÚDictÚAnyÚCallableÚOptionalÚTypeÚUnion)ÚTracebackType)ÚDequeÚTupleÚListc                       ó8   e Zd ZdZdeddf‡ fdd„Zdefdd„Z‡  ZS )	ÚHTTPTimeoutErrorzÃError raised by SimpleAsyncHTTPClient on timeout.

    For historical reasons, this is a subclass of `.HTTPClientError`
    which simulates a response code of 599.

    .. versionadded:: 5.1
    ÚmessageÚreturnNc                    ó   t ƒ jd|d� d S ©NéW  ©r$   ©ÚsuperÚ__init__©Úselfr$   ©Ú	__class__© ú;/usr/lib/python3/dist-packages/tornado/simple_httpclient.pyr,   5   ó   zHTTPTimeoutError.__init__c                 C   ó
   | j pdS )NÚTimeoutr)   ©r.   r1   r1   r2   Ú__str__8   ó   
zHTTPTimeoutError.__str__©Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ústrr,   r7   Ú__classcell__r1   r1   r/   r2   r#   ,   s    r#   c                       r"   )	ÚHTTPStreamClosedErroraZ  Error raised by SimpleAsyncHTTPClient when the underlying stream is closed.

    When a more specific exception is available (such as `ConnectionResetError`),
    it may be raised instead of this one.

    For historical reasons, this is a subclass of `.HTTPClientError`
    which simulates a response code of 599.

    .. versionadded:: 5.1
    r$   r%   Nc                    r&   r'   r*   r-   r/   r1   r2   r,   H   r3   zHTTPStreamClosedError.__init__c                 C   r4   )NúStream closedr)   r6   r1   r1   r2   r7   K   r8   zHTTPStreamClosedError.__str__r9   r1   r1   r/   r2   r@   <   s    r@   c                       s(  e Zd ZdZ							d%dedeeeef  dedee d	eeee	f  d
ee dee ddf‡ fdd„Z
d&‡ fdd„Zdedeegdf ddfdd„Zd&dd„Zdefdd„Zdedeg df deegdf ddfdd„Zdeddfdd„Zdeddfd d!„Zd'ded"ee ddfd#d$„Z‡  ZS )(ÚSimpleAsyncHTTPClientai  Non-blocking HTTP client with no external dependencies.

    This class implements an HTTP 1.1 client on top of Tornado's IOStreams.
    Some features found in the curl-based AsyncHTTPClient are not yet
    supported.  In particular, proxies are not supported, connections
    are not reused, and callers cannot select the network interface to be
    used.
    é
   Né  @Úmax_clientsÚhostname_mappingÚmax_buffer_sizeÚresolverÚdefaultsÚmax_header_sizeÚmax_body_sizer%   c                    s†   t ƒ j|d� || _t ¡ | _i | _i | _|| _|| _	|| _
|r'|| _d| _ntƒ | _d| _|dur:t| j|d�| _t| jd�| _dS )a  Creates a AsyncHTTPClient.

        Only a single AsyncHTTPClient instance exists per IOLoop
        in order to provide limitations on the number of pending connections.
        ``force_instance=True`` may be used to suppress this behavior.

        Note that because of this implicit reuse, unless ``force_instance``
        is used, only the first call to the constructor actually uses
        its arguments. It is recommended to use the ``configure`` method
        instead of the constructor to ensure that arguments take effect.

        ``max_clients`` is the number of concurrent requests that can be
        in progress; when this limit is reached additional requests will be
        queued. Note that time spent waiting in this queue still counts
        against the ``request_timeout``.

        ``hostname_mapping`` is a dictionary mapping hostnames to IP addresses.
        It can be used to make local DNS changes when modifying system-wide
        settings like ``/etc/hosts`` is not possible or desirable (e.g. in
        unittests).

        ``max_buffer_size`` (default 100MB) is the number of bytes
        that can be read into memory at once. ``max_body_size``
        (defaults to ``max_buffer_size``) is the largest response body
        that the client will accept.  Without a
        ``streaming_callback``, the smaller of these two limits
        applies; with a ``streaming_callback`` only ``max_body_size``
        does.

        .. versionchanged:: 4.2
           Added the ``max_body_size`` argument.
        )rI   FTN)rH   Úmapping)rH   )r+   Ú
initializerE   ÚcollectionsÚdequeÚqueueÚactiveÚwaitingrG   rJ   rK   rH   Úown_resolverr   r   r   Ú
tcp_client)r.   rE   rF   rG   rH   rI   rJ   rK   r/   r1   r2   rM   Y   s*   *ÿÿÿÿz SimpleAsyncHTTPClient.initializec                    s(   t ƒ  ¡  | jr| j ¡  | j ¡  d S ©N)r+   ÚcloserS   rH   rT   r6   r/   r1   r2   rV   Ÿ   s   

zSimpleAsyncHTTPClient.closeÚrequestÚcallbackc                 C   sÎ   t ƒ }| j |||f¡ |jd usJ ‚|jd usJ ‚d }t| jƒ| jkrEt|j|jƒp0|jp0|j}|rE| j	 
| j	 ¡ | t | j|d¡¡}|||f| j|< |  ¡  | jret dt| jƒt| jƒf ¡ d S d S )Nzin request queuezImax_clients limit reached, request queued. %d active, %d queued requests.)ÚobjectrP   ÚappendÚconnect_timeoutÚrequest_timeoutÚlenrQ   rE   ÚminÚio_loopÚadd_timeoutÚtimeÚ	functoolsÚpartialÚ_on_timeoutrR   Ú_process_queuer   Údebug)r.   rW   rX   ÚkeyÚtimeout_handleÚtimeoutr1   r1   r2   Ú
fetch_impl¥   s2   ÿýþÿÿÿz SimpleAsyncHTTPClient.fetch_implc                 C   sŒ   | j r@t| jƒ| jk rB| j  ¡ \}}}|| jvrq |  |¡ ||f| j|< t | j	|¡}|  
|||¡ | j rDt| jƒ| jk sd S d S d S d S rU   )rP   r]   rQ   rE   ÚpopleftrR   Ú_remove_timeoutrb   rc   Ú_release_fetchÚ_handle_request)r.   rg   rW   rX   Úrelease_callbackr1   r1   r2   re   À   s   

&ùz$SimpleAsyncHTTPClient._process_queuec                 C   s   t S rU   )Ú_HTTPConnectionr6   r1   r1   r2   Ú_connection_classÊ   s   z'SimpleAsyncHTTPClient._connection_classro   Úfinal_callbackc              	   C   s&   |   ¡ | |||| j| j| j| jƒ d S rU   )rq   rG   rT   rJ   rK   )r.   rW   ro   rr   r1   r1   r2   rn   Í   s   øz%SimpleAsyncHTTPClient._handle_requestrg   c                 C   s   | j |= |  ¡  d S rU   )rQ   re   )r.   rg   r1   r1   r2   rm   Þ   s   z$SimpleAsyncHTTPClient._release_fetchc                 C   s>   || j v r| j | \}}}|d ur| j |¡ | j |= d S d S rU   )rR   r_   Úremove_timeout)r.   rg   rW   rX   rh   r1   r1   r2   rl   â   s   
üz%SimpleAsyncHTTPClient._remove_timeoutÚinfoc                 C   sn   | j | \}}}| j |||f¡ |rd |¡nd}t|dt|ƒ| j ¡ |j d�}| j 	||¡ | j |= dS )zâTimeout callback of request.

        Construct a timeout HTTPResponse when a timeout occurs.

        :arg object key: A simple object to mark the request.
        :info string key: More detailed timeout information.
        úTimeout {0}r5   r(   )ÚerrorÚrequest_timeN)
rR   rP   ÚremoveÚformatr   r#   r_   ra   Ú
start_timeÚadd_callback)r.   rg   rt   rW   rX   rh   Úerror_messageÚtimeout_responser1   r1   r2   rd   é   s   üz!SimpleAsyncHTTPClient._on_timeout)rC   NrD   NNNN©r%   NrU   )r:   r;   r<   r=   Úintr   r   r>   r   r   rM   rV   r
   r   r   rj   re   Útyperq   rn   rY   rm   rl   rd   r?   r1   r1   r/   r2   rB   O   s`    øþýüûúùø	÷Fÿÿ
þ

þ
ýü
û$rB   c                   @   sr  e Zd Zeg d¢ƒZdee dedeg df dee	gdf de
ded	e
d
e
ddfdd„Zd8dd„Zdededeeef ejf fdd„Zd9dee ddfdd„Zd8dd„Zdedefdd„Zdeddfdd„Zd8dd„Zd e	ddfd!d"„Zd#d$d%ee d&ee defd'd(„Z d8d)d*„Z!d+ee"j#e"j$f d,e"j%ddfd-d.„Z&defd/d0„Z'd8d1d2„Z(d8d3d4„Z)d5e*ddfd6d7„Z+dS ):rp   )ÚGETÚHEADÚPOSTÚPUTÚDELETEÚPATCHÚOPTIONSÚclientrW   ro   Nrr   rG   rT   rJ   rK   r%   c	           	      C   s–   t  ¡ | _| j ¡ | _t ¡ | _|| _|| _|| _|| _	|| _
|| _|| _|| _d | _d | _g | _d | _d | _d | _t  ¡  t |  ¡ ¡dd„ ¡ d S )Nc                 S   s   |   ¡ S rU   ©Úresult©Úfr1   r1   r2   Ú<lambda>"  s    z*_HTTPConnection.__init__.<locals>.<lambda>)r   Úcurrentr_   ra   rz   Ústart_wall_timerˆ   rW   ro   rr   rG   rT   rJ   rK   ÚcodeÚheadersÚchunksÚ_decompressorÚ_timeoutÚ	_sockaddrÚ
add_futurer   Úconvert_yieldedÚrun)	r.   rˆ   rW   ro   rr   rG   rT   rJ   rK   r1   r1   r2   r,     s(   

ÿz_HTTPConnection.__init__c                 Ã   sþ  ��zht j t| jjƒ¡| _| jjdvrtd| jj ƒ‚| jj	}d|v r,| 
d¡\}}}t |¡\}}|d u rA| jjdkr?dnd}t d|¡rM|dd	… }|| _| jjd
u rZtj}ntj}|  | jj¡}d }| jjr~t| jjƒru| jj}n	td| jjf ƒ‚t| jj| jjƒpŽ| jjpŽ| jj}	|	r¡| j | j|	 t | jd¡¡| _ | j!j"||||| j#|d�I d H }
| j$d u r½|
 %¡  W d S |
| _&| j& '| j(¡ |  )¡  | j$d u rÓW d S | jjré| j | j| jj t | jd¡¡| _ | jj*| j+vrü| jj,süt-d| jj* ƒ‚dD ]}t.| j|d ƒ�rt/d| ƒ‚qþd| jj0v�rd| jj0d< d| jj0v�r@d| jj	v �r8| jj	 
d¡d	 | jj0d< n| jj	| jj0d< d\}}| jj1d u�rU| jj1| jj2}}n| jj3d u�rg| jj3}| jj4�pfd}|d u�r’|d u�ssJ ‚| jj5dv�r�td| jj5ƒ‚dtt6 7t 8||¡¡ƒ | jj0d< | jj9�r | jj9| jj0d< n| jj0 :d¡d u �r³d ;t<¡| jj0d< | jj,�sæ| jj*dv }| jj=d u�pÊ| jj>d u}|�rÑ|�r×|�ræ|�sætd|�rÞdnd| jj*f ƒ‚| jj?�rñd | jj0d!< | jj=d u�rt@tA| jj=ƒƒ| jj0d"< | jj*d#k�rd$| jj0v�rd%| jj0d$< | jjB�r#d&| jj0d'< | jjC�p)d(| jjD�r4d)| jjD nd }|  E|
¡| _Ft G| jj*|d¡}| jF H|| jj0¡ | jj?�r`| jF I| ¡I d H  W d S |  Jd*¡I d H  W d S  tK�y~   | jLtM N¡ Ž �s{‚ Y d S w )+N)ÚhttpÚhttpszUnsupported url scheme: %sú@rš   i»  éP   z^\[.*\]$é   éÿÿÿÿFz?Unrecognized IPv4 or IPv6 address for network_interface, got %rzwhile connecting)ÚafÚssl_optionsrG   Ú	source_ipzduring requestzunknown method %s)Ú
proxy_hostÚ
proxy_portÚproxy_usernameÚproxy_passwordÚproxy_auth_modez%s not supportedÚ
ConnectionrV   ÚHost)NNÚ )NÚbasiczunsupported auth_mode %szBasic ÚAuthorizationz
User-Agentz
Tornado/{})rƒ   r†   r„   zLBody must %sbe None for method %s (unless allow_nonstandard_methods is true)znot z100-continueÚExpectúContent-Lengthrƒ   úContent-Typez!application/x-www-form-urlencodedÚgzipzAccept-Encodingú/ú?T)OÚurllibÚparseÚurlsplitr   rW   ÚurlÚparsedÚschemeÚ
ValueErrorÚnetlocÚ
rpartitionr   Úsplit_host_and_portÚreÚmatchÚparsed_hostnameÚ
allow_ipv6ÚsocketÚAF_INETÚ	AF_UNSPECÚ_get_ssl_optionsÚnetwork_interfacer   r^   r[   r\   r_   r`   rz   rb   rc   rd   r”   rT   ÚconnectrG   rr   rV   ÚstreamÚset_close_callbackÚon_connection_closerl   ÚmethodÚ_SUPPORTED_METHODSÚallow_nonstandard_methodsÚKeyErrorÚgetattrÚNotImplementedErrorr‘   ÚusernameÚpasswordÚauth_usernameÚauth_passwordÚ	auth_modeÚbase64Ú	b64encodeÚencode_username_passwordÚ
user_agentÚgetry   r   ÚbodyÚbody_producerÚexpect_100_continuer>   r]   Údecompress_responseÚpathÚqueryÚ_create_connectionÚ
connectionÚRequestStartLineÚwrite_headersÚread_responseÚ_write_bodyÚ	ExceptionÚ_handle_exceptionÚsysÚexc_info)r.   r¹   ÚuserpassÚ_ÚhostÚportrŸ   r    r¡   ri   rÆ   rg   rÏ   rÐ   Úbody_expectedÚbody_presentÚreq_pathÚ
start_liner1   r1   r2   r˜   %  s  €
ÿÿÿýþú
	
þÿÿÿ

ÿÿ


þÿÿþÿ
þÿ
ÿ
ÿÿz_HTTPConnection.runr·   c                 C   sº   |dkr[| j jd ur| j jS | j jr&| j jd u r&| j jd u r&| j jd u r&tS tjtj	j
| j jd�}| j js<d|_tj|_| j jd urL| | j j| j j¡ ttdƒrY| jtjO  _|S d S )Nrš   )ÚcafileFÚOP_NO_COMPRESSION)rW   r    Úvalidate_certÚca_certsÚclient_certÚ
client_keyr   ÚsslÚcreate_default_contextÚPurposeÚSERVER_AUTHÚcheck_hostnameÚ	CERT_NONEÚverify_modeÚload_cert_chainÚhasattrÚoptionsrò   )r.   r·   Ússl_ctxr1   r1   r2   rÃ   Á  s.   ÿÿÿ
z _HTTPConnection._get_ssl_optionsrt   c                 C   s<   d| _ |r
d |¡nd}| jdur|  tt|ƒd¡ dS dS )z¯Timeout callback of _HTTPConnection instance.

        Raise a `HTTPTimeoutError` when a timeout occurs.

        :info string key: More detailed timeout information.
        Nru   r5   )r”   ry   rr   ræ   r#   )r.   rt   r|   r1   r1   r2   rd   à  s   

ÿÿz_HTTPConnection._on_timeoutc                 C   s&   | j d ur| j | j ¡ d | _ d S d S rU   )r”   r_   rs   r6   r1   r1   r2   rl   î  s   

þz_HTTPConnection._remove_timeoutrÆ   c              	   C   s6   |  d¡ t|dtd| j| jt| jjƒd�| jƒ}|S )NT)Úno_keep_aliverJ   rK   Ú
decompress)	Úset_nodelayr   r   rJ   rK   ÚboolrW   rÜ   r•   )r.   rÆ   rà   r1   r1   r2   rß   ó  s   

ü÷z"_HTTPConnection._create_connectionÚ
start_readc                 Ã   sž   �| j jd ur| j | j j¡ n| j jd ur'| j  | jj¡}|d ur'|I d H  | j ¡  |rMz| j | ¡I d H  W d S  tyL   | jt	 
¡ Ž sI‚ Y d S w d S rU   )rW   rÙ   rà   ÚwriterÚ   Úfinishrã   r   ræ   rç   rè   )r.   r  Úfutr1   r1   r2   rä     s"   €

ÿÿýz_HTTPConnection._write_bodyc                 C   s$   | j d ur| j }d | _ |ƒ  d S d S rU   )ro   )r.   ro   r1   r1   r2   Ú_release  s
   

ýz_HTTPConnection._releaseÚresponsec                 C   s4   |   ¡  | jd ur| j}d | _| j ||¡ d S d S rU   )r
  rr   r_   r{   )r.   r  rr   r1   r1   r2   Ú_run_callback  s   
ýz_HTTPConnection._run_callbackÚtypzOptional[Type[BaseException]]ÚvalueÚtbc              	   C   s|   | j r9|  ¡  t|tƒr|jd u rtdƒ}n|j}|  t| jd|| j	 
¡ | j | jd�¡ t| dƒr7| j ¡  dS t|tƒS )NrA   r(   )rv   rw   rz   rÆ   T)rr   rl   Ú
isinstancer   Ú
real_errorr@   r  r   rW   r_   ra   rz   r�   rÿ   rÆ   rV   )r.   r  r  r  r1   r1   r2   ræ     s&   


ûÿ



z!_HTTPConnection._handle_exceptionc                 C   sN   | j d ur%d}| jjr| jj‚zt|ƒ‚ ty$   | jt ¡ Ž  Y d S w d S )NzConnection closed)rr   rÆ   rv   r@   ræ   rç   rè   r-   r1   r1   r2   rÈ   B  s   
ÿúz#_HTTPConnection.on_connection_closeÚ
first_liner‘   c                 Ã   s²   �t |tjƒs	J ‚| jjr|jdkr|  d¡I d H  d S |j| _|j| _|| _|  	¡ r-d S | jj
d urW| j 
d| ¡ | j ¡ D ]\}}| j 
d||f ¡ q@| j 
d¡ d S d S )Néd   Fz
%s %s %s
z%s: %s
z
)r  r   ÚResponseStartLinerW   rÛ   r�   rä   Úreasonr‘   Ú_should_follow_redirectÚheader_callbackÚget_all)r.   r  r‘   ÚkÚvr1   r1   r2   Úheaders_receivedL  s    €ûz _HTTPConnection.headers_receivedc                 C   sL   | j jr$| j jd usJ ‚| jdv o#| j jdko#| jd uo#| j d¡d uS dS )N)é-  é.  é/  i3  i4  r   ÚLocationF)rW   Úfollow_redirectsÚmax_redirectsr�   r‘   rØ   r6   r1   r1   r2   r  c  s   

ÿþüz'_HTTPConnection._should_follow_redirectc              
      s–  | j d usJ ‚d | j¡}|  ¡  t| jd| jƒ}|  ¡ r™t| jtƒs%J ‚t	 	| jj¡}t
j | jj| jd ¡|_| jjd |_|jd= | j dkrO| jjdksZ| j dv ru| jjd	krud
|_d |_dD ]}z| jj|= W qb tyt   Y qbw ||_| j‰ d | _|  ¡  | jj|dd�}| ‡ fdd„¡ |  ¡  d S | jjr¡tƒ }nt|ƒ}t|| j t| dd ƒ| j| j ¡ | j | j || jjd�}|  !|¡ |  ¡  d S )Nó    Úoriginal_requestr  r�   r¨   r  r‚   )r  r  rƒ   r�   )r­   r®   zContent-EncodingzTransfer-EncodingF)Úraise_errorc                    s   ˆ |   ¡ ƒS rU   r‰   r‹   ©rr   r1   r2   r�   ˜  s    z(_HTTPConnection.finish.<locals>.<lambda>r  )r  r‘   rw   rz   ÚbufferÚeffective_url)"r�   Újoinr’   rl   rÍ   rW   r  r  r	   Úcopyr²   r³   Úurljoinrµ   r‘   r!  rÉ   rÙ   rÌ   r#  rr   r
  rˆ   ÚfetchÚadd_done_callbackÚ_on_end_requestÚstreaming_callbackr   r   r_   ra   rz   r�   r  )r.   Údatar#  Únew_requestÚhr	  r&  r  r1   r%  r2   r  n  sZ   ÿ
ÿ
ø

z_HTTPConnection.finishc                 C   s   | j  ¡  d S rU   )rÆ   rV   r6   r1   r1   r2   r-  ¬  s   z_HTTPConnection._on_end_requestÚchunkc                 C   s8   |   ¡ rd S | jjd ur| j |¡ d S | j |¡ d S rU   )r  rW   r.  r’   rZ   )r.   r2  r1   r1   r2   Údata_received¯  s
   z_HTTPConnection.data_receivedr~   rU   ),r:   r;   r<   ÚsetrÊ   r   rB   r
   r   r   r   r   r,   r˜   r>   r   r   r   r÷   Ú
SSLContextrÃ   rd   rl   r   r   rß   r  rä   r
  r  ÚBaseExceptionr   ræ   rÈ   r   r  rá   ÚHTTPHeadersr  r  r  r-  Úbytesr3  r1   r1   r1   r2   rp   ÿ   sr    ÿþý
üûúùø	÷

ö
! ÿ
þ

þýü
û
$
þý
ü

>rp   Ú__main__)?Útornado.escaper   Útornador   r   Útornado.httpclientr   r   r   r   r	   r
   r   Útornado.http1connectionr   r   Útornado.ioloopr   Útornado.iostreamr   r   Útornado.netutilr   r   r   r   Útornado.logr   Útornado.tcpclientr   rÔ   rN   r)  rb   r¼   rÀ   r÷   rç   ra   Úior   Úurllib.parser²   Útypingr   r   r   r   r   r   Útypesr   ÚTYPE_CHECKINGr   r    r!   r#   r@   rB   ÚHTTPMessageDelegaterp   r:   Ú	configurer1   r1   r1   r2   Ú<module>   sL       1   =

þ