HEX
Server: LiteSpeed
System: Linux php-prod-1.spaceapp.ru 5.15.0-157-generic #167-Ubuntu SMP Wed Sep 17 21:35:53 UTC 2025 x86_64
User: xnsbb3110 (1041)
PHP: 8.1.33
Disabled: NONE
Upload Files
File: //usr/local/CyberPanel/lib64/python3.10/site-packages/tornado/__pycache__/httputil.cpython-310.pyc
o

��h���
@s~dZddlZddlZddlZddlZddlZddlm	Z	ddl
mZddlZ
ddlZddlmZddlZddlZddlmZmZmZmZddlmZmZmZddlmZdd	lmZm Z eddl!Z!dd
l!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,e!j-r�ddl!m.Z.ddl/m0Z0ddl1Z1d
Z2e	d�de3de3fdd��Z4Gdd�dej5j6�Z7Gdd�de8�Z9Gdd�de:�Z;Gdd�de:�Z<Gdd�de8�Z=Gdd�de8�Z>Gdd �d e8�Z?d!e3d"e(de'e3e3fe$e"e3e3fe"e"e3e3fd#ffde3fd$d%�Z@Gd&d'�d'e�ZAd(e3de)e"e)eBe)eBffd)d*�ZCd+e)eBd,e)eBd-eBde3fd.d/�ZDd0e3de)eBfd1d2�ZE	djd3e3d4eFd5e'e3e$eFfd6e'e3e$eAfd7e)e7ddfd8d9�ZGd:eFd;eFd5e'e3e$eFfd6e'e3e$eAfddf
d<d=�ZHd>e(eBeIeJejKejfde3fd?d@�ZLe�MdAgdB��ZNe�OdC�ZPdDe3deNfdEdF�ZQe�MdGgdH��ZRe�OdI�ZSdDe3deRfdJdK�ZTdLe3de+e3ddffdMdN�ZUdDe3de"e3e'e3e3fffdOdP�ZVdQe3dRe'e3e3fde3fdSdT�ZWdUe(e3eFfdVe(e3eFfdeFfdWdX�ZXdYdZ�ZYe�Od[�ZZd\e3de"e3e)eBffd]d^�Z[d_e'e3e$e,fde#e"e3e,ffd`da�Z\e�Odb�Z]e�Odc�Z^ddj_Z`dLe3de3fdedf�Zadge3de'e3e3ffdhdi�ZbdS)kz�HTTP utility code shared by clients and servers.

This module also defines the `HTTPServerRequest` class which is exposed
via `tornado.web.RequestHandler.request`.
�N)�	lru_cache)�	responses)�SSLError)�	urlencode�urlparse�
urlunparse�	parse_qsl)�
native_str�parse_qs_bytes�utf8)�gen_log)�
ObjectDict�unicode_type)�Tuple�Iterable�List�Mapping�Iterator�Dict�Union�Optional�	Awaitable�	Generator�AnyStr)�Deque)�Futurez 	i��name�returncCsd�dd�|�d�D��S)ziMap a header name to Http-Header-Case.

    >>> _normalize_header("coNtent-TYPE")
    'Content-Type'
    �-cSsg|]}|���qS�)�
capitalize)�.0�wrr�F/usr/local/CyberPanel/lib/python3.10/site-packages/tornado/httputil.py�
<listcomp>Lsz%_normalize_header.<locals>.<listcomp>)�join�split)rrrr#�_normalize_headerEsr'c@s�eZdZdZejdeeeefddfdd��Z	ejdeeefddfdd��Z	ejde
eefddfd	d��Z	ejd
eddfdd��Z	dejd
eddfdd�Z	d
ededdfdd�Zd
edeefdd�Z
dee
eeffdd�Zdeddfdd�Zededdfdd��Zd
ededdfdd�Zd
edefdd�Zd
eddfdd �Zdefd!d"�Zdeejfd#d$�Zd)d%d&�ZeZdefd'd(�ZeZdS)*�HTTPHeadersa�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
    �_HTTPHeaders__argrNcC�dS�Nr��selfr)rrr#�__init__l�zHTTPHeaders.__init__cCr*r+rr,rrr#r.pr/�argscGr*r+r)r-r0rrr#r.tr/�kwargscKr*r+r)r-r1rrr#r.xr/cOsri|_i|_d|_t|�dkr/t|�dkr/t|dt�r/|d��D]
\}}|�||�q"dS|j|i|��dS)N�r)	�_dict�_as_list�	_last_key�len�
isinstancer(�get_all�add�update)r-r0r1�k�vrrr#r.|s&�r�valuecCsTt|�}||_||vr$t||�dt|�|j|<|j|�|�dS|||<dS)z#Adds a new value for the given key.�,N)r'r5r	r3r4�append�r-rr=�	norm_namerrr#r9�s�zHTTPHeaders.addcCst|�}|j�|g�S)z2Returns all values for the given header as a list.)r'r4�get�r-rrArrr#�get_list�szHTTPHeaders.get_listccs.�|j��D]\}}|D]}||fVqqdS)z�Returns an iterable of all (name, value) pairs.

        If a header has multiple values, multiple pairs will be
        returned with the same name.
        N)r4�items)r-r�valuesr=rrr#r8�s���zHTTPHeaders.get_all�linecCs�|d��r.|jdurtd��d|�t�}|j|jd|7<|j|j|7<dSz
|�dd�\}}WntyCtd��w|�	||�
t��dS)	z�Updates the dictionary with a single header line.

        >>> h = HTTPHeaders()
        >>> h.parse_line("Content-Type: text/html")
        >>> h.get('content-type')
        'text/html'
        rNz.first header line cannot start with whitespace� ����:r2zno colon in header line)�isspacer5�HTTPInputError�lstrip�HTTP_WHITESPACEr4r3r&�
ValueErrorr9�strip)r-rG�new_partrr=rrr#�
parse_line�s
�zHTTPHeaders.parse_line�headerscCs>|�}|�d�D]}|�d�r|dd�}|r|�|�q|S)a�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`.

        �
�
NrI)r&�endswithrR)�clsrS�hrGrrr#�parse�s

�zHTTPHeaders.parsecCs"t|�}||j|<|g|j|<dSr+�r'r3r4r@rrr#�__setitem__�s
zHTTPHeaders.__setitem__cCs|jt|�Sr+)r3r')r-rrrr#�__getitem__�szHTTPHeaders.__getitem__cCst|�}|j|=|j|=dSr+rZrCrrr#�__delitem__�szHTTPHeaders.__delitem__cC�
t|j�Sr+)r6r3�r-rrr#�__len__��
zHTTPHeaders.__len__cCr^r+)�iterr3r_rrr#�__iter__�razHTTPHeaders.__iter__cCst|�Sr+)r(r_rrr#�copy�szHTTPHeaders.copycCs2g}|��D]
\}}|�d||f�qd�|�S)Nz%s: %s
�)r8r?r%)r-�linesrr=rrr#�__str__�s
zHTTPHeaders.__str__)rr()�__name__�
__module__�__qualname__�__doc__�typing�overloadr�strrr.r�Anyr9rDrr8rR�classmethodrYr[r\r]�intr`rrcrd�__copy__rg�__unicode__rrrr#r(Os4 

r(c@s
eZdZdZdZdZdZ										d"deedeededee	dee
d	eed
eeeedfded
deddee
ddfdd�Zedeeejjffdd��Zdefdd�Zdefdd�Z	d#dededee
ffdd�Zd$dd�Zdefd d!�ZdS)%�HTTPServerRequesta7
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``.
    N�HTTP/1.0�method�uri�versionrS�body�host�files�HTTPFile�
connection�HTTPConnection�
start_line�RequestStartLine�server_connectionrc
Cs�|	dur	|	\}}}||_||_||_|pt�|_|pd|_t|dd�}t|dd�|_t|dd�|_|p:|j�	d�p:d|_
t|j
���d|_
|pIi|_||_|
|_t��|_d|_|durg|�d	�\|_}|_t|jd
d�|_t�|j�|_i|_dS)N��context�	remote_ip�protocol�http�Hostz	127.0.0.1r�?T��keep_blank_values)rvrwrxr(rSry�getattrr�r�rBrz�split_host_and_port�lower�	host_namer{r}r��time�_start_time�_finish_time�	partition�path�queryr
�	argumentsrd�deepcopy�query_arguments�body_arguments)
r-rvrwrxrSryrzr{r}rr�r��seprrr#r.]s,




zHTTPServerRequest.__init__c	Cs�t|d�s>tj��|_d|jvr>z	t|jd�}Wnty$Y|jSw|��D]\}}z||j|<Wq)ty=Yq)w|jS)z0A dictionary of ``http.cookies.Morsel`` objects.�_cookies�Cookie)	�hasattrr��cookies�SimpleCookier�rS�parse_cookie�	ExceptionrE)r-�parsedr;r<rrr#r��s"
�

��zHTTPServerRequest.cookiescCs|jd|j|jS)z+Reconstructs the full URL for this request.z://)r�rzrwr_rrr#�full_url�szHTTPServerRequest.full_urlcCs$|jdurt��|jS|j|jS)z?Returns the amount of time it took for this request to execute.N)r�r�r�r_rrr#�request_time�s
zHTTPServerRequest.request_timeF�binary_formcCs:z|jdur	WdS|jjjj|d�WStyYdSw)a>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
        N)r�)r}�stream�socket�getpeercertr)r-r�rrr#�get_ssl_certificate�s

��z%HTTPServerRequest.get_ssl_certificatecCsNt|j�dd�|j|j|j|j�|j��D]\}}|j�|g��	|�qdS)N�Content-Typere)
�parse_body_argumentsrSrBryr�r{rEr��
setdefault�extend)r-r;r<rrr#�_parse_body�s��zHTTPServerRequest._parse_bodycs,d}d��fdd�|D��}d�jj|fS)N)r�rzrvrwrxr�z, csg|]}d|t�|�f�qS)z%s=%r)r�)r!�nr_rr#r$�sz.HTTPServerRequest.__repr__.<locals>.<listcomp>z%s(%s))r%�	__class__rh)r-�attrsr0rr_r#�__repr__�szHTTPServerRequest.__repr__)
NNruNNNNNNN)F�rN)rhrirjrkr�r��_body_futurerrnr(�bytesrr�objectr.�propertyr�r��Morselr��floatr��boolrr�r�r�rrrr#rt�sd\��������	�
��
�(��
�
rtc@�eZdZdZdS)rLzqException class for malformed HTTP requests or responses
    from remote sources.

    .. versionadded:: 4.0
    N�rhrirjrkrrrr#rL�srLc@r�)�HTTPOutputErrorzJException class for errors in HTTP output.

    .. versionadded:: 4.0
    Nr�rrrr#r��sr�c@s8eZdZdZdeddddfdd�Zdedd	fd
d�Zd	S)�HTTPServerConnectionDelegatez_Implement this interface to handle requests from `.HTTPServer`.

    .. versionadded:: 4.0
    �server_conn�request_connr~r�HTTPMessageDelegatecC�t��)ajThis 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`.
        ��NotImplementedError)r-r�r�rrr#�
start_request�sz*HTTPServerConnectionDelegate.start_requestNcC�dS)z�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``.
        Nr)r-r�rrr#�on_close��z%HTTPServerConnectionDelegate.on_close)rhrirjrkr�r�r�rrrr#r��s��
�r�c@s`eZdZdZdeddedeedfdd�Zd	e	deedfd
d�Z
ddd
�Zddd�ZdS)r�z_Implement this interface to handle an HTTP request or response.

    .. versionadded:: 4.0
    r�r��ResponseStartLinerSrNcCr�)a�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.
        Nr)r-rrSrrr#�headers_receivedsz$HTTPMessageDelegate.headers_received�chunkcCr�)ziCalled when a chunk of data has been received.

        May return a `.Future` for flow control.
        Nr�r-r�rrr#�
data_received"sz!HTTPMessageDelegate.data_receivedcCr�)z6Called after the last chunk of data has been received.Nrr_rrr#�finish)r/zHTTPMessageDelegate.finishcCr�)z�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.
        Nrr_rrr#�on_connection_close-r�z'HTTPMessageDelegate.on_connection_closer�)
rhrirjrkrr(rrr�r�r�r�r�rrrr#r�s��

�
r�c	@sReZdZdZ	ddeddedeeddfd	d
�Zdeddfdd�Z	dd
d�Z
dS)r~zYApplications use this interface to write their responses.

    .. versionadded:: 4.0
    Nrr�rSr�rzFuture[None]cCr�)aWrite 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.

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

        Returns a future for flow control.

        .. versionchanged:: 6.0

           The ``callback`` argument was removed.
        r�)r-rrSr�rrr#�
write_headers<szHTTPConnection.write_headerscCr�)z�Writes a chunk of body data.

        Returns a future for flow control.

        .. versionchanged:: 6.0

           The ``callback`` argument was removed.
        r�r�rrr#�writeTs	zHTTPConnection.writecCr�)z3Indicates that the last body data has been written.r�r_rrr#r�_szHTTPConnection.finishr+r�)rhrirjrkrr(rr�r�r�r�rrrr#r~6s	����
�r~�urlr0.cCs�|dur|St|�}t|t�rt|jdd�}|�|���n"t|t�s(t|t�r5t|jdd�}|�|�nd�	t
|��}t|��t|�}t
|d|d|d|d||d	f�}|S)
aConcatenate 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'
    NTr�z7'args' parameter should be dict, list or tuple. Not {0}rr2���)rr7�dictrr�r�rE�list�tuple�format�type�	TypeErrorrr)r�r0�
parsed_url�parsed_query�err�final_queryrrr#�
url_concatds0
���
r�c@s*eZdZUdZeed<eed<eed<dS)r|z�Represents a file uploaded via a form.

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

    * ``filename``
    * ``body``
    * ``content_type``
    �filenamery�content_typeN)rhrirjrkrn�__annotations__r�rrrr#r|�s


r|�range_headercCs�|�d�\}}}|��|��}}|dkrdS|�d�\}}}z
t|�}t|�}Wn
ty3YdSw|durM|durI|dkrE|}d}||fS|d7}||fS)agParses 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
    �=r�Nrrr2)r�rP�_int_or_nonerO)r��unit�_r=�start_b�end_b�start�endrrr#�_parse_request_range�s&��r�r�r��totalcCs"|pd}|p|d}d|||fS)z�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
    rr2zbytes %s-%s/%sr)r�r�r�rrr#�_get_content_range�s
r��valcCs|��}|dkr
dSt|�S)Nre)rPrq)r�rrr#r��sr�r�ryr�r{rSc
CsT|�d�rN|rd|vrt�d|d�dSzt|dd�}Wnty7}zt�d|�i}WYd}~nd}~ww|��D]\}}|rK|�|g��|�q<dS|�d�r�|rcd|vrct�d|d�dSz+|�d	�}	|	D]}
|
�	��
d
�\}}}
|dkr�|
r�tt|
�|||�WdSqkt
d��ty�}z
t�d
|�WYd}~dSd}~wwdS)aFParses 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.
    z!application/x-www-form-urlencodedzContent-Encodingz Unsupported Content-Encoding: %sNTr�z&Invalid x-www-form-urlencoded body: %szmultipart/form-data�;r��boundaryzmultipart boundary not foundzInvalid multipart/form-data: %s)�
startswithr�warningr
r�rEr�r�r&rPr��parse_multipart_form_datarrO)r�ryr�r{rS�
uri_arguments�errF�fields�fieldr;r�r<rrr#r��sL
�����
�
����r�r��datacCsZ|�d�r|�d�r|dd�}|�d|d�}|dkr$t�d�dS|d|��d|d�}|D]w}|s8q3|�d�}|dkrGt�d	�q3t�|d|��	d
��}|�
dd�}	t|	�\}
}|
d
ksh|�d�snt�d�q3||dd�}|�
d�s�t�d�q3|d}
|�
d�r�|�
dd�}|�|
g��
t|d||d��q3|�|
g��
|�q3dS)a]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.
    �"r2rIs--z.Invalid multipart/form-data: no final boundaryNs
s

z#multipart/form-data missing headerszutf-8zContent-Dispositionrez	form-datazInvalid multipart/form-data����rz&multipart/form-data value missing namer�r�zapplication/unknown)r�ryr�)r�rV�rfindrr�r&�findr(rY�decoderB�
_parse_headerr�r?r|)r�r�r�r{�final_boundary_index�parts�part�eohrS�disp_header�disposition�disp_paramsr=r�ctyperrr#r�sD







���r��tscCsht|ttf�r
|}n"t|ttjf�rt�|�}nt|tj�r&t�|�	��}nt
d|��tjj
|dd�S)a�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. Naive `datetime.datetime` objects are assumed to represent
    UTC; aware objects are converted to UTC before formatting.

    >>> format_timestamp(1359312200)
    'Sun, 27 Jan 2013 18:43:20 GMT'
    zunknown timestamp type: %rT)�usegmt)r7rqr�r�r��struct_time�calendar�timegm�datetime�utctimetupler��email�utils�
formatdate)r
�time_numrrr#�format_timestampWs
rr�)rvr�rxz^HTTP/1\.[0-9]$rGcCsNz
|�d�\}}}Wntytd��wt�|�s!td|��t|||�S)z�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')
    rHzMalformed HTTP request linez/Malformed HTTP version in HTTP Request-Line: %r)r&rOrL�_http_version_re�matchr�)rGrvr�rxrrr#�parse_request_start_linews�
�rr�)rx�code�reasonz (HTTP/1.[0-9]) ([0-9]+) ([^\r]*)cCs@t|�}t�|�}|std��t|�d�t|�d��|�d��S)z�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')
    z!Error parsing response start liner2r�r�)r	�_http_response_line_rerrLr��grouprq)rGrrrr#�parse_response_start_line�s

"r�sccs��|dd�dkrg|dd�}|�d�}|dkrD|�dd|�|�dd|�drD|�d|d�}|dkrD|�dd|�|�dd|�ds(|dkrLt|�}|d|�}|��V||d�}|dd�dks	dSdS)Nr2r�r�"z\"r�)r��countr6rP)rr��frrr#�_parseparam�s�
((�
�r"cCs�td|�}t|�}dg}|D](}|�d�}|dkr7|d|�����}||dd���}|�|t|�f�qtj�	|�}|�
d�i}	|D]&\}}
tj�|
�}t|�dkri|ddkri|d	dkri|dd	�}||	|<qG||	fS)
aYParse 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�)�Dummyr=r�rNr2r�rrI)
r"�nextr�rPr�r?r	rr�
decode_params�pop�collapse_rfc2231_valuer6)rGr�key�params�p�irr=�decoded_params�pdict�
decoded_valuerrr#r�s&
�
$
rr(r-cCsT|s|S|g}t|���D]\}}|dur|�|�q
|�d||f�q
d�|�S)z�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'
    Nz%s=%sz; )�sortedrEr?r%)r(r-�outr;r<rrr#�_encode_header�s
r1�username�passwordcCs@t|t�rt�d|�}t|t�rt�d|�}t|�dt|�S)z�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
    �NFC�:)r7r�unicodedata�	normalizer)r2r3rrr#�encode_username_password�s

	
r8cCsddl}|��S)Nr)�doctest�DocTestSuite)r9rrr#�doctests�sr;z^(.+):(\d+)$�netloccCs>t�|�}|r|�d�}t|�d��}||fS|}d}||fS)z�Returns ``(host, port)`` tuple from ``netloc``.

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

    .. versionadded:: 4.1
    r2r�N)�
_netloc_rerrrq)r<rrz�portrrr#r�	s

�r��qsccs,�|��D]\}}|D]}||fVqqdS)zgGenerator converting a result of ``parse_qs`` back to name-value pairs.

    .. versionadded:: 5.0
    N)rE)r?r;�vsr<rrr#�	qs_to_qsls���rAz\\[0-3][0-7][0-7]z[\\].recCsn|dus
t|�dkr|S|ddks|ddkr|S|dd�}d}t|�}g}d|kr2|kr�nt|�St�||�}t�||�}|sU|sU|�||d��	t|�Sd}}|r`|�d�}|rg|�d�}|r�|ro||kr�|�|||��|�||d�|d}n|�|||��|�tt||d|d�d���|d}d|kr�|ks7t|�St|�S)	z�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.
    Nr�rrrIr2r��)	r6�
_OctalPatt�search�
_QuotePattr?r��chrrq�	_nulljoin)rr+r��res�o_match�q_match�jr;rrr#�_unquote_cookie)s@	��


$��rL�cookiecCsri}|�td��D]-}td�|vr|�td�d�\}}ntd�|}}|��|��}}|s0|r6t|�||<q	|S)a[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�r2re)r&rnrPrL)rM�
cookiedictr�r(r�rrr#r�[s�r�r+)crkr
�collections.abc�collectionsrdr�email.utilsr�	functoolsr�http.clientr�http.cookiesr��re�sslrr�r6�urllib.parserrrr�tornado.escaper	r
r�tornado.logr�tornado.utilr
rrlrrrrrrrrrrr�
TYPE_CHECKINGr�asyncior�unittestrNrnr'�abc�MutableMappingr(r�rtr�rLr�r�r�r~r�r|rqr�r�r�r�r�r�r�r�rr�
namedtupler��compilerrr�rrr"rr1r8r;r=r�rArCrEr%rGrLr�rrrr#�<module>s�4	,_
	..�.��
�/�
�"3������
�1����
�:�
��
�
"
#
�
�
�
*


2