ó
    <ÕÎiB‘  ã                   ó"  • S r SSKrSSKrSSKrSSKrSSKrSSKJ	r	  SSK
Jr  SSKrSSKrSSKJr  SSKrSSKrSSKJrJrJrJr  SSKJrJrJr  SSKJrJr  \  SSKrSS	KJ r J!r!J"r"J#r#J$r$J%r%J&r&J'r'J(r(J)r)J*r*  \RV                  (       a  SS
KJ,r,  SSK-J.r.  SSK/r/Sr0\	" S5      S\1S\14S j5       r2 " S S\Rf                  Rh                  5      r5 " S S\65      r7 " S S\85      r9 " S S\85      r: " S S\65      r; " S S\65      r< " S S\65      r=S\1S \&S\%\1\14   \"\ \1\14      \ \ \1\14   S!4   4   S\14S" jr> " S# S$\5      r?S%\1S\'\ \'\@   \'\@   4      4S& jrAS'\'\@   S(\'\@   S)\@S\14S* jrBS+\1S\'\@   4S, jrC SVS-\1S.\DS/\%\1\"\D   4   S0\%\1\"\?   4   S1\'\5   SS4S2 jjrES3\DS4\DS/\%\1\"\D   4   S0\%\1\"\?   4   SS4
S5 jrFS6\&\@\G\H\R’                  \R
                  4   S\14S7 jrJ\R–                  " S8/ S9Q5      rL\Rš                  " S:5      rNS;\1S\L4S< jrO\R–                  " S=/ S>Q5      rP\Rš                  " S?5      rQS;\1S\P4S@ jrRSA\1S\)\1SS4   4SB jrSS;\1S\ \1\%\1\14   4   4SC jrTSD\1SE\%\1\14   S\14SF jrUSG\&\1\D4   SH\&\1\D4   S\D4SI jrVSJ rW\Rš                  " SK5      rXSL\1S\ \1\'\@   4   4SM jrYSN\%\1\"\*   4   S\!\ \1\*4      4SO jrZ\Rš                  " SP5      R¶                  r\SQ\Rº                  S\14SR jr^SA\1S\14SS jr_ST\1S\%\1\14   4SU jr`g)Wz¤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)Ú
ObjectDictÚunicode_type)ÚTupleÚIterableÚListÚMappingÚIteratorÚDictÚUnionÚOptionalÚ	AwaitableÚ	GeneratorÚAnyStr)ÚDeque)ÚFuturez 	iè  ÚnameÚreturnc                 óˆ   • SR                  U R                  S5       Vs/ s H  oR                  5       PM     sn5      $ s  snf )z]Map a header name to Http-Header-Case.

>>> _normalize_header("coNtent-TYPE")
'Content-Type'
Ú-)ÚjoinÚsplitÚ
capitalize)r   Úws     Ú2/usr/lib/python3/dist-packages/tornado/httputil.pyÚ_normalize_headerr%   D   s1   € ð �8‰8¨T¯Z©Z¸¬_Ó=ª_¨—\‘\–^©_Ñ=Ó>Ð>ùÒ=s   Ÿ?c                   óB  • \ rS rSrSr\R                  S\\\	\   4   SS4S j5       r
\R                  S\\\4   SS4S j5       r
\R                  S\\\4   SS4S	 j5       r
\R                  S
\SS4S j5       r
S\R                  S
\SS4S jr
S\S\SS4S jrS\S\	\   4S jrS\\\\4      4S jrS\SS4S jr\S\SS 4S j5       rS\S\SS4S jrS\S\4S jrS\S\4S jrS\SS4S jrS\4S jrS\\R                     4S jrSS jr\rS\4S jr \ r!Sr"g) ÚHTTPHeaderséN   a…  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__argr   Nc                 ó   • g ©N© ©Úselfr)   s     r$   Ú__init__ÚHTTPHeaders.__init__k   ó   € àó    c                 ó   • g r+   r,   r-   s     r$   r/   r0   o   r1   r2   Úargsc                 ó   • g r+   r,   )r.   r4   s     r$   r/   r0   s   r1   r2   Úkwargsc                 ó   • g r+   r,   )r.   r6   s     r$   r/   r0   w   r1   r2   c                 ó  • 0 U l         0 U l        S U l        [        U5      S:X  aU  [        U5      S:X  aF  [	        US   [
        5      (       a.  US   R                  5        H  u  p4U R                  X45        M     g U R                  " U0 UD6  g )Né   r   )	Ú_as_listÚ_combined_cacheÚ	_last_keyÚlenÚ
isinstancer'   Úget_allÚaddÚupdate)r.   r4   r6   ÚkÚvs        r$   r/   r0   {   su   € ð /1ˆŒØ/1ˆÔØˆŒÜˆt‹9˜‹>œc &›k¨QÓ.´:¸dÀ1¹gÄ{×3SÑ3Sà˜Q™Ÿ™Ö)‘�Ø—‘˜–ò *ð �KŠK˜Ð( Ó(r2   r   Úvaluec                 ó®   • [        U5      nX0l        X0;   a;  U R                  R                  US5        U R                  U   R                  U5        gX U'   g)z#Adds a new value for the given key.N)r%   r<   r;   Úpopr:   Úappend©r.   r   rD   Ú	norm_names       r$   r@   ÚHTTPHeaders.add�   sK   € ä% dÓ+ˆ	Ø"ŒØÓØ× Ñ ×$Ñ$ Y°Ô5Ø�M‰M˜)Ñ$×+Ñ+¨EÕ2à#�ŠOr2   c                 óP   • [        U5      nU R                  R                  U/ 5      $ )z2Returns all values for the given header as a list.)r%   r:   Úget©r.   r   rI   s      r$   Úget_listÚHTTPHeaders.get_list™   s#   € ä% dÓ+ˆ	Ø�}‰}× Ñ  ¨BÓ/Ð/r2   c              #   ón   #   • U R                   R                  5        H  u  pU H  nX4v •  M
     M     g7f)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)r:   Úitems)r.   r   ÚvaluesrD   s       r$   r?   ÚHTTPHeaders.get_allž   s2   é € ð !ŸM™M×/Ñ/Ö1‰LˆDÛ�Ø�mÔ#ó  ò 2ùs   ‚35Úlinec                 óÎ  • US   R                  5       (       a{  U R                  c  [        S5      eSUR                  [        5      -   nU R
                  U R                     S==   U-  ss'   U R                  R                  U R                  S5        g UR                  SS5      u  p4U R                  X4R                  [        5      5        g! [         a    [        S5      ef = f)	z›Updates the dictionary with a single header line.

>>> h = HTTPHeaders()
>>> h.parse_line("Content-Type: text/html")
>>> h.get('content-type')
'text/html'
r   Nz.first header line cannot start with whitespaceÚ éÿÿÿÿÚ:r9   zno colon in header line)Úisspacer<   ÚHTTPInputErrorÚlstripÚHTTP_WHITESPACEr:   r;   rF   r!   Ú
ValueErrorr@   Ústrip)r.   rT   Únew_partr   rD   s        r$   Ú
parse_lineÚHTTPHeaders.parse_line¨   sÃ   € ð �‰7�?‰?×Ñà�~‰~Ñ%Ü$Ð%UÓVÐVØ˜TŸ[™[¬Ó9Ñ9ˆHØ�M‰M˜$Ÿ.™.Ñ)¨"Ó-°Ñ9Ó-Ø× Ñ ×$Ñ$ T§^¡^°TÕ:ð@Ø"Ÿj™j¨¨aÓ0‘�ð �H‰H�TŸ;™;¤Ó7Õ8øô ó @Ü$Ð%>Ó?Ð?ð@ús   ÂC ÃC$Úheadersc                 ó®   • U " 5       nUR                  S5       H8  nUR                  S5      (       a  USS nU(       d  M'  UR                  U5        M:     U$ )aL  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`.

Ú
ÚNrW   )r!   Úendswithr`   )Úclsrb   ÚhrT   s       r$   ÚparseÚHTTPHeaders.parse¾   sR   € ñ ‹Eˆð —M‘M $Ö'ˆDØ�}‰}˜T×"Ñ"Ø˜C˜R�y�ßˆtØ—‘˜TÖ"ñ	 (ð
 ˆr2   c                 óV   • [        U5      nX R                  U'   U/U R                  U'   g r+   ©r%   r;   r:   rH   s       r$   Ú__setitem__ÚHTTPHeaders.__setitem__Ø   s*   € Ü% dÓ+ˆ	Ø*/×Ñ˜YÑ'Ø$) 7ˆ�‰�iÒ r2   c                 ó`   • [        U[        5      (       d  g[        U5      nX R                  ;   $ )NF)r>   Ústrr%   r:   rM   s      r$   Ú__contains__ÚHTTPHeaders.__contains__Ý   s+   € ô ˜$¤×$Ñ$ØÜ% dÓ+ˆ	ØŸM™MÑ)Ð)r2   c                 óª   • [        U5      nX R                  ;  a+  SR                  U R                  U   5      U R                  U'   U R                  U   $ )NÚ,)r%   r;   r    r:   )r.   r   Úheaders      r$   Ú__getitem__ÚHTTPHeaders.__getitem__å   sK   € Ü" 4Ó(ˆØ×-Ñ-Ó-Ø+.¯8©8°D·M±MÀ&Ñ4IÓ+JˆD× Ñ  Ñ(Ø×#Ñ# FÑ+Ð+r2   c                 óN   • [        U5      nU R                  U	 U R                  U	 g r+   rl   rM   s      r$   Ú__delitem__ÚHTTPHeaders.__delitem__ë   s&   € Ü% dÓ+ˆ	Ø× Ñ  Ð+Ø�M‰M˜)Ñ$r2   c                 ó,   • [        U R                  5      $ r+   )r=   r:   ©r.   s    r$   Ú__len__ÚHTTPHeaders.__len__ð   s   € Ü�4—=‘=Ó!Ð!r2   c                 ó,   • [        U R                  5      $ r+   )Úiterr:   r|   s    r$   Ú__iter__ÚHTTPHeaders.__iter__ó   s   € Ü�D—M‘MÓ"Ð"r2   c                 ó   • [        U 5      $ r+   )r'   r|   s    r$   ÚcopyÚHTTPHeaders.copyö   s   € ä˜4Ó Ð r2   c                 óŒ   • / nU R                  5        H  u  p#UR                  U< SU< S35        M      SR                  U5      $ )Nz: rd   Ú )r?   rG   r    )r.   Úlinesr   rD   s       r$   Ú__str__ÚHTTPHeaders.__str__ÿ   s8   € ØˆØŸ<™<ž>‰KˆDØ�L‰L£t«UÐ3Ö4ñ *à�w‰w�u‹~Ðr2   )r:   r;   r<   )r   r'   )#Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚtypingÚoverloadr   rp   r   r/   r   ÚAnyr@   rN   r   r?   r`   Úclassmethodri   rm   ÚobjectÚboolrq   rv   ry   Úintr}   r   r�   r„   Ú__copy__r‰   Ú__unicode__Ú__static_attributes__r,   r2   r$   r'   r'   N   sí  † ñð8 ‡_�_ð˜g c¨4°©9 nÑ5ð ¸$ó ó ðð ‡_�_ð˜g c¨3 hÑ/ð °Dó ó ðð ‡_�_ð˜e C¨ H™oð °$ó ó ðð ‡_�_ð ð ¨ó ó ðð)˜fŸj™jð )°Cð )¸Dô )ð($˜ð $ Cð $¨Dô $ð0˜Sð 0 T¨#¡Yô 0ð
$˜ %¨¨S¨¡/Ñ2ô $ð9˜sð 9 tô 9ð, ð˜Cð  Mó ó ðð2+ ð +¨Cð +°Dô +ð
* ð *¨Dô *ð, ð ,¨ô ,ð% ð %¨ô %ð
"˜ô "ð#˜( 6§:¡:Ñ.ô #ô!ð €Hð˜ô ð ƒKr2   r'   c                   óZ  • \ rS rSrSrSrSrSr          SS\\	   S\\	   S\	S\\
   S\\   S	\\	   S
\\\	\S   4      S\S   S\S   S\\   SS4S jjr\S\\	\R$                  R&                  4   4S j5       rS\	4S jrS\4S jr SS\S\S\\4   4S jjrSS jrS\	4S jrSrg)ÚHTTPServerRequesti  a[	  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ÚmethodÚuriÚversionrb   ÚbodyÚhostÚfilesÚHTTPFileÚ
connectionÚHTTPConnectionÚ
start_lineÚRequestStartLineÚserver_connectionr   c                 óê  • U	b  U	u  pnXl         X l        X0l        U=(       d
    [        5       U l        U=(       d    SU l        [        USS 5      n[        USS 5      U l        [        USS5      U l        U=(       d$    U R                  R                  S5      =(       d    SU l
        [        U R                  R                  5       5      S   U l        U=(       d    0 U l        X€l        X l        ["        R"                  " 5       U l        S U l        Ub  UR)                  S	5      u  U l        oÀl        [/        U R,                  S
S9U l        [2        R4                  " U R0                  5      U l        0 U l        g )Nr2   ÚcontextÚ	remote_ipÚprotocolÚhttpÚHostz	127.0.0.1r   Ú?T©Úkeep_blank_values)rœ   r�   rž   r'   rb   rŸ   Úgetattrrª   r«   rL   r    Úsplit_host_and_portÚlowerÚ	host_namer¡   r£   r§   ÚtimeÚ_start_timeÚ_finish_timeÚ	partitionÚpathÚqueryr   Ú	argumentsr„   ÚdeepcopyÚquery_argumentsÚbody_arguments)r.   rœ   r�   rž   rb   rŸ   r    r¡   r£   r¥   r§   r©   Úseps                r$   r/   ÚHTTPServerRequest.__init__k  s  € ð Ñ!Ø#-Ñ ˆF˜ØŒØŒØŒØ×/¤+£-ˆŒØ—K˜CˆŒ	ô ˜* i°Ó6ˆÜ  ¨+°tÓ<ˆŒÜ ¨°VÓ<ˆŒà×C˜DŸL™L×,Ñ,¨VÓ4×C¸ˆŒ	Ü,¨T¯Y©Y¯_©_Ó->Ó?ÀÑBˆŒØ—[˜bˆŒ
Ø$ŒØ!2ÔÜŸ9š9›;ˆÔØ ˆÔà‰?Ø),¯©°sÓ);Ñ&ˆDŒI�sœJÜ'¨¯
©
ÀdÑKˆŒÜ#Ÿ}š}¨T¯^©^Ó<ˆÔØ ˆÕr2   c                 ó”  • [        U S5      (       d€  [        R                  R                  5       U l        SU R
                  ;   aM   [        U R
                  S   5      nUR                  5        H  u  p# X0R                  U'   M     U R                  $ U R                  $ ! [         a     M=  f = f! [         a     U R                  $ f = f)z0A dictionary of ``http.cookies.Morsel`` objects.Ú_cookiesÚCookie)	Úhasattrr¬   ÚcookiesÚSimpleCookierÂ   rb   Úparse_cookierQ   Ú	Exception)r.   ÚparsedrB   rC   s       r$   rÅ   ÚHTTPServerRequest.cookies“  s½   € ô �t˜Z×(Ñ(ä—‘×)Ñ)Ó+ð ŒMð ˜4Ÿ<™<Ó'ð!Ü)¨$¯,©,°xÑ*@ÓA�Fð !'§¡¦™˜ð!Ø/0ŸM™M¨!Ó,ñ !/ð �}‰}Ðˆt�}‰}Ðøô  )ó !ò !ð	!ûô !ó Øð �}‰}Ððús$   ÁB/ Á4BÂ
B,Â+B,Â/
CÃCc                 óT   • U R                   S-   U R                  -   U R                  -   $ )z+Reconstructs the full URL for this request.z://)r«   r    r�   r|   s    r$   Úfull_urlÚHTTPServerRequest.full_urlª  s#   € à�}‰}˜uÑ$ t§y¡yÑ0°4·8±8Ñ;Ð;r2   c                 ó’   • U R                   c"  [        R                  " 5       U R                  -
  $ U R                   U R                  -
  $ )z?Returns the amount of time it took for this request to execute.)r·   rµ   r¶   r|   s    r$   Úrequest_timeÚHTTPServerRequest.request_time®  s<   € à×ÑÑ$Ü—9’9“; ×!1Ñ!1Ñ1Ð1à×$Ñ$ t×'7Ñ'7Ñ7Ð7r2   Úbinary_formc                 óš   •  U R                   c  gU R                   R                  R                  R                  US9$ ! [         a     gf = f)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Ñ   s     r$   Úget_ssl_certificateÚ%HTTPServerRequest.get_ssl_certificateµ  sS   € ð*	Ø�‰Ñ&Øà—?‘?×)Ñ)×0Ñ0×<Ñ<Ø'ð =ð ð øô ó 	Ùð	ús   ‚= �,= ½
A
Á	A
c                 óB  • [        U R                  R                  SS5      U R                  U R                  U R
                  U R                  5        U R                  R                  5        H0  u  pU R                  R                  U/ 5      R                  U5        M2     g )NúContent-Typer‡   )
Úparse_body_argumentsrb   rL   rŸ   r¾   r¡   rQ   r»   Ú
setdefaultÚextend)r.   rB   rC   s      r$   Ú_parse_bodyÚHTTPServerRequest._parse_bodyÔ  sx   € ÜØ�L‰L×Ñ˜^¨RÓ0Ø�I‰IØ×ÑØ�J‰JØ�L‰Lô	
ð ×'Ñ'×-Ñ-Ö/‰DˆAØ�N‰N×%Ñ% a¨Ó,×3Ñ3°AÖ6ò 0r2   c                 ó®   • SnSR                  U Vs/ s H  o"< S[        X5      < 3PM     sn5      nU R                  R                  < SU< S3$ s  snf )N)r«   r    rœ   r�   rž   rª   z, Ú=Ú(Ú))r    r±   Ú	__class__r‹   )r.   ÚattrsÚnr4   s       r$   Ú__repr__ÚHTTPServerRequest.__repr__à  sI   € ØMˆØ�y‰yÁ5ÓIÂ5¸a¢Q¬°Õ(8Ó9Á5ÑIÓJˆØŸ>™>×2Ô2³DÐ9Ð9ùò Js   ’A)rÂ   r·   r¶   r»   rŸ   r¾   r£   r¡   rb   r    r´   rœ   r¹   r«   rº   r½   rª   r§   r�   rž   )
NNzHTTP/1.0NNNNNNN)F©r   N)r‹   rŒ   r�   rŽ   r�   r¹   rº   Ú_body_futurer   rp   r'   Úbytesr   r   r”   r/   Úpropertyr¬   rÅ   ÚMorselrÌ   ÚfloatrÏ   r•   r   rÖ   rÝ   ræ   r™   r,   r2   r$   r›   r›     sf  † ñZðx €DØ€Eð €Lð !%Ø!Ø!Ø)-Ø $Ø"Ø7;Ø15Ø37Ø.2ñ&!à˜‘ð&!ð �c‰]ð&!ð ð	&!ð
 ˜+Ñ&ð&!ð �u‰oð&!ð �s‰mð&!ð ˜˜S $ zÑ"2Ð2Ñ3Ñ4ð&!ð Ð-Ñ.ð&!ð Ð/Ñ0ð&!ð $ FÑ+ð&!ð 
õ&!ðP ð˜˜c 4§<¡<×#6Ñ#6Ð6Ñ7ó ó ðð,<˜#ô <ð8˜eô 8ð #(ñØðà	ˆt�T˜5Ð Ñ	!õô>
7ð:˜#÷ :r2   r›   c                   ó   • \ rS rSrSrSrg)rZ   iæ  zeException class for malformed HTTP requests or responses
from remote sources.

.. versionadded:: 4.0
r,   N©r‹   rŒ   r�   rŽ   r�   r™   r,   r2   r$   rZ   rZ   æ  s   † ñò 	r2   rZ   c                   ó   • \ rS rSrSrSrg)ÚHTTPOutputErrorið  zBException class for errors in HTTP output.

.. versionadded:: 4.0
r,   Nrï   r,   r2   r$   rñ   rñ   ð  s   † ñò
 	r2   rñ   c                   ó@   • \ rS rSrSrS\SSSS4S jrS\SS	4S
 jrSrg	)ÚHTTPServerConnectionDelegateiù  zWImplement this interface to handle requests from `.HTTPServer`.

.. versionadded:: 4.0
Úserver_connÚrequest_connr¤   r   ÚHTTPMessageDelegatec                 ó   • [        5       e)a:  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`.
©ÚNotImplementedError)r.   rô   rõ   s      r$   Ústart_requestÚ*HTTPServerConnectionDelegate.start_requestÿ  s   € ô "Ó#Ð#r2   Nc                 ó   • g)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ô   s     r$   Úon_closeÚ%HTTPServerConnectionDelegate.on_close  ó   € ð 	r2   r,   )	r‹   rŒ   r�   rŽ   r�   r”   rú   rý   r™   r,   r2   r$   ró   ró   ù  s7   † ñð
$Ø!ð$Ø1Að$à	ô$ð Fð ¨t÷ r2   ró   c                   ór   • \ rS rSrSrS\S   S\S\\S      4S jr	S	\
S\\S      4S
 jrSS jrSS jrSrg)rö   i  zWImplement this interface to handle an HTTP request or response.

.. versionadded:: 4.0
r¥   ©r¦   ÚResponseStartLinerb   r   Nc                 ó   • g)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.   r¥   rb   s      r$   Úheaders_receivedÚ$HTTPMessageDelegate.headers_received  s   € ð" 	r2   Úchunkc                 ó   • g)zYCalled when a chunk of data has been received.

May return a `.Future` for flow control.
Nr,   ©r.   r  s     r$   Údata_receivedÚ!HTTPMessageDelegate.data_received0  s   € ð
 	r2   c                 ó   • g)z6Called after the last chunk of data has been received.Nr,   r|   s    r$   ÚfinishÚHTTPMessageDelegate.finish7  r1   r2   c                 ó   • g)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.
Nr,   r|   s    r$   Úon_connection_closeÚ'HTTPMessageDelegate.on_connection_close;  rÿ   r2   r,   rè   )r‹   rŒ   r�   rŽ   r�   r   r'   r   r   r  rê   r	  r  r  r™   r,   r2   r$   rö   rö     s]   † ñðàÐAÑBðð ðð 
�)˜D‘/Ñ	"ô	ð& 5ð ¨X°iÀ±oÑ-Fô ô÷r2   rö   c            	       ó`   • \ rS rSrSr SS\S   S\S\\   SS	4S
 jjr	S\SS	4S jr
SS jrSrg)r¤   iD  zQApplications use this interface to write their responses.

.. versionadded:: 4.0
Nr¥   r  rb   r  r   zFuture[None]c                 ó   • [        5       e)a¾  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.

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

Returns a future for flow control.

.. versionchanged:: 6.0

   The ``callback`` argument was removed.
rø   )r.   r¥   rb   r  s       r$   Úwrite_headersÚHTTPConnection.write_headersJ  s   € ô, "Ó#Ð#r2   c                 ó   • [        5       e)z…Writes a chunk of body data.

Returns a future for flow control.

.. versionchanged:: 6.0

   The ``callback`` argument was removed.
rø   r  s     r$   ÚwriteÚHTTPConnection.writeb  s   € ô "Ó#Ð#r2   c                 ó   • [        5       e)z3Indicates that the last body data has been written.rø   r|   s    r$   r  ÚHTTPConnection.finishm  s   € ä!Ó#Ð#r2   r,   r+   rè   )r‹   rŒ   r�   rŽ   r�   r   r'   r   rê   r  r  r  r™   r,   r2   r$   r¤   r¤   D  sY   † ñð "&ñ	$àÐAÑBð$ð ð$ð ˜‰ð	$ð
 
õ$ð0	$˜5ð 	$ ^ô 	$÷$r2   r¤   Úurlr4   .c           	      óø  • Uc  U $ [        U 5      n[        U[        5      (       a4  [        UR                  SS9nUR                  UR                  5       5        Ou[        U[        5      (       d  [        U[        5      (       a&  [        UR                  SS9nUR                  U5        O%SR                  [        U5      5      n[        U5      e[        U5      n[        US   US   US   US   UUS   45      n U $ )	að  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'
Tr¯   z7'args' parameter should be dict, list or tuple. Not {0}r   r9   é   é   é   )r   r>   Údictr	   rº   rÜ   rQ   ÚlistÚtupleÚformatÚtypeÚ	TypeErrorr   r   )r  r4   Ú
parsed_urlÚparsed_queryÚerrÚfinal_querys         r$   Ú
url_concatr)  r  sì   € ð& �|Øˆ
Ü˜#“€JÜ�$œ×ÑÜ  ×!1Ñ!1ÀTÑJˆØ×Ñ˜DŸJ™J›LÕ)Ü	�Dœ$×	Ñ	¤:¨d´E×#:Ñ#:Ü  ×!1Ñ!1ÀTÑJˆØ×Ñ˜DÕ!àG×NÑNÜ�‹Jó
ˆô ˜‹nÐÜ˜LÓ)€KÜ
à�q‰MØ�q‰MØ�q‰MØ�q‰MØØ�q‰Mð	
ó	€Cð €Jr2   c                   ó8   • \ rS rSr% Sr\\S'   \\S'   \\S'   Srg)r¢   i¡  z³Represents a file uploaded via a form.

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

* ``filename``
* ``body``
* ``content_type``
ÚfilenamerŸ   Úcontent_typer,   N)	r‹   rŒ   r�   rŽ   r�   rp   Ú__annotations__rê   r™   r,   r2   r$   r¢   r¢   ¡  s   ‡ ñð ƒMØ
ƒKØÖr2   r¢   Úrange_headerc                 ó$  • U R                  S5      u  pnUR                  5       UR                  5       p1US:w  a  gUR                  S5      u  pBn [        U5      n[        U5      nUb  Uc  US:w  a  U* nSnXg4$ US-  nXg4$ ! [         a     gf = f)a  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
rà   rê   Nr   r   r9   )r¸   r^   Ú_int_or_noner]   )r.  ÚunitÚ_rD   Ústart_bÚend_bÚstartÚends           r$   Ú_parse_request_ranger7  ±  s±   € ð> "×+Ñ+¨CÓ0�N€DˆUØ—*‘*“, §¡£ˆ%ØˆwƒØØŸ™¨Ó,Ñ€G�ðÜ˜WÓ%ˆÜ˜5Ó!ˆð �Ø‰=Ø�a‹xØ˜�Ø�ð ˆ<Ðð �1‰HˆCØˆ<Ðøô ó Ùðús   ÁB Â
BÂBr5  r6  Útotalc                 óP   • U =(       d    Sn U=(       d    US-
  nSU < SU< SU< 3$ )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
r   r9   zbytes r   Ú/r,   )r5  r6  r8  s      r$   Ú_get_content_ranger;  ä  s(   € ð �J�Q€EØ�<�%˜1Ñ
�CÛ$£cª5Ð1Ð1r2   Úvalc                 óF   • U R                  5       n U S:X  a  g [        U 5      $ )Nr‡   )r^   r–   )r<  s    r$   r0  r0  ó  s    € Ø
�)‰)‹+€CØ
ˆbƒyØÜˆs‹8€Or2   r,  rŸ   r»   r¡   rb   c                 óÔ  • U R                  S5      (       am  U(       a  SU;   a  [        SUS   -  5      e [        USS9nUR	                  5        H/  u  pxU(       d  M  UR                  U/ 5      R                  U5        M1     gU R                  S5      (       a�  U(       a  SU;   a  [        SUS   -  5      e U R                  S	5      n	U	 HL  n
U
R                  5       R                  S
5      u  p¼nUS:X  d  M-  U(       d  M6  [        [        U5      XU5          g   [        S5      eg! [         a  n[        SU-  5      UeSnAff = f! [         a  n[        SU-  5      UeSnAff = f)a.  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.
z!application/x-www-form-urlencodedzContent-Encodingz Unsupported Content-Encoding: %sTr¯   z&Invalid x-www-form-urlencoded body: %sNzmultipart/form-dataÚ;rà   Úboundaryzmultipart boundary not foundzInvalid multipart/form-data: %s)Ú
startswithrZ   r   rÈ   rQ   rÛ   rÜ   r!   r^   r¸   Úparse_multipart_form_datar   )r,  rŸ   r»   r¡   rb   Úuri_argumentsÚer   rR   ÚfieldsÚfieldrB   r¿   rC   s                 r$   rÚ   rÚ   ú  sx  € ð ×ÑÐB×CÑCÞÐ)¨WÓ4Ü Ø2°WÐ=OÑ5PÑPóð ð	Vä*¨4À4ÑHˆMð *×/Ñ/Ö1‰LˆDßˆvØ×$Ñ$ T¨2Ó.×5Ñ5°fÖ=ò 2ð 
×	 Ñ	 Ð!6×	7Ñ	7ÞÐ)¨WÓ4Ü Ø2°WÐ=OÑ5PÑPóð ð
	OØ!×'Ñ'¨Ó,ˆFÛ�Ø!ŸK™K›M×3Ñ3°CÓ8‘	�˜Ø˜
•?§q qÜ-¬d°1«g°tÈÔNÙñ	  ô %Ð%CÓDÐDð 
8øô ó 	VÜ Ð!IÈAÑ!MÓNÐTUÐUûð	Vûô& ó 	OÜ Ð!BÀQÑ!FÓGÈQÐNûð	OúsA   ¶
D( Â9<E	 Ã9E	 ÄE	 ÄE	 Ä(
EÄ2EÅEÅ	
E'ÅE"Å"E'r@  Údatac           	      óz  • U R                  S5      (       a  U R                  S5      (       a  U SS n UR                  SU -   S-   5      nUS:X  a  [        S5      eUSU R	                  SU -   S-   5      nU GHA  nU(       d  M  UR                  S5      nUS:X  a  [        S	5      e[        R                  USU R                  S
5      5      nUR                  SS5      n	[        U	5      u  p«U
S:w  d  UR                  S5      (       d  [        S5      eXgS-   S nUR                  S5      (       d  [        S5      eUS   nUR                  S5      (       aA  UR                  SS5      nUR                  U/ 5      R                  [        US   XÎS95        GM   UR                  U/ 5      R                  U5        GMD     g)aA  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.
ó   "r9   rW   s   --z4Invalid multipart/form-data: no final boundary foundNs   
s   

z#multipart/form-data missing headerszutf-8zContent-Dispositionr‡   z	form-datazInvalid multipart/form-dataé   éþÿÿÿr   z multipart/form-data missing namer+  rÙ   zapplication/unknown)r+  rŸ   r,  )rA  rf   ÚrfindrZ   r!   Úfindr'   ri   ÚdecoderL   Ú_parse_headerrÛ   rG   r¢   )r@  rG  r»   r¡   Úfinal_boundary_indexÚpartsÚpartÚeohrb   Údisp_headerÚdispositionÚdisp_paramsrD   r   Úctypes                  r$   rB  rB  (  s¯  € ð, ×Ñ˜4× Ñ  X×%6Ñ%6°t×%<Ñ%<Ø˜A˜b�>ˆØŸ:™: e¨hÑ&6¸Ñ&>Ó?ÐØ˜rÓ!ÜÐSÓTÐTØÐ&Ð&Ð'×-Ñ-¨e°hÑ.>ÀÑ.HÓI€EÜˆÞÙØ�i‰i˜Ó$ˆØ�"‹9Ü Ð!FÓGÐGÜ×#Ñ# D¨¨# J×$5Ñ$5°gÓ$>Ó?ˆØ—k‘kÐ"7¸Ó<ˆÜ#0°Ó#=Ñ ˆØ˜+Ó%¨T¯]©]¸7×-CÑ-CÜ Ð!>Ó?Ð?Ø˜1‘W˜rÐ"ˆØ�‰˜v×&Ñ&Ü Ð!CÓDÐDØ˜6Ñ"ˆØ�?‰?˜:×&Ñ&Ø—K‘K Ð0EÓFˆEØ×Ñ˜T 2Ó&×-Ñ-ÜØ(¨Ñ4¸5ñ÷ð × Ñ   rÓ*×1Ñ1°%×8ò/ r2   Útsc                 ó–  • [        U [        [        45      (       a  U nOŽ[        U [        [        R
                  45      (       a  [        R                  " U 5      nOR[        U [        R                  5      (       a%  [        R                  " U R                  5       5      nO[        SU -  5      e[        R                  R                  USS9$ )ay  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'
zunknown timestamp type: %rT)Úusegmt)r>   r–   rí   r!  rµ   Ústruct_timeÚcalendarÚtimegmÚdatetimeÚutctimetupler$  ÚemailÚutilsÚ
formatdate)rX  Útime_nums     r$   Úformat_timestamprd  ^  s“   € ô �"”sœE�l×#Ñ#Ø‰Ü	�Bœ¤× 0Ñ 0Ð1×	2Ñ	2Ü—?’? 2Ó&‰Ü	�Bœ×)Ñ)×	*Ñ	*Ü—?’? 2§?¡?Ó#4Ó5‰äÐ4°rÑ9Ó:Ð:Ü�;‰;×!Ñ! (°4Ð!Ð8Ð8r2   r¦   )rœ   r¹   rž   z^HTTP/1\.[0-9]$rT   c                 óÆ   •  U R                  S5      u  pn[        R	                  U5      (       d  [        SU-  5      e[        XU5      $ ! [         a    [        S5      ef = f)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')
rV   zMalformed HTTP request linez/Malformed HTTP version in HTTP Request-Line: %r)r!   r]   rZ   Ú_http_version_reÚmatchr¦   )rT   rœ   r¹   rž   s       r$   Úparse_request_start_linerh  ~  so   € ð<Ø $§
¡
¨3£Ñˆ�gô
 ×!Ñ! '×*Ñ*ÜØ=ÀÑGó
ð 	
ô ˜F¨'Ó2Ð2øô ó <ô Ð:Ó;Ð;ð<ús   ‚A
 Á
A r  )rž   ÚcodeÚreasonz (HTTP/1.[0-9]) ([0-9]+) ([^\r]*)c                 óì   • [        U 5      n [        R                  U 5      nU(       d  [        S5      e[	        UR                  S5      [        UR                  S5      5      UR                  S5      5      $ )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 liner9   r  r  )r
   Ú_http_response_line_rerg  rZ   r  Úgroupr–   )rT   rg  s     r$   Úparse_response_start_linern  ›  sY   € ô �dÓ€DÜ"×(Ñ(¨Ó.€EÞÜÐ@ÓAÐAÜ˜UŸ[™[¨›^¬S°·±¸Q³Ó-@À%Ç+Á+ÈaÃ.ÓQÐQr2   Úsc              #   óœ  #   • SnU R                  SU5      U:X  a°  US-  nU R                  SU5      nUSpCUS:”  aN  X@R                  SX25      U R                  SX25      -
  -  nUS-  S:X  a  OX0R                  SUS-   5      p2US:”  a  MN  US:  a  [        U 5      nXU nUR                  5       v •  UnU R                  SU5      U:X  a  M¯  g g 7f)Nr   r?  r9   Ú"z\"r  )rM  Úcountr=   r^   )ro  r5  r6  ÚindÚdiffÚfs         r$   Ú_parseparamrv  ¼  sÒ   é € Ø€EØ
�&‰&��eÓ
 Ó
%Ø�‰
ˆØ�f‰f�S˜%Ó ˆØ˜1ˆTØ�A‹gØ—G‘G˜C Ó*¨Q¯W©W°U¸CÓ-EÑEÑEˆDØ�a‰x˜1‹}ØØŸF™F 3¨¨a©Ó0�ð	 �A�gð
 �‹7Ü�a“&ˆCØ�CˆLˆØ�g‰g‹iŠØˆð �&‰&��eÓ
 ×
%ùs   ‚BCÂ	?CÃ
Cc                 ó4  • [        SU -   5      n[        U5      nS/nU Hn  nUR                  S5      nUS:¼  d  M  USU R                  5       R	                  5       nXES-   S R                  5       nUR                  U[        U5      45        Mp     [        R                  R                  U5      nUR                  S5        0 n	U HN  u  pj[        R                  R                  U
5      n[        U5      S:¼  a  US   S:X  a  US	   S:X  a  USS	 nXyU'   MP     X)4$ )
a1  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?  )ÚDummyrD   rà   r   Nr9   r  rq  rW   )rv  ÚnextrM  r^   r³   rG   r
   r`  ra  Údecode_paramsrF   Úcollapse_rfc2231_valuer=   )rT   rQ  ÚkeyÚparamsÚpÚir   rD   Údecoded_paramsÚpdictÚdecoded_values              r$   rO  rO  Î  s  € ô ˜˜d™
Ó#€EÜ
ˆu‹+€Cà Ð!€FÛˆØ�F‰F�3‹KˆØ��6Ø�R�a�5—;‘;“=×&Ñ&Ó(ˆDØ˜!‘e�g�J×$Ñ$Ó&ˆEØ�M‰M˜4¤¨EÓ!2Ð3Ö4ñ ô —[‘[×.Ñ.¨vÓ6€NØ×Ñ�qÔØ€EÛ-ÑˆÜ—‘×2Ñ2°=ÓAˆÜˆu‹:˜‹?˜u Q™x¨3›°5¸±9ÀÓ3CØ˜!˜B�KˆEØˆd‹ñ	  .ð
 ˆ:Ðr2   r|  r�  c                 óÜ   • U(       d  U $ U /n[        UR                  5       5       H3  u  p4Uc  UR                  U5        M  UR                  U< SU< 35        M5     SR                  U5      $ )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'
rà   z; )ÚsortedrQ   rG   r    )r|  r�  ÚoutrB   rC   s        r$   Ú_encode_headerr†  ñ  s]   € ö Øˆ
Øˆ%€Cä�u—{‘{“}Ö%‰ˆØ‰9Ø�J‰J�qŽMð �J‰J£!¢QÐ'Ö(ñ &ð �9‰9�S‹>Ðr2   ÚusernameÚpasswordc                 óæ   • [        U [        5      (       a  [        R                  " SU 5      n [        U[        5      (       a  [        R                  " SU5      n[	        U 5      S-   [	        U5      -   $ )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ó   :)r>   r   ÚunicodedataÚ	normalizer   )r‡  rˆ  s     r$   Úencode_username_passwordrŽ    sZ   € ô �(œL×)Ñ)Ü×(Ò(¨°Ó9ˆÜ�(œL×)Ñ)Ü×(Ò(¨°Ó9ˆÜ�‹>˜DÑ ¤4¨£>Ñ1Ð1r2   c                  ó*   • SS K n U R                  5       $ )Nr   )ÚdoctestÚDocTestSuite)r�  s    r$   Údoctestsr’    s   € ãà×ÑÓ!Ð!r2   z^(.+):(\d+)$Únetlocc                 ó¤   • [         R                  U 5      nU(       a.  UR                  S5      n[        UR                  S5      5      nX#4$ U nSnX#4$ )z{Returns ``(host, port)`` tuple from ``netloc``.

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

.. versionadded:: 4.1
r9   r  N)Ú
_netloc_rerg  rm  r–   )r“  rg  r    Úports       r$   r²   r²     sT   € ô ×Ñ˜VÓ$€EÞØ�{‰{˜1‹~ˆÜ�5—;‘;˜q“>Ó"ˆð ˆ<Ðð ˆØˆØˆ<Ðr2   Úqsc              #   óZ   #   • U R                  5        H  u  pU H  nX4v •  M
     M     g7f)z_Generator converting a result of ``parse_qs`` back to name-value pairs.

.. versionadded:: 5.0
N)rQ   )r—  rB   ÚvsrC   s       r$   Ú	qs_to_qslrš  0  s*   é € ð
 —‘–‰ˆÛˆAØ�&ŒLó ò ùs   ‚)+z\\(?:([0-3][0-7][0-7])|(.))Úmc                 óP   • U S   (       a  [        [        U S   S5      5      $ U S   $ )Nr9   é   r  )Úchrr–   )r›  s    r$   Ú_unquote_replacerŸ  =  s'   € Øˆ‡tÜ”3�q˜‘t˜Q“<Ó Ð à�‰tˆr2   c                 ó|   • U b  [        U 5      S:  a  U $ U S   S:w  d	  U S   S:w  a  U $ U SS n [        [        U 5      $ )zÇHandle double quotes and escaping in cookie values.

This method is copied verbatim from the Python 3.13 standard
library (http.cookies._unquote) so we don't have to depend on
non-public interfaces.
r  r   rq  rW   r9   )r=   Ú_unquote_subrŸ  )ro  s    r$   Ú_unquote_cookier¢  D  sO   € ð 	�y”C˜“F˜Q“JØˆØˆ�tˆsƒ{�a˜‘e˜s“lØˆð 	
ˆ!ˆBˆ€Aô Ô(¨!Ó,Ð,r2   Úcookiec                 ó6  • 0 nU R                  [        S5      5       Hx  n[        S5      U;   a  UR                  [        S5      S5      u  p4O[        S5      UpCUR                  5       UR                  5       pCU(       d	  U(       d  Mk  [        U5      X'   Mz     U$ )aC  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à   r9   r‡   )r!   rp   r^   r¢  )r£  Ú
cookiedictr  r|  r<  s        r$   rÇ   rÇ   _  s   € ð €JØ—‘œc #›hÖ'ˆÜˆs‹8�uÓØ—{‘{¤3 s£8¨QÓ/‰HˆC�ô ˜2“w �Ø—9‘9“; §	¡	£ˆSÞ—#�#ä-¨cÓ2ˆJ‹Oñ (ð Ðr2   r+   )ar�   r\  Úcollections.abcÚcollectionsr„   r^  Úemail.utilsr`  Ú	functoolsr   Úhttp.clientr   Úhttp.cookiesr¬   ÚreÚsslr   rµ   rŒ  Úurllib.parser   r   r   r	   Útornado.escaper
   r   r   Útornado.utilr   r   r�   r   r   r   r   r   r   r   r   r   r   r   ÚTYPE_CHECKINGr   Úasyncior   Úunittestr\   rp   r%   ÚabcÚMutableMappingr'   r”   r›   rÈ   rZ   rñ   ró   rö   r¤   r)  r¢   r–   r7  r;  r0  rê   rÚ   rB  rí   r!  r[  rd  Ú
namedtupler¦   Úcompilerf  rh  r  rl  rn  rv  rO  r†  rŽ  r’  r•  r²   rš  Úsubr¡  ÚMatchrŸ  r¢  rÇ   r,   r2   r$   Ú<module>rº     s˜  ðñ ó Û Û Û Û Ý Ý !Û Û 	Ý Û Û ß CÓ Cç ;Ñ ;ß 1ñ
 
ã ÷÷ ÷ ñ ð 
××ÝÝÛð €ñ ˆ4ƒð?˜Cð ? Có ?ó ð?ôw�+—/‘/×0Ñ0ô wôt[:˜ô [:ô|	�Yô 	ô	�iô 	ô 6ô ô:+˜&ô +ô\+$�Vô +$ð\,Ø	ð,à
Øˆd�3˜�8‰n˜d 5¨¨c¨¡?Ñ3°U¸5ÀÀcÀ¹?ÈCÐ;OÑ5PÐPñð,ð
 	ô,ô^ˆzô ð 0Øð0àˆe�H˜S‘M 8¨C¡=Ð0Ñ1Ñ2ô0ðf2˜h s™mð 2°(¸3±-ð 2Èð 2ÐPSô 2ð�cð ˜h s™mô ð &*ñ+OØð+Oà
ð+Oð �C˜˜e™Ð$Ñ%ð+Oð ��T˜(‘^Ð#Ñ$ð	+Oð
 �kÑ"ð+Oð 
õ+Oð\39Øð39à
ð39ð �C˜˜e™Ð$Ñ%ð39ð ��T˜(‘^Ð#Ñ$ð	39ð
 
ô39ðl9Øˆc�5˜% ×!1Ñ!1°8×3DÑ3DÐDÑEð9àô9ð0 ×)Ò)ØÒ5óÐ ð
 —:’:Ð0Ó1Ð ð3 3ð 3Ð+;ô 3ð*  ×*Ò*ØÒ6óÐ ð
 ŸšÐ$GÓHÐ ðR Cð RÐ,=ô RðB�3ð ˜9 S¨$° _Ñ5ô ð$ ˜ð    c¨4°°S°©>Ð&9Ñ :ô  ðF˜ð  D¨¨c¨¡Nð °sô ð(2Ø�C˜�JÑð2Ø+0°°e°Ñ+<ð2à
ô2ò "ð �ZŠZ˜Ó(€
ð ð ¨¨c°8¸C±=Ð.@Ñ(Aô ð"�$�s˜D ™LÐ(Ñ)ð ¨h°u¸SÀ&¸[Ñ7IÑ.Jô ð �zŠzÐ8Ó9×=Ñ=€ð˜Ÿ™ð  Sô ð-�sð -˜sô -ð6˜ð   c¨3 h¡õ r2   