B
    hk                 @   s  d dl mZ d dl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.m/Z/m0Z0 d dl1m2Z2 d dl*Z*e*j3rLd dl*m4Z4m5Z5m6Z6 G dd deZ7G dd deZ8G dd deZ9G dd dej:Z;e<dkre=e9 e  dS )    )_unicode)gen)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                   s6   e Zd ZdZedd fddZedddZ  ZS )	HTTPTimeoutErrorzError raised by SimpleAsyncHTTPClient on timeout.

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

    .. versionadded:: 5.1
    N)messagereturnc                s   t t| jd|d d S )NiW  )r"   )superr!   __init__)selfr"   )	__class__ VC:\Users\sanjo\AppData\Local\Qlobot\Launcher\ext_packages\tornado\simple_httpclient.pyr%   5   s    zHTTPTimeoutError.__init__)r#   c             C   s
   | j pdS )NTimeout)r"   )r&   r(   r(   r)   __str__8   s    zHTTPTimeoutError.__str__)__name__
__module____qualname____doc__strr%   r+   __classcell__r(   r(   )r'   r)   r!   ,   s   r!   c                   s6   e Zd ZdZedd fddZedddZ  ZS )	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
    N)r"   r#   c                s   t t| jd|d d S )NiW  )r"   )r$   r2   r%   )r&   r"   )r'   r(   r)   r%   H   s    zHTTPStreamClosedError.__init__)r#   c             C   s
   | j pdS )NzStream closed)r"   )r&   r(   r(   r)   r+   K   s    zHTTPStreamClosedError.__str__)r,   r-   r.   r/   r0   r%   r+   r1   r(   r(   )r'   r)   r2   <   s   
r2   c            
       s   e Zd ZdZdeeeef eeeeef eedd fddZ	dd fd	d
Z
eeegdf ddddZddddZedddZeeg df eegdf ddddZeddddZeddddZdeedd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 t| j|d || _t | _i | _i | _|| _	|| _
|| _|rR|| _d| _nt | _d| _|dk	rxt| 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.
        )r:   FTN)r9   mapping)r9   )r$   r3   
initializer6   collectionsdequequeueactivewaitingr8   r;   r<   r9   own_resolverr   r   r   
tcp_client)r&   r6   r7   r8   r9   r:   r;   r<   )r'   r(   r)   r>   Y   s"    *
z SimpleAsyncHTTPClient.initialize)r#   c                s,   t t|   | jr| j  | j  d S )N)r$   r3   closerD   r9   rE   )r&   )r'   r(   r)   rF      s    
zSimpleAsyncHTTPClient.close)requestcallbackr#   c             C   s   t  }| j|||f t| j| jk st|jd k	s6t|jd k	sDt| j	
| j	 t|j|j t| j|d}nd }|||f| j|< |   | jrtdt| jt| jf  d S )Nzin request queuezImax_clients limit reached, request queued. %d active, %d queued requests.)objectrA   appendlenrB   r6   connect_timeoutAssertionErrorrequest_timeoutio_loopadd_timeouttimemin	functoolspartial_on_timeoutrC   _process_queuer   debug)r&   rG   rH   keytimeout_handler(   r(   r)   
fetch_impl   s     z SimpleAsyncHTTPClient.fetch_implc             C   sp   xj| j rjt| j| jk rj| j  \}}}|| jkr4q| | ||f| j|< t| j	|}| 
||| qW d S )N)rA   rK   rB   r6   popleftrC   _remove_timeoutrS   rT   _release_fetch_handle_request)r&   rX   rG   rH   release_callbackr(   r(   r)   rV      s    

z$SimpleAsyncHTTPClient._process_queuec             C   s   t S )N)_HTTPConnection)r&   r(   r(   r)   _connection_class   s    z'SimpleAsyncHTTPClient._connection_class)rG   r_   final_callbackr#   c          	   C   s&   |   | |||| j| j| j| j d S )N)ra   r8   rE   r;   r<   )r&   rG   r_   rb   r(   r(   r)   r^      s    z%SimpleAsyncHTTPClient._handle_request)rX   r#   c             C   s   | j |= |   d S )N)rB   rV   )r&   rX   r(   r(   r)   r]      s    z$SimpleAsyncHTTPClient._release_fetchc             C   s:   || j kr6| j | \}}}|d k	r.| j| | j |= d S )N)rC   rO   remove_timeout)r&   rX   rG   rH   rY   r(   r(   r)   r\      s
    
z%SimpleAsyncHTTPClient._remove_timeout)rX   infor#   c             C   sn   | j | \}}}| j|||f |r0d|nd}t|dt|| j |j d}| j	|| | j |= dS )zTimeout 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.
        zTimeout {0}r*   iW  )errorrequest_timeN)
rC   rA   removeformatr   r!   rO   rQ   
start_timeadd_callback)r&   rX   rd   rG   rH   rY   error_messageZtimeout_responser(   r(   r)   rU      s    z!SimpleAsyncHTTPClient._on_timeout)r4   Nr5   NNNN)N)r,   r-   r.   r/   intr   r0   r   r   r>   rF   r	   r   r   rZ   rV   typera   r^   rI   r]   r\   rU   r1   r(   r(   )r'   r)   r3   O   s*          =

r3   c            
   @   sj  e Zd ZedddddddgZee eeg df ee	gdf e
ee
e
dd		d
dZddddZeedeeef ejf dddZd4eddddZddddZeedddZeddddZddddZe	ddd d!Zd"ee ee ed#d$d%Z ddd&d'Z!ee"j#e"j$f e"j%dd(d)d*Z&edd+d,Z'ddd-d.Z(ddd/d0Z)e*dd1d2d3Z+dS )5r`   GETHEADPOSTPUTDELETEPATCHOPTIONSN)	clientrG   r_   rb   r8   rE   r;   r<   r#   c	       	      C   s   t  | _| j | _t | _|| _|| _|| _|| _	|| _
|| _|| _|| _d | _d | _g | _d | _d | _d | _t  t|  dd  d S )Nc             S   s   |   S )N)result)fr(   r(   r)   <lambda>      z*_HTTPConnection.__init__.<locals>.<lambda>)r   currentrO   rQ   ri   start_wall_timeru   rG   r_   rb   r8   rE   r;   r<   codeheaderschunks_decompressor_timeout	_sockaddr
add_futurer   convert_yieldedrun)	r&   ru   rG   r_   rb   r8   rE   r;   r<   r(   r(   r)   r%      s&    

z_HTTPConnection.__init__)r#   c                s  yt jt| jj| _| jjdkr6td| jj | jj	}d|krV|
d\}}}t|\}}|d kr| jjdkr|dnd}td|r|dd	 }|| _| jjd
krtj}ntj}| | jj}d }| jjrt| jjr| jj}ntd| jjf t| jj| jj}	|	r| j| j|	 t| jd| _ | j!j"||||| j#|dI d H }
| j$d krj|
%  d S |
| _&| j&'| j( | )  | j$d krd S | jjr| j| j| jj t| jd| _ | jj*| j+kr| jj,st-d| jj* x*dD ]"}t.| j|d rt/d| qW d| jj0kr4d| jj0d< d| jj0kr|d| jj	krl| jj	
dd	 | jj0d< n| jj	| jj0d< d\}}| jj1d k	r| jj1| jj2 }}n$| jj3d k	r| jj3}| jj4pd}|d k	r |d k	st5| jj6dkrtd| jj6dtt78t9|| | jj0d< | jj:r:| jj:| jj0d< | jj,s| jj*dk}| jj;d k	ph| jj<d k	}|rv|r|r|std|rdnd| jj*f | jj=rd| jj0d < | jj;d k	rt>t?| jj;| jj0d!< | jj*d"krd#| jj0krd$| jj0d#< | jj@rd%| jj0d&< | jjAp&d'| jjBr<d(| jjB nd }| C|
| _DtE| jj*|d}| jDF|| jj0 | jj=r| jDG| I d H  n| Hd)I d H  W n( tIk
r   | jJtKL  sƂ Y nX d S )*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_optionsr8   	source_ipzduring requestzunknown method %s)
proxy_host
proxy_portproxy_usernameproxy_passwordproxy_auth_modez%s not supported
ConnectionrF   Host)NN )Nbasiczunsupported auth_mode %szBasic Authorizationz
User-Agent)rp   rs   rq   zLBody must %sbe None for method %s (unless allow_nonstandard_methods is true)znot z100-continueExpectzContent-Lengthrp   zContent-Typez!application/x-www-form-urlencodedgzipzAccept-Encoding/?T)Murllibparseurlsplitr   rG   urlparsedscheme
ValueErrornetloc
rpartitionr
   split_host_and_portrematchZparsed_hostname
allow_ipv6socketAF_INET	AF_UNSPEC_get_ssl_optionsnetwork_interfacer   rR   rL   rN   rO   rP   ri   rS   rT   rU   r   rE   connectr8   rb   rF   streamset_close_callbackon_connection_closer\   method_SUPPORTED_METHODSallow_nonstandard_methodsKeyErrorgetattrNotImplementedErrorr}   usernamepasswordauth_usernameauth_passwordrM   	auth_modebase64	b64encodeencode_username_password
user_agentbodybody_producerexpect_100_continuer0   rK   decompress_responsepathquery_create_connection
connectionRequestStartLinewrite_headersread_response_write_body	Exception_handle_exceptionsysexc_info)r&   r   Zuserpass_hostportr   r   r   timeoutr   rX   r   r   Zbody_expectedZbody_presentreq_path
start_liner(   r(   r)   r   !  s    








z_HTTPConnection.run)r   r#   c             C   s   |dkr| j jd k	r| j jS | j jrL| j jd krL| j jd krL| j jd krLtS tjtj	j
| j jd}| j jsxd|_tj|_| j jd k	r|| j j| j j ttdr| jtjO  _|S d S )Nr   )cafileFOP_NO_COMPRESSION)rG   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   Zssl_ctxr(   r(   r)   r     s(    
z _HTTPConnection._get_ssl_options)rd   r#   c             C   s8   d| _ |rd|nd}| jdk	r4| tt|d dS )zTimeout callback of _HTTPConnection instance.

        Raise a `HTTPTimeoutError` when a timeout occurs.

        :info string key: More detailed timeout information.
        NzTimeout {0}r*   )r   rh   rb   r   r!   )r&   rd   rk   r(   r(   r)   rU     s
    
z_HTTPConnection._on_timeoutc             C   s"   | j d k	r| j| j  d | _ d S )N)r   rO   rc   )r&   r(   r(   r)   r\     s    
z_HTTPConnection._remove_timeout)r   r#   c          	   C   s6   | d t|dtd| j| jt| jjd| j}|S )NT)no_keep_aliver;   r<   
decompress)	set_nodelayr   r   r;   r<   boolrG   r   r   )r&   r   r   r(   r(   r)   r     s    
z"_HTTPConnection._create_connection)
start_readr#   c                s   | j jd k	r| j| j j n.| j jd k	rL| j | jj}|d k	rL|I d H  | j  |ry| j| I d H  W n$ tk
r   | jt	
  s Y nX d S )N)rG   r   r   writer   finishr   r   r   r   r   )r&   r   futr(   r(   r)   r     s    

z_HTTPConnection._write_bodyc             C   s    | j d k	r| j }d | _ |  d S )N)r_   )r&   r_   r(   r(   r)   _release  s    
z_HTTPConnection._release)responser#   c             C   s0   |    | jd k	r,| j}d | _| j|| d S )N)r   rb   rO   rj   )r&   r   rb   r(   r(   r)   _run_callback  s
    
z_HTTPConnection._run_callbackzOptional[Type[BaseException]])typvaluetbr#   c          	   C   s   | j rr|   t|tr2|jd kr,td}n|j}| t| jd|| j	
 | j | jd t| drn| j  dS t|tS d S )NzStream closediW  )re   rf   ri   r   T)rb   r\   
isinstancer   
real_errorr2   r   r   rG   rO   rQ   ri   r{   r   r   rF   )r&   r   r   r   r(   r(   r)   r     s"    




z!_HTTPConnection._handle_exceptionc             C   sR   | j d k	rNd}| jjr| jjyt|W n" tk
rL   | jt   Y nX d S )NzConnection closed)rb   r   re   r2   r   r   r   )r&   r"   r(   r(   r)   r   <  s    
z#_HTTPConnection.on_connection_close)
first_liner}   r#   c                s   t |tjst| jjr6|jdkr6| dI d H  d S |j| _|j| _|| _	| 
 rXd S | jjd k	r| jd|  x*| j	 D ]\}}| jd||f  qW | jd d S )Nd   Fz
%s %s %s
z%s: %s
z
)r   r
   ResponseStartLinerM   rG   r   r|   r   reasonr}   _should_follow_redirectheader_callbackget_all)r&   r   r}   kvr(   r(   r)   headers_receivedF  s    z _HTTPConnection.headers_receivedc             C   sL   | j jrH| j jd k	st| jdkoF| j jdkoF| jd k	oF| jdd k	S dS )N)i-  i.  i/  i3  i4  r   LocationF)rG   follow_redirectsmax_redirectsrM   r|   r}   get)r&   r(   r(   r)   r   ]  s    

z'_HTTPConnection._should_follow_redirectc          
      s  | j d k	std| j}|   t| jd| j}|  r&t| jt	sLtt

| jj}tj| jj| jd |_| jjd |_|jd= | j dkr| jjdkrd|_d |_x0d	D ](}y| jj|= W q tk
r   Y qX qW ||_| j d | _|   | jj|d
d}| fdd |   d S | jjr8t }nt|}t|| j t| dd | j| j | j  | j!|| jjd}| "| |   d S )Nry   original_requestr  r   r   )i-  i.  i/  rp   rn   )zContent-LengthzContent-TypezContent-EncodingzTransfer-EncodingF)raise_errorc                s    |   S )N)rv   )rw   )rb   r(   r)   rx     ry   z(_HTTPConnection.finish.<locals>.<lambda>r   )r   r}   rf   ri   buffereffective_url)#r|   rM   joinr~   r\   r   rG   r   r   r   copyr   r   urljoinr   r}   r  r   r   r   r  rb   r   ru   fetchadd_done_callback_on_end_requeststreaming_callbackr   r   rO   rQ   ri   r{   r   )r&   datar  Znew_requesthr   r  r   r(   )rb   r)   r   h  sR    





z_HTTPConnection.finishc             C   s   | j   d S )N)r   rF   )r&   r(   r(   r)   r    s    z_HTTPConnection._on_end_request)chunkr#   c             C   s6   |   rd S | jjd k	r&| j| n| j| d S )N)r   rG   r  r~   rJ   )r&   r  r(   r(   r)   data_received  s
    z_HTTPConnection.data_received)N),r,   r-   r.   setr   r   r3   r	   r   r   rl   r   r%   r   r0   r   r   r   r   
SSLContextr   rU   r\   r   r   r   r   r   r   r   BaseExceptionr   r   r   r
   r   r   HTTPHeadersr   r   r   r  bytesr  r(   r(   r(   r)   r`      sB   
 "	=r`   __main__)>tornado.escaper   tornador   Z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   r?   r
  rS   r   r   r   r   rQ   ior   urllib.parser   typingr   r   r   r   r   r   typesr   TYPE_CHECKINGr   r   r    r!   r2   r3   HTTPMessageDelegater`   r,   	configurer(   r(   r(   r)   <module>   sH      -   :

