
[c           @` s  d  Z  d d l m Z m Z 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 Z d d l m Z m Z m Z d d l m Z d d l m Z m Z m Z e r,d d l j Z d d l m Z d d l m  Z  m! Z! m" Z" m# Z# nH d d l Z d d l$ m Z d d	 l% m  Z  d d
 l! m! Z! m" Z" m# Z# e y d d l& m' Z' Wn- e( k
 rd e) f d     YZ* e* Z' n Xy d d l+ Z+ Wn e( k
 rn Xe j, d  Z- d e. f d     YZ/ e/ d  Z0 d e j1 f d     YZ2 d e3 f d     YZ4 d e) f d     YZ5 d e) f d     YZ6 d e3 f d     YZ7 d e3 f d     YZ8 d e3 f d     YZ9 d    Z: d! e f d"     YZ; d#   Z< d$   Z= d%   Z> d d&  Z@ d'   ZA d(   ZB e jC d) d* d+ d, g  ZD d-   ZE e jC d. d, d/ d0 g  ZF d1   ZG d2   ZH d3   ZI d4   ZJ d5   ZK d6   ZL d7   ZM d8   ZN e j, d9  ZO e j, d:  ZP d; jQ ZR d<   ZS d=   ZT d S(>   s   HTTP utility code shared by clients and servers.

This module also defines the `HTTPServerRequest` class which is exposed
via `tornado.web.RequestHandler.request`.
i    (   t   absolute_importt   divisiont   print_functionN(   t
   native_strt   parse_qs_bytest   utf8(   t   gen_log(   t
   ObjectDictt   PY3t   unicode_type(   t	   responses(   t	   urlencodet   urlparset
   urlunparset	   parse_qsl(   R   (   R   R   R   (   t   SSLErrort	   _SSLErrorc           B` s   e  Z RS(    (   t   __name__t
   __module__(    (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR   :   s   s   \r?\nt   _NormalizedHeaderCachec           B` s    e  Z d  Z d   Z d   Z RS(   sK  Dynamic cached mapping of header names to Http-Header-Case.

    Implemented as a dict subclass so that cache hits are as fast as a
    normal dict lookup, without the overhead of a python function
    call.

    >>> normalized_headers = _NormalizedHeaderCache(10)
    >>> normalized_headers["coNtent-TYPE"]
    'Content-Type'
    c         C` s/   t  t |   j   | |  _ t j   |  _ d  S(   N(   t   superR   t   __init__t   sizet   collectionst   dequet   queue(   t   selfR   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR   V   s    	c         C` s   d j  g  | j d  D] } | j   ^ q  } | |  | <|  j j |  t |  j  |  j k r| |  j j   } |  | =n  | S(   Nt   -(   t   joint   splitt
   capitalizeR   t   appendt   lenR   t   popleft(   R   t   keyt   wt
   normalizedt   old_key(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   __missing__[   s    1

(   R   R   t   __doc__R   R&   (    (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR   K   s   
	i  t   HTTPHeadersc           B` s   e  Z d  Z d   Z d   Z d   Z d   Z d   Z e d    Z	 d   Z
 d   Z d	   Z d
   Z d   Z d   Z e Z d   Z e Z RS(   s  A dictionary that maintains ``Http-Header-Case`` for all keys.

    Supports multiple values per key via a pair of new methods,
    `add()` and `get_list()`.  The regular dictionary interface
    returns a single value per key, with multiple values joined by a
    comma.

    >>> h = HTTPHeaders({"content-type": "text/html"})
    >>> list(h.keys())
    ['Content-Type']
    >>> h["Content-Type"]
    'text/html'

    >>> h.add("Set-Cookie", "A=B")
    >>> h.add("Set-Cookie", "C=D")
    >>> h["set-cookie"]
    'A=B,C=D'
    >>> h.get_list("set-cookie")
    ['A=B', 'C=D']

    >>> for (k,v) in sorted(h.get_all()):
    ...    print('%s: %s' % (k,v))
    ...
    Content-Type: text/html
    Set-Cookie: A=B
    Set-Cookie: C=D
    c         O` s   i  |  _  i  |  _ d  |  _ t |  d k r t |  d k r t | d t  r xA | d j   D] \ } } |  j | |  qc Wn |  j	 | |   d  S(   Ni   i    (
   t   _dictt   _as_listt   Nonet	   _last_keyR    t
   isinstanceR(   t   get_allt   addt   update(   R   t   argst   kwargst   kt   v(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR      s    			$c         C` si   t  | } | |  _ | |  k r[ t |  |  d t |  |  j | <|  j | j |  n
 | |  | <d S(   s#   Adds a new value for the given key.t   ,N(   t   _normalized_headersR,   R   R)   R*   R   (   R   t   namet   valuet	   norm_name(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR/      s    
	c         C` s   t  | } |  j j | g   S(   s2   Returns all values for the given header as a list.(   R6   R*   t   get(   R   R7   R9   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   get_list   s    
c         c` s@   x9 |  j  j   D]( \ } } x | D] } | | f Vq# Wq Wd S(   s   Returns an iterable of all (name, value) pairs.

        If a header has multiple values, multiple pairs will be
        returned with the same name.
        N(   R*   t   items(   R   R7   t   valuesR8   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR.      s    c         C` s   | d j    rq |  j d k r. t d   n  d | j   } |  j |  j d c | 7<|  j |  j c | 7<nR y | j d d  \ } } Wn t k
 r t d   n X|  j	 | | j
    d S(	   s   Updates the dictionary with a single header line.

        >>> h = HTTPHeaders()
        >>> h.parse_line("Content-Type: text/html")
        >>> h.get('content-type')
        'text/html'
        i    s.   first header line cannot start with whitespacet    it   :i   s   no colon in header lineN(   t   isspaceR,   R+   t   HTTPInputErrort   lstripR*   R)   R   t
   ValueErrorR/   t   strip(   R   t   linet   new_partR7   R8   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt
   parse_line   s    c         C` s=   |    } x- t  j |  D] } | r | j |  q q W| S(   s  Returns a dictionary from HTTP header text.

        >>> h = HTTPHeaders.parse("Content-Type: text/html\r\nContent-Length: 42\r\n")
        >>> sorted(h.items())
        [('Content-Length', '42'), ('Content-Type', 'text/html')]

        .. versionchanged:: 5.1

           Raises `HTTPInputError` on malformed headers instead of a
           mix of `KeyError`, and `ValueError`.

        (   t   _CRLF_RER   RG   (   t   clst   headerst   hRE   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   parse   s
    	c         C` s+   t  | } | |  j | <| g |  j | <d  S(   N(   R6   R)   R*   (   R   R7   R8   R9   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   __setitem__   s    
c         C` s   |  j  t | S(   N(   R)   R6   (   R   R7   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   __getitem__   s    c         C` s"   t  | } |  j | =|  j | =d  S(   N(   R6   R)   R*   (   R   R7   R9   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   __delitem__   s    

c         C` s   t  |  j  S(   N(   R    R)   (   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   __len__   s    c         C` s   t  |  j  S(   N(   t   iterR)   (   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   __iter__   s    c         C` s
   t  |   S(   N(   R(   (   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   copy   s    c         C` sG   g  } x1 |  j    D]# \ } } | j d | | f  q Wd j |  S(   Ns   %s: %s
t    (   R.   R   R   (   R   t   linesR7   R8   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   __str__   s    (   R   R   R'   R   R/   R;   R.   RG   t   classmethodRL   RM   RN   RO   RP   RR   RS   t   __copy__RV   t   __unicode__(    (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR(   k   s    												t   HTTPServerRequestc           B` s   e  Z d  Z d d d d d d d d d d d 
 Z d   Z e d    Z d d  Z d   Z	 d   Z
 d   Z e d	  Z d
   Z d   Z RS(   s7
  A single HTTP request.

    All attributes are type `str` unless otherwise noted.

    .. attribute:: method

       HTTP request method, e.g. "GET" or "POST"

    .. attribute:: uri

       The requested uri.

    .. attribute:: path

       The path portion of `uri`

    .. attribute:: query

       The query portion of `uri`

    .. attribute:: version

       HTTP version specified in request, e.g. "HTTP/1.1"

    .. attribute:: headers

       `.HTTPHeaders` dictionary-like object for request headers.  Acts like
       a case-insensitive dictionary with additional methods for repeated
       headers.

    .. attribute:: body

       Request body, if present, as a byte string.

    .. attribute:: remote_ip

       Client's IP address as a string.  If ``HTTPServer.xheaders`` is set,
       will pass along the real IP address provided by a load balancer
       in the ``X-Real-Ip`` or ``X-Forwarded-For`` header.

    .. versionchanged:: 3.1
       The list format of ``X-Forwarded-For`` is now supported.

    .. attribute:: protocol

       The protocol used, either "http" or "https".  If ``HTTPServer.xheaders``
       is set, will pass along the protocol used by a load balancer if
       reported via an ``X-Scheme`` header.

    .. attribute:: host

       The requested hostname, usually taken from the ``Host`` header.

    .. attribute:: arguments

       GET/POST arguments are available in the arguments property, which
       maps arguments names to lists of values (to support multiple values
       for individual names). Names are of type `str`, while arguments
       are byte strings.  Note that this is different from
       `.RequestHandler.get_argument`, which returns argument values as
       unicode strings.

    .. attribute:: query_arguments

       Same format as ``arguments``, but contains only arguments extracted
       from the query string.

       .. versionadded:: 3.2

    .. attribute:: body_arguments

       Same format as ``arguments``, but contains only arguments extracted
       from the request body.

       .. versionadded:: 3.2

    .. attribute:: files

       File uploads are available in the files property, which maps file
       names to lists of `.HTTPFile`.

    .. attribute:: connection

       An HTTP request is attached to a single HTTP connection, which can
       be accessed through the "connection" attribute. Since connections
       are typically kept open in HTTP/1.1, multiple requests can be handled
       sequentially on a single connection.

    .. versionchanged:: 4.0
       Moved from ``tornado.httpserver.HTTPRequest``.
    s   HTTP/1.0c         C` sd  |	 d  k	 r |	 \ } } } n  | |  _ | |  _ | |  _ | pE t   |  _ | pT d |  _ t | d d   } t | d d   |  _ t | d d  |  _	 | p |  j j
 d  p d |  _ t |  j j    d |  _ | p i  |  _ | |  _ |
 |  _ t j   |  _ d  |  _ | j d	  \ |  _ } |  _ t |  j d
 t |  _ t j |  j  |  _ i  |  _ d  S(   NRT   t   contextt	   remote_ipt   protocolt   httpt   Hosts	   127.0.0.1i    t   ?t   keep_blank_values(   R+   t   methodt   urit   versionR(   RJ   t   bodyt   getattrR\   R]   R:   t   hostt   split_host_and_portt   lowert	   host_namet   filest
   connectiont   server_connectiont   timet   _start_timet   _finish_timet	   partitiont   patht   queryR   t   Truet	   argumentsRS   t   deepcopyt   query_argumentst   body_arguments(   R   Rb   Rc   Rd   RJ   Re   Rg   Rk   Rl   t
   start_lineRm   R[   t   sep(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR   `  s*    			!			c         C` s   t  j d t  |  j d k S(   s\  Returns True if this request supports HTTP/1.1 semantics.

        .. deprecated:: 4.0

           Applications are less likely to need this information with
           the introduction of `.HTTPConnection`. If you still need
           it, access the ``version`` attribute directly. This method
           will be removed in Tornado 6.0.

        s>   supports_http_1_1() is deprecated, use request.version insteads   HTTP/1.1(   t   warningst   warnt   DeprecationWarningRd   (   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   supports_http_1_1}  s    	c         C` s   t  |  d  s t j   |  _ d |  j k r y t |  j d  } Wn t k
 rW q XxB | j   D]1 \ } } y | |  j | <Wqe t k
 r qe Xqe Wq n  |  j S(   s&   A dictionary of Cookie.Morsel objects.t   _cookiest   Cookie(   t   hasattrR   t   SimpleCookieR   RJ   t   parse_cookiet	   ExceptionR<   (   R   t   parsedR3   R4   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   cookies  s    c         C` s]   t  j d t  t | t  s% t  |  j j d  sC t d   |  j j	 | d | d S(   s   Writes the given chunk to the response stream.

        .. deprecated:: 4.0
           Use ``request.connection`` and the `.HTTPConnection` methods
           to write the response. This method will be removed in Tornado 6.0.
        sH   req.write deprecated, use req.connection.write and write_headers insteads   HTTP/1.s/   deprecated interface only supported in HTTP/1.xt   callbackN(
   R{   R|   R}   R-   t   bytest   AssertionErrorRd   t
   startswithRl   t   write(   R   t   chunkR   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR     s    		c         C` s0   t  j d t  |  j j   t j   |  _ d S(   s   Finishes this HTTP request on the open connection.

        .. deprecated:: 4.0
           Use ``request.connection`` and the `.HTTPConnection` methods
           to write the response. This method will be removed in Tornado 6.0.
        s8   req.finish deprecated, use req.connection.finish insteadN(   R{   R|   R}   Rl   t   finishRn   Rp   (   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR     s    	c         C` s   |  j  d |  j |  j S(   s+   Reconstructs the full URL for this request.s   ://(   R]   Rg   Rc   (   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   full_url  s    c         C` s2   |  j  d k r  t j   |  j S|  j  |  j Sd S(   s?   Returns the amount of time it took for this request to execute.N(   Rp   R+   Rn   Ro   (   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   request_time  s    c         C` s6   y |  j  j j j d |  SWn t k
 r1 d SXd S(   s>  Returns the client's SSL certificate, if any.

        To use client certificates, the HTTPServer's
        `ssl.SSLContext.verify_mode` field must be set, e.g.::

            ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
            ssl_ctx.load_cert_chain("foo.crt", "foo.key")
            ssl_ctx.load_verify_locations("cacerts.pem")
            ssl_ctx.verify_mode = ssl.CERT_REQUIRED
            server = HTTPServer(app, ssl_options=ssl_ctx)

        By default, the return value is a dictionary (or None, if no
        client certificate is present).  If ``binary_form`` is true, a
        DER-encoded form of the certificate is returned instead.  See
        SSLSocket.getpeercert() in the standard library for more
        details.
        http://docs.python.org/library/ssl.html#sslsocket-objects
        t   binary_formN(   Rl   t   streamt   sockett   getpeercertR   R+   (   R   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   get_ssl_certificate  s
    c         C` sq   t  |  j j d d  |  j |  j |  j |  j  x9 |  j j   D]( \ } } |  j j | g   j	 |  qA Wd  S(   Ns   Content-TypeRT   (
   t   parse_body_argumentsRJ   R:   Re   Rx   Rk   R<   Ru   t
   setdefaultt   extend(   R   R3   R4   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   _parse_body  s    
c         C` sO   d
 } d j  g  | D] } d | t |  |  f ^ q  } d	 |  j j | f S(   NR]   Rg   Rb   Rc   Rd   R\   s   , s   %s=%rs   %s(%s)(   R]   Rg   Rb   Rc   Rd   R\   (   R   Rf   t	   __class__R   (   R   t   attrst   nR1   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   __repr__  s    5N(   R   R   R'   R+   R   R~   t   propertyR   R   R   R   R   t   FalseR   R   R   (    (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyRZ     s   [						RA   c           B` s   e  Z d  Z RS(   sq   Exception class for malformed HTTP requests or responses
    from remote sources.

    .. versionadded:: 4.0
    (   R   R   R'   (    (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyRA     s   t   HTTPOutputErrorc           B` s   e  Z d  Z RS(   sJ   Exception class for errors in HTTP output.

    .. versionadded:: 4.0
    (   R   R   R'   (    (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR     s   t   HTTPServerConnectionDelegatec           B` s    e  Z d  Z d   Z d   Z RS(   s_   Implement this interface to handle requests from `.HTTPServer`.

    .. versionadded:: 4.0
    c         C` s   t     d S(   sj  This method is called by the server when a new request has started.

        :arg server_conn: is an opaque object representing the long-lived
            (e.g. tcp-level) connection.
        :arg request_conn: is a `.HTTPConnection` object for a single
            request/response exchange.

        This method should return a `.HTTPMessageDelegate`.
        N(   t   NotImplementedError(   R   t   server_connt   request_conn(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   start_request  s    
c         C` s   d S(   s   This method is called when a connection has been closed.

        :arg server_conn: is a server connection that has previously been
            passed to ``start_request``.
        N(    (   R   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   on_close  s    (   R   R   R'   R   R   (    (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR     s   	t   HTTPMessageDelegatec           B` s2   e  Z d  Z d   Z d   Z d   Z d   Z RS(   s_   Implement this interface to handle an HTTP request or response.

    .. versionadded:: 4.0
    c         C` s   d S(   s  Called when the HTTP headers have been received and parsed.

        :arg start_line: a `.RequestStartLine` or `.ResponseStartLine`
            depending on whether this is a client or server message.
        :arg headers: a `.HTTPHeaders` instance.

        Some `.HTTPConnection` methods can only be called during
        ``headers_received``.

        May return a `.Future`; if it does the body will not be read
        until it is done.
        N(    (   R   Ry   RJ   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   headers_received  s    c         C` s   d S(   si   Called when a chunk of data has been received.

        May return a `.Future` for flow control.
        N(    (   R   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   data_received-  s    c         C` s   d S(   s6   Called after the last chunk of data has been received.N(    (   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR   4  s    c         C` s   d S(   s   Called if the connection is closed without finishing the request.

        If ``headers_received`` is called, either ``finish`` or
        ``on_connection_close`` will be called, but not both.
        N(    (   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   on_connection_close8  s    (   R   R   R'   R   R   R   R   (    (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR     s
   			t   HTTPConnectionc           B` s2   e  Z d  Z d d d  Z d d  Z d   Z RS(   sY   Applications use this interface to write their responses.

    .. versionadded:: 4.0
    c         C` s   t     d S(   s  Write an HTTP header block.

        :arg start_line: a `.RequestStartLine` or `.ResponseStartLine`.
        :arg headers: a `.HTTPHeaders` instance.
        :arg chunk: the first (optional) chunk of data.  This is an optimization
            so that small responses can be written in the same call as their
            headers.
        :arg callback: a callback to be run when the write is complete.

        The ``version`` field of ``start_line`` is ignored.

        Returns a `.Future` if no callback is given.

        .. deprecated:: 5.1

           The ``callback`` argument is deprecated and will be removed
           in Tornado 6.0.
        N(   R   (   R   Ry   RJ   R   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   write_headersF  s    c         C` s   t     d S(   s  Writes a chunk of body data.

        The callback will be run when the write is complete.  If no callback
        is given, returns a Future.

        .. deprecated:: 5.1

           The ``callback`` argument is deprecated and will be removed
           in Tornado 6.0.
        N(   R   (   R   R   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR   [  s    c         C` s   t     d S(   s<   Indicates that the last body data has been written.
        N(   R   (   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR   h  s    N(   R   R   R'   R+   R   R   R   (    (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR   A  s   c         C` s   | d k r |  St |   } t | t  rV t | j d t } | j | j    nd t | t	  st t | t
  r t | j d t } | j |  n! d j t |   } t |   t |  } t | d | d | d | d | | d f  }  |  S(	   s  Concatenate url and arguments regardless of whether
    url has existing query parameters.

    ``args`` may be either a dictionary or a list of key-value pairs
    (the latter allows for multiple values with the same key.

    >>> url_concat("http://example.com/foo", dict(c="d"))
    'http://example.com/foo?c=d'
    >>> url_concat("http://example.com/foo?a=b", dict(c="d"))
    'http://example.com/foo?a=b&c=d'
    >>> url_concat("http://example.com/foo?a=b", [("c", "d"), ("c", "d2")])
    'http://example.com/foo?a=b&c=d&c=d2'
    Ra   s7   'args' parameter should be dict, list or tuple. Not {0}i    i   i   i   i   N(   R+   R   R-   t   dictR   Rs   Rt   R   R<   t   listt   tuplet   formatt   typet	   TypeErrorR   R   (   t   urlR1   t
   parsed_urlt   parsed_queryt   errt   final_query(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt
   url_concatn  s*    t   HTTPFilec           B` s   e  Z d  Z RS(   s   Represents a file uploaded via a form.

    For backwards compatibility, its instance attributes are also
    accessible as dictionary keys.

    * ``filename``
    * ``body``
    * ``content_type``
    (   R   R   R'   (    (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR     s   	c         C` s   |  j  d  \ } } } | j   | j   } } | d k rA d S| j  d  \ } } } y t |  } t |  } Wn t k
 r d SX| d k	 r | d k r | d k r | } d } q q | d 7} n  | | f S(   sg  Parses a Range header.

    Returns either ``None`` or tuple ``(start, end)``.
    Note that while the HTTP headers use inclusive byte positions,
    this method returns indexes suitable for use in slices.

    >>> start, end = _parse_request_range("bytes=1-2")
    >>> start, end
    (1, 3)
    >>> [0, 1, 2, 3, 4][start:end]
    [1, 2]
    >>> _parse_request_range("bytes=6-")
    (6, None)
    >>> _parse_request_range("bytes=-6")
    (-6, None)
    >>> _parse_request_range("bytes=-0")
    (None, 0)
    >>> _parse_request_range("bytes=")
    (None, None)
    >>> _parse_request_range("foo=42")
    >>> _parse_request_range("bytes=1-2,6-10")

    Note: only supports one range (ex, ``bytes=1-2,6-10`` is not allowed).

    See [0] for the details of the range header.

    [0]: http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p5-range-latest.html#byte.ranges
    t   =R   R   i    i   N(   Rq   RD   R+   t   _int_or_noneRC   (   t   range_headert   unitt   _R8   t   start_bt   end_bt   startt   end(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   _parse_request_range  s"    c         C` s-   |  p	 d }  | p | d } d |  | | f S(   s   Returns a suitable Content-Range header:

    >>> print(_get_content_range(None, 1, 4))
    bytes 0-0/4
    >>> print(_get_content_range(1, 3, 4))
    bytes 1-2/4
    >>> print(_get_content_range(None, None, 4))
    bytes 0-3/4
    i    i   s   bytes %s-%s/%s(    (   R   R   t   total(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   _get_content_range  s    
c         C` s&   |  j    }  |  d k r d  St |   S(   NRT   (   RD   R+   t   int(   t   val(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR     s    c         C` s|  | r* d | k r* t  j d | d  d S|  j d  r y t t |  d t } Wn) t k
 r } t  j d |  i  } n Xx | j   D]. \ } } | r | j | g   j	 |  q q Wn |  j d  rxy} |  j
 d  }	 xg |	 D]S }
 |
 j   j d	  \ } } } | d
 k r | r t t |  | | |  Pq q Wt d   Wqxt k
 rt} t  j d |  qxXn  d S(   sF  Parses a form request body.

    Supports ``application/x-www-form-urlencoded`` and
    ``multipart/form-data``.  The ``content_type`` parameter should be
    a string and ``body`` should be a byte string.  The ``arguments``
    and ``files`` parameters are dictionaries that will be updated
    with the parsed contents.
    s   Content-Encodings    Unsupported Content-Encoding: %sNs!   application/x-www-form-urlencodedRa   s&   Invalid x-www-form-urlencoded body: %ss   multipart/form-datat   ;R   t   boundarys   multipart boundary not founds   Invalid multipart/form-data: %s(   R   t   warningR   R   R   Rt   R   R<   R   R   R   RD   Rq   t   parse_multipart_form_dataR   RC   (   t   content_typeRe   Ru   Rk   RJ   t   uri_argumentst   eR7   R=   t   fieldst   fieldR3   Rz   R4   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR     s0    		
#c      	   C` s  |  j  d  r. |  j d  r. |  d d !}  n  | j d |  d  } | d k rb t j d  d S| |  j d |  d  } xc| D][} | s q n  | j d  } | d k r t j d	  q n  t j | |  j	 d
   } | j
 d d  }	 t |	  \ }
 } |
 d k s | j d  r3t j d  q n  | | d d !} | j
 d  sft j d  q n  | d } | j
 d  r| j
 d d  } | j | g   j t d | d d | d |   q | j | g   j |  q Wd S(   s]  Parses a ``multipart/form-data`` body.

    The ``boundary`` and ``data`` parameters are both byte strings.
    The dictionaries given in the arguments and files parameters
    will be updated with the contents of the body.

    .. versionchanged:: 5.1

       Now recognizes non-ASCII filenames in RFC 2231/5987
       (``filename*=``) format.
    t   "i   is   --s.   Invalid multipart/form-data: no final boundaryNs   
s   

s#   multipart/form-data missing headerss   utf-8s   Content-DispositionRT   s	   form-datas   Invalid multipart/form-datai   iR7   s&   multipart/form-data value missing namet   filenames   Content-Types   application/unknownRe   R   (   R   t   endswitht   rfindR   R   R   t   findR(   RL   t   decodeR:   t   _parse_headerR   R   R   (   R   t   dataRu   Rk   t   final_boundary_indext   partst   partt   eohRJ   t   disp_headert   dispositiont   disp_paramsR8   R7   t   ctype(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR     s>    
c         C` s   t  |  t j  r nd t  |  t t j f  r? t j |   }  n: t  |  t j  ri t j |  j	    }  n t
 d |    t j j |  d t S(   s  Formats a timestamp in the format used by HTTP.

    The argument may be a numeric timestamp as returned by `time.time`,
    a time tuple as returned by `time.gmtime`, or a `datetime.datetime`
    object.

    >>> format_timestamp(1359312200)
    'Sun, 27 Jan 2013 18:43:20 GMT'
    s   unknown timestamp type: %rt   usegmt(   R-   t   numberst   RealR   Rn   t   struct_timet   calendart   timegmt   datetimet   utctimetupleR   t   emailt   utilst
   formatdateRt   (   t   ts(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   format_timestamp?  s    
t   RequestStartLineRb   Rr   Rd   c         C` sq   y |  j  d  \ } } } Wn t k
 r; t d   n Xt j d |  sa t d |   n  t | | |  S(   s   Returns a (method, path, version) tuple for an HTTP 1.x request line.

    The response is a `collections.namedtuple`.

    >>> parse_request_start_line("GET /foo HTTP/1.1")
    RequestStartLine(method='GET', path='/foo', version='HTTP/1.1')
    R>   s   Malformed HTTP request lines   ^HTTP/1\.[0-9]$s/   Malformed HTTP version in HTTP Request-Line: %r(   R   RC   RA   t   ret   matchR   (   RE   Rb   Rr   Rd   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   parse_request_start_lineX  s    t   ResponseStartLinet   codet   reasonc         C` sd   t  |   }  t j d |   } | s3 t d   n  t | j d  t | j d   | j d   S(   s   Returns a (version, code, reason) tuple for an HTTP 1.x response line.

    The response is a `collections.namedtuple`.

    >>> parse_response_start_line("HTTP/1.1 200 OK")
    ResponseStartLine(version='HTTP/1.1', code=200, reason='OK')
    s   (HTTP/1.[0-9]) ([0-9]+) ([^]*)s!   Error parsing response start linei   i   i   (   R   R   R   RA   R   t   groupR   (   RE   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   parse_response_start_linep  s    !c         c` s   x |  d  d k r |  d }  |  j  d  } xR | d k r |  j d d |  |  j d d |  d r |  j  d | d  } q/ W| d k  r t |   } n  |  |  } | j   V|  | }  q Wd  S(   Ni   R   i    R   s   \"i   (   R   t   countR    RD   (   t   sR   t   f(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   _parseparam  s    
;
c   	      C` s;  t  d |   } t |  } d
 g } xo | D]g } | j d  } | d k r, | |  j   j   } | | d j   } | j | t |  f  q, q, Wt j j	 |  } | j
 d  i  } xr | D]j \ } } t j j |  } t |  d k r#| d d k r#| d	 d k r#| d d	 !} n  | | | <q W| | f S(   sY  Parse a Content-type like header.

    Return the main content-type and a dictionary of options.

    >>> d = "form-data; foo=\"b\\\\a\\\"r\"; file*=utf-8''T%C3%A4st"
    >>> ct, d = _parse_header(d)
    >>> ct
    'form-data'
    >>> d['file'] == r'T\u00e4st'.encode('ascii').decode('unicode_escape')
    True
    >>> d['foo']
    'b\\a"r'
    R   t   DummyR8   R   i    i   i   R   i(   R   R8   (   R   t   nextR   RD   Ri   R   R   R   R   t   decode_paramst   popt   collapse_rfc2231_valueR    (	   RE   R   R"   t   paramst   pt   iR7   R8   t   pdict(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR     s$    	 2c         C` sv   | s
 |  S|  g } xS t  | j    D]? \ } } | d k rN | j |  q& | j d | | f  q& Wd j |  S(   s   Inverse of _parse_header.

    >>> _encode_header('permessage-deflate',
    ...     {'client_max_window_bits': 15, 'client_no_context_takeover': None})
    'permessage-deflate; client_max_window_bits=15; client_no_context_takeover'
    s   %s=%ss   ; N(   t   sortedR<   R+   R   R   (   R"   R  t   outR3   R4   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   _encode_header  s    	c         C` s`   t  |  t  r$ t j d |   }  n  t  | t  rH t j d |  } n  t |   d t |  S(   s   Encodes a username/password pair in the format used by HTTP auth.

    The return value is a byte string in the form ``username:password``.

    .. versionadded:: 5.1
    t   NFCR?   (   R-   R	   t   unicodedatat	   normalizeR   (   t   usernamet   password(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   encode_username_password  s
    c          C` s   d d  l  }  |  j   S(   Ni    (   t   doctestt   DocTestSuite(   R  (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   doctests  s    c         C` sU   t  j d |   } | r? | j d  } t | j d   } n |  } d } | | f S(   s   Returns ``(host, port)`` tuple from ``netloc``.

    Returned ``port`` will be ``None`` if not present.

    .. versionadded:: 4.1
    s   ^(.+):(\d+)$i   i   N(   R   R   R   R   R+   (   t   netlocR   Rg   t   port(    (    s/   lib/python2.7/site-packages/tornado/httputil.pyRh     s    c         c` s=   x6 |  j    D]( \ } } x | D] } | | f Vq  Wq Wd S(   sg   Generator converting a result of ``parse_qs`` back to name-value pairs.

    .. versionadded:: 5.0
    N(   R<   (   t   qsR3   t   vsR4   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt	   qs_to_qsl  s    s   \\[0-3][0-7][0-7]s   [\\].RT   c         C` s  |  d k s t |   d k  r" |  S|  d d k sB |  d d k rF |  S|  d d !}  d } t |   } g  } x9d | k o | k  n rt j |  |  } t j |  |  } | r | r | j |  |  Pn  d } } | r | j d  } n  | r| j d  } n  | rZ| s$| | k  rZ| j |  | | ! | j |  | d  | d } qn | j |  | | ! | j t t |  | d | d !d    | d } qn Wt	 |  S(	   s   Handle double quotes and escaping in cookie values.

    This method is copied verbatim from the Python 3.5 standard
    library (http.cookies._unquote) so we don't have to depend on
    non-public interfaces.
    i   i    R   ii   i   i   N(
   R+   R    t
   _OctalPattt   searcht
   _QuotePattR   R   t   chrR   t	   _nulljoin(   t   strR  R   t   rest   o_matcht   q_matcht   jR3   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   _unquote_cookie  s6    	 
+c         C` s   i  } x |  j  t d   D] } t d  | k rU | j  t d  d  \ } } n t d  | } } | j   | j   } } | s | r t |  | | <q q W| S(   s[  Parse a ``Cookie`` HTTP header into a dict of name/value pairs.

    This function attempts to mimic browser cookie parsing behavior;
    it specifically does not follow any of the cookie-related RFCs
    (because browsers don't either).

    The algorithm used is identical to that used by Django version 1.9.10.

    .. versionadded:: 4.4.2
    R   R   i   RT   (   R   R  RD   R  (   t   cookiet
   cookiedictR   R"   R   (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyR   0  s    !(U   R'   t
   __future__R    R   R   R   R   RS   R   t   email.utilsR   R   R   Rn   R  R{   t   tornado.escapeR   R   R   t   tornado.logR   t   tornado.utilR   R   R	   t   http.cookiesR   R   t   http.clientR
   t   urllib.parseR   R   R   R   t   httplibt   urllibt   sslR   t   ImportErrorR   R   t   typingt   compileRH   R   R   R6   t   MutableMappingR(   t   objectRZ   RA   R   R   R   R   R   R   R   R   R   R+   R   R   R   t
   namedtupleR   R   R   R   R   R   R  R  R  Rh   R  R  R  R   R  R  R   (    (    (    s/   lib/python2.7/site-packages/tornado/httputil.pyt   <module>   s   %
	(-	&	1		$	3					#					
		2