
[c           @` sF  d  d l  m Z m Z m Z d  d l m Z d  d l m Z d  d l 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 d  d	 l m Z m Z m Z d  d
 l m Z d  d l 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) m* Z* e  rd  d l+ j, Z- n d  d l- Z- y d  d l. Z. Wn e/ k
 re0 Z. n Xd e
 f d     YZ1 d e
 f d     YZ2 d e f d     YZ3 d e j4 f d     YZ5 e6 d k rBe j7 e3  e   n  d S(   i    (   t   absolute_importt   divisiont   print_function(   t   _unicode(   t   gen(   t   HTTPResponset	   HTTPErrort   AsyncHTTPClientt   maint   _RequestProxy(   t   httputil(   t   HTTP1Connectiont   HTTP1ConnectionParameters(   t   IOLoop(   t   StreamClosedError(   t   Resolvert   OverrideResolvert   _client_ssl_defaults(   t   gen_log(   t   stack_context(   t	   TCPClient(   t   PY3N(   t   BytesIOt   HTTPTimeoutErrorc           B` s    e  Z d  Z d   Z d   Z RS(   s   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
    c         C` s    t  t |   j d d | d  S(   NiW  t   message(   t   superR   t   __init__(   t   selfR   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR   /   s    c         C` s   |  j  S(   N(   R   (   R   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyt   __str__2   s    (   t   __name__t
   __module__t   __doc__R   R   (    (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR   '   s   	t   HTTPStreamClosedErrorc           B` s    e  Z d  Z d   Z d   Z RS(   sZ  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
    c         C` s    t  t |   j d d | d  S(   NiW  R   (   R   R    R   (   R   R   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR   A   s    c         C` s   |  j  S(   N(   R   (   R   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR   D   s    (   R   R   R   R   R   (    (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR    6   s   
	t   SimpleAsyncHTTPClientc           B` sw   e  Z d  Z d d d d d d d d  Z d   Z d   Z d   Z d   Z d   Z	 d	   Z
 d
   Z d d  Z RS(   si  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.
    i
   i  @c         C` s   t  t |   j d |  | |  _ t j   |  _ i  |  _ i  |  _ | |  _	 | |  _
 | |  _ | ry | |  _ t |  _ n t   |  _ t |  _ | d k	 r t d |  j d |  |  _ n  t d |  j  |  _ d S(   s  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.
        t   defaultst   resolvert   mappingN(   R   R!   t
   initializet   max_clientst   collectionst   dequet   queuet   activet   waitingt   max_buffer_sizet   max_header_sizet   max_body_sizeR#   t   Falset   own_resolverR   t   Truet   NoneR   R   t
   tcp_client(   R   R&   t   hostname_mappingR,   R#   R"   R-   R.   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR%   Q   s"    $								c         C` s=   t  t |   j   |  j r, |  j j   n  |  j j   d  S(   N(   R   R!   t   closeR0   R#   R3   (   R   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR5      s    	c         C` s   t    } |  j j | | | f  t |  j  |  j k  s |  j j |  j j   t	 | j
 | j  t j |  j | d   } n d  } | | | f |  j | <|  j   |  j r t j d t |  j  t |  j  f  n  d  S(   Ns   in request queuesI   max_clients limit reached, request queued. %d active, %d queued requests.(   t   objectR)   t   appendt   lenR*   R&   t   io_loopt   add_timeoutt   timet   mint   connect_timeoutt   request_timeoutt	   functoolst   partialt   _on_timeoutR2   R+   t   _process_queueR   t   debug(   R   t   requestt   callbackt   keyt   timeout_handle(    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyt
   fetch_impl   s    		

		c         C` s   t  j    x |  j r t |  j  |  j k  r |  j j   \ } } } | |  j k r^ q n  |  j |  | | f |  j | <t	 j
 |  j |  } |  j | | |  q WWd  QXd  S(   N(   R   t   NullContextR)   R8   R*   R&   t   popleftR+   t   _remove_timeoutR?   R@   t   _release_fetcht   _handle_request(   R   RF   RD   RE   t   release_callback(    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyRB      s    $c         C` s   t  S(   N(   t   _HTTPConnection(   R   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyt   _connection_class   s    c      	   C` s5   |  j    |  | | | |  j |  j |  j |  j  d  S(   N(   RP   R,   R3   R-   R.   (   R   RD   RN   t   final_callback(    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyRM      s    		c         C` s   |  j  | =|  j   d  S(   N(   R*   RB   (   R   RF   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyRL      s    
c         C` sU   | |  j  k rQ |  j  | \ } } } | d  k	 rD |  j j |  n  |  j  | =n  d  S(   N(   R+   R2   R9   t   remove_timeout(   R   RF   RD   RE   RG   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyRK      s
    c         C` s   |  j  | \ } } } |  j j | | | f  | rD d j |  n d } t | d d t |  d |  j j   | j } |  j j	 | |  |  j  | =d S(   s   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.
        s   Timeout {0}t   TimeoutiW  t   errort   request_timeN(
   R+   R)   t   removet   formatR   R   R9   R;   t
   start_timet   add_callback(   R   RF   t   infoRD   RE   RG   t   error_messaget   timeout_response(    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyRA      s    N(   R   R   R   R2   R%   R5   RH   RB   RP   RM   RL   RK   RA   (    (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR!   H   s   	6							RO   c           B` s   e  Z e d  d d d d d d g  Z d   Z e j d    Z d	   Z d d
  Z
 d   Z d   Z e j d    Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z RS(   t   GETt   HEADt   POSTt   PUTt   DELETEt   PATCHt   OPTIONSc	   	      C` s   t  j   |  _ |  j j   |  _ t j   |  _ | |  _ | |  _ | |  _ | |  _	 | |  _
 | |  _ | |  _ | |  _ d  |  _ d  |  _ g  |  _ d  |  _ d  |  _ d  |  _ t  j   j |  j  d  S(   N(   R   t   currentR9   R;   RX   t   start_wall_timet   clientRD   RN   RQ   R,   R3   R-   R.   R2   t   codet   headerst   chunkst   _decompressort   _timeoutt	   _sockaddrRY   t   run(	   R   Rf   RD   RN   RQ   R,   R3   R-   R.   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR      s$    														c      	   c` sP  yt  j t |  j j   |  _ |  j j d. k rL t d |  j j   n  |  j j } d | k r | j	 d  \ } } } n  t
 j |  \ } } | d  k r |  j j d k r d n d } n  t j d |  r | d d	 !} n  | |  _ |  j j t k r
t j } n	 t j } |  j |  j j  } t |  j j |  j j  } | r|  j j |  j | t j t j |  j  d
    |  _! |  j" j# | | d | d | d |  j$ V}	 |  j% d  k r|	 j&   d  S|	 |  _' |  j' j( |  j)  |  j*   |  j% d  k rd  S|  j j rM|  j j |  j |  j j t j t j |  j  d    |  _! n  |  j j+ |  j, k r|  j j- rt. d |  j j+   n  x6 d/ D]. }
 t/ |  j |
 d   rt0 d |
   qqWd |  j j1 k rd |  j j1 d <n  d |  j j1 k rId |  j j k r0|  j j j	 d  d	 |  j j1 d <qI|  j j |  j j1 d <n  d0 \ } } |  j j2 d  k	 r|  j j2 |  j j3 } } n3 |  j j4 d  k	 r|  j j4 } |  j j5 pd } n  | d  k	 r|  j j6 d1 k rt d |  j j6   n  d t7 j8 t
 j9 | |   |  j j1 d <n  |  j j: r=|  j j: |  j j1 d <n  |  j j- s|  j j+ d2 k } |  j j; d  k	 p||  j j< d  k	 } | r| s| r| rt d# | rd$ n d |  j j+ f   qn  |  j j= rd% |  j j1 d& <n  |  j j; d  k	 rt> t? |  j j;   |  j j1 d' <n  |  j j+ d  k rTd( |  j j1 k rTd) |  j j1 d( <n  |  j j@ rsd* |  j j1 d+ <n  |  j jA pd, |  j jB rd- |  j jB n d } |  jC |	  |  _D t
 jE |  j j+ | d  } |  jD jF | |  j j1  |  j j= r|  jD jG |   Vq|  jH tI  Vn  Wn, tJ k
 rK|  jK tL jM     sL  qLn Xd  S(3   Nt   httpt   httpss   Unsupported url scheme: %st   @i  iP   s   ^\[.*\]$i   is   while connectingt   aft   ssl_optionsR,   s   during requests   unknown method %st   network_interfacet
   proxy_hostt
   proxy_portt   proxy_usernamet   proxy_passwordt   proxy_auth_modes   %s not supportedt
   ConnectionR5   t   Hostt    t   basics   unsupported auth_mode %ss   Basic t   Authorizations
   User-AgentR_   Rb   R`   sL   Body must %sbe None for method %s (unless allow_nonstandard_methods is true)s   not s   100-continuet   Expects   Content-Lengths   Content-Types!   application/x-www-form-urlencodedt   gzips   Accept-Encodingt   /t   ?(   Rn   Ro   (   Rs   Rt   Ru   Rv   Rw   Rx   (   NN(   NR|   (   R_   Rb   R`   (N   t   urlparset   urlsplitR   RD   t   urlt   parsedt   schemet
   ValueErrort   netloct
   rpartitionR
   t   split_host_and_portR2   t   ret   matcht   parsed_hostnamet
   allow_ipv6R/   t   sockett   AF_INETt	   AF_UNSPECt   _get_ssl_optionsR<   R=   R>   R9   R:   RX   R   t   wrapR?   R@   RA   Rk   R3   t   connectR,   RQ   R5   t   streamt   set_close_callbackt   on_connection_closeRK   t   methodt   _SUPPORTED_METHODSt   allow_nonstandard_methodst   KeyErrort   getattrt   NotImplementedErrorRh   t   usernamet   passwordt   auth_usernamet   auth_passwordt	   auth_modet   base64t	   b64encodet   encode_username_passwordt
   user_agentt   bodyt   body_producert   expect_100_continuet   strR8   t   decompress_responset   patht   queryt   _create_connectiont
   connectiont   RequestStartLinet   write_headerst   read_responset   _write_bodyR1   t	   Exceptiont   _handle_exceptiont   syst   exc_info(   R   R   t   userpasst   _t   hostt   portRq   Rr   t   timeoutR   RF   R   R   t   body_expectedt   body_presentt   req_patht
   start_line(    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyRm      s    !			
$	
	
	'  
&	#(#c         C` s  | d k r|  j  j d  k	 r( |  j  j S|  j  j rn |  j  j d  k rn |  j  j d  k rn |  j  j d  k rn t St j	 t j
 j d |  j  j } |  j  j s t | _ t j | _ n  |  j  j d  k	 r | j |  j  j |  j  j  n  t t d  r| j t j O_ n  | Sd  S(   NRo   t   cafilet   OP_NO_COMPRESSION(   RD   Rr   R2   t   validate_certt   ca_certst   client_certt
   client_keyR   t   sslt   create_default_contextt   Purposet   SERVER_AUTHR/   t   check_hostnamet	   CERT_NONEt   verify_modet   load_cert_chaint   hasattrt   optionsR   (   R   R   t   ssl_ctx(    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR   e  s*    
	c         C` sS   d |  _ | r d j |  n d } |  j d k	 rO |  j t t |  d  n  d S(   s   Timeout callback of _HTTPConnection instance.

        Raise a `HTTPTimeoutError` when a timeout occurs.

        :info string key: More detailed timeout information.
        s   Timeout {0}RS   N(   R2   Rk   RW   RQ   R   R   (   R   RZ   R[   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyRA     s
    	c         C` s2   |  j  d  k	 r. |  j j |  j   d  |  _  n  d  S(   N(   Rk   R2   R9   RR   (   R   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyRK     s    c         C` sP   | j  t  t | t t d t d |  j d |  j d |  j j  |  j  } | S(   Nt   no_keep_aliveR-   R.   t
   decompress(	   t   set_nodelayR1   R   R   R-   R.   RD   R   Rl   (   R   R   R   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR     s    		c         c` s   |  j  j d  k	 r+ |  j j |  j  j  nA |  j  j d  k	 rl |  j  j |  j j  } | d  k	 rl | Vql n  |  j j   | r y |  j j |   VWq t k
 r |  j	 t
 j     s   q q Xn  d  S(   N(   RD   R   R2   R   t   writeR   t   finishR   R   R   R   R   (   R   t
   start_readt   fut(    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR     s    c         C` s/   |  j  d  k	 r+ |  j  } d  |  _  |   n  d  S(   N(   RN   R2   (   R   RN   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyt   _release  s    		c         C` sE   |  j    |  j d  k	 rA |  j } d  |  _ |  j j | |  n  d  S(   N(   R   RQ   R2   R9   RY   (   R   t   responseRQ   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyt   _run_callback  s
    
		c      
   C` s   |  j  r |  j   t | t  rL | j d  k r@ t d  } qL | j } n  |  j t |  j	 d d | d |  j
 j   |  j d |  j  t |  d  r |  j j   n  t St | t  Sd  S(   Ns   Stream closediW  RT   RU   RX   R   (   RQ   RK   t
   isinstanceR   t
   real_errorR2   R    R   R   RD   R9   R;   RX   Re   R   R   R5   R1   (   R   t   typt   valuet   tb(    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR     s    	
c         C` sn   |  j  d  k	 rj d } |  j j r0 |  j j  n  y t |   Wqj t k
 rf |  j t j     qj Xn  d  S(   Ns   Connection closed(   RQ   R2   R   RT   R    R   R   R   (   R   R   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR     s    c         C` s   |  j  j r, | j d k r, |  j t  d  S| j |  _ | j |  _ | |  _ |  j   r] d  S|  j  j d  k	 r |  j  j d |  x7 |  j j
   D]& \ } } |  j  j d | | f  q W|  j  j d  n  d  S(   Nid   s
   %s %s %s
s   %s: %s
s   
(   RD   R   Rg   R   R/   t   reasonRh   t   _should_follow_redirectt   header_callbackR2   t   get_all(   R   t
   first_lineRh   t   kt   v(    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyt   headers_received  s    	c         C` s+   |  j  j o* |  j  j d k o* |  j d k S(   Ni    i-  i.  i/  i3  i4  (   i-  i.  i/  i3  i4  (   RD   t   follow_redirectst   max_redirectsRg   (   R   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR     s    c         ` s  d j  |  j  } |  j   t |  j d |  j  } |  j   rst |  j t  sX t  t	 j	 |  j j  } t
 j |  j j |  j d  | _ |  j j d | _ | j d =|  j d k rd | _ d  | _ xB d	 d
 d d g D]+ } y |  j j | =Wq t k
 r
q Xq Wn  | | _ |  j   d  |  _ |  j   |  j j | d t } | j   f d    |  j   d  S|  j j rt   } n t |  } t | |  j d t |  d d   d |  j d |  j j    |  j! d |  j" d | d |  j j } |  j# |  |  j   d  S(   NR{   t   original_requestt   Locationi   Rz   i.  i/  R]   s   Content-Lengths   Content-Types   Content-Encodings   Transfer-Encodingt   raise_errorc         ` s     |  j     S(   N(   t   result(   t   f(   RQ   (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyt   <lambda>  s    R   Rh   RU   RX   t   buffert   effective_url(   i.  i/  ($   t   joinRi   RK   R   RD   R   R   R	   t   AssertionErrort   copyR   t   urljoinR   Rh   R   Rg   R   R2   R   R   R   RQ   R   Rf   t   fetchR/   t   add_done_callbackt   _on_end_requestt   streaming_callbackR   R   R9   R;   RX   Re   R   (   R   t   dataR   t   new_requestt   hR   R   R   (    (   RQ   s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR     sP    

						

		c         C` s   |  j  j   d  S(   N(   R   R5   (   R   (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyR   '  s    c         C` sI   |  j    r d  S|  j j d  k	 r5 |  j j |  n |  j j |  d  S(   N(   R   RD   R   R2   Ri   R7   (   R   t   chunk(    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyt   data_received*  s
    N(   R   R   t   setR   R   R   t	   coroutineRm   R   R2   RA   RK   R   R   R   R   R   R   R   R   R   R   R   (    (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyRO      s"   !	x							
			2	t   __main__(8   t
   __future__R    R   R   t   tornado.escapeR   t   tornadoR   t   tornado.httpclientR   R   R   R   R	   R
   t   tornado.http1connectionR   R   t   tornado.ioloopR   t   tornado.iostreamR   t   tornado.netutilR   R   R   t   tornado.logR   R   t   tornado.tcpclientR   t   tornado.utilR   R   R'   R   R?   R   R   R   R;   t   ioR   t   urllib.parset   parseR   R   t   ImportErrorR2   R   R    R!   t   HTTPMessageDelegateRO   R   t	   configure(    (    (    s8   lib/python2.7/site-packages/tornado/simple_httpclient.pyt   <module>   sH   (
 b