Ë
    #ïàjL9 ã                   óŠ  — d 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ZddlZddlZddlZddlmZ ddlmZmZmZ ddlmZmZ ddlmZmZ ddlmZ d	Z  ejB                  «       d
k(  Z"	  ejF                  dd«      jI                  d«      Z%	 e" xr e% Z&	 e&r	 ddl'Z'ddl(Z(ddl*Z*nd\  Z'Z(Z*e"r) e+e
d«      r  e+e
d«      sde
_,         e+e
d«      sde
_-         e+e
d«      s	 erdnde
_.        dZ/dZ0dZ1dZ2dZ3dZ4dZ5d Z6d!Z7d"Z8 e	jr                  dju                  d#e8f«      «      Z; e<«       Z=g d$¢Z> e+ed%«      si e_?         G d&„ d'«      Z@ G d(„ d)e@«      ZA G d*„ d+«      ZB G d,„ d-«      ZC G d.„ d/«      ZD G d0„ d1«      ZE G d2„ d3«      ZF G d4„ d5«      ZG G d6„ d7«      ZHd8d9d:œZId<d;„ZJy# e)$ r 	 dZ&d\  Z'Z(Y �Œw xY w)=a­  
A high-speed, production ready, thread pooled, generic HTTP server.

For those of you wanting to understand internals of this module, here's the
basic call flow. The server's listening thread runs a very tight loop,
sticking incoming connections onto a Queue::

    server = HTTPServer(...)
    server.start()
    ->  serve()
        while ready:
            _connections.run()
                while not stop_requested:
                    child = socket.accept()  # blocks until a request comes in
                    conn = HTTPConnection(child, ...)
                    server.process_conn(conn)  # adds conn to threadpool

Worker threads are kept in a pool and poll the Queue, popping off and then
handling each connection in turn. Each connection can consist of an arbitrary
number of requests and their responses, so we run a nested loop::

    while True:
        conn = server.requests.get()
        conn.communicate()
        ->  while True:
                req = HTTPRequest(...)
                req.parse_request()
                ->  # Read the Request-Line, e.g. "GET /page HTTP/1.1"
                    req.rfile.readline()
                    read_headers(req.rfile, req.inheaders)
                req.respond()
                ->  response = app(...)
                    try:
                        for chunk in response:
                            if chunk:
                                req.write(chunk)
                    finally:
                        if hasattr(response, "close"):
                            response.close()
                if req.close_connection:
                    return

For running a server you can invoke :func:`start() <HTTPServer.start()>` (it
will run the server forever) or use invoking :func:`prepare()
<HTTPServer.prepare()>` and :func:`serve() <HTTPServer.serve()>` like this::

    server = HTTPServer(...)
    server.prepare()
    try:
        threading.Thread(target=server.serve).start()

        # waiting/detecting some appropriate stop condition here
        ...

    finally:
        server.stop()

And now for a trivial doctest to exercise the test suite

.. testsetup::

   from cheroot.server import HTTPServer

>>> 'HTTPServer' in globals()
True
é    N)Ú	lru_cacheé   )Ú__version__ÚconnectionsÚerrors)ÚIS_PPCÚbton)ÚMakeFileÚStreamWriter)Ú
threadpool)
ÚChunkedRFileÚDropUnderscoreHeaderReaderÚGatewayÚHTTPConnectionÚHTTPRequestÚ
HTTPServerÚHeaderReaderÚKnownLengthRFileÚSizeCheckWrapperÚget_ssl_adapter_classÚWindowsÚSERVER_SOFTWAREÚ zGoogle App Engine/F)NN)NNNÚAF_INET6ÚIPPROTO_IPV6é)   ÚIPV6_V6ONLYé   ÚSO_PEERCREDé   é   ó   
s   
ó   	ó    ó   :ó   ;ó    ó   *ó   /s   %2Fs   (?i))s   Accepts   Accept-Charsets   Accept-Encodings   Accept-Languages   Accept-Rangess   Allows   Cache-Controló
   Connections   Content-Encodings   Content-Languageó   Expects   If-Matchs   If-None-Matchs   Pragmas   Proxy-Authenticates   TEs   Traileró   Transfer-Encodings   Upgrades   Varys   Vias   Warnings   WWW-AuthenticateÚ
statisticsc                   ó$   — e Zd ZdZdd„Zd„ Zd„ Zy)r   z`Object for reading headers from an HTTP request.

    Interface and default implementation.
    Nc                 ó  — |€i }d}	 |j                  «       }|st        d«      ‚|t        k(  r	 |S |j                  t        «      st        d«      ‚|dd t        t
        hv r|j                  «       }n=	 |j                  t        d«      \  }}|j                  «       }| j                  |«      }|}| j                  «      sŒ»|t        v r&|j                  |«      }|rdj                  ||f«      }|||<   Œî# t        $ r t        d«      ‚w xY w)aÈ  
        Read headers from the given stream into the given header dict.

        If hdict is None, a new header dict is created. Returns the populated
        header dict.

        Headers which are repeated are folded together using a comma if their
        specification so dictates.

        This function raises ValueError when the read bytes violate the HTTP
        spec.
        You should probably return "400 Bad Request" if this happens.
        NúIllegal end of headers.úHTTP requires CRLF terminatorsr   zIllegal header line.s   , )ÚreadlineÚ
ValueErrorÚCRLFÚendswithÚSPACEÚTABÚstripÚsplitÚCOLONÚ_transform_keyÚ_allow_headerÚcomma_separated_headersÚgetÚjoin)ÚselfÚrfileÚhdictÚhnameÚlineÚvÚkÚexistings           ú=/srv/dav/.venv/lib/python3.12/site-packages/cheroot/server.pyÚ__call__zHeaderReader.__call__Î   s  € ð ˆ=ØˆEàˆØØ—>‘>Ó#ˆDÙä Ð!:Ó;Ð;à”tŠ|àð: ˆð9 —=‘=¤Ô&Ü Ð!AÓBÐBà�B�QˆxœE¤3˜<Ñ'ð —J‘J“L‘ð=ØŸ:™:¤e¨QÓ/‘D�A�qð —G‘G“I�Ø×'Ñ'¨Ó*�Ø�à×%Ñ% aÔ(ØàÔ+Ñ+Ø Ÿ9™9 UÓ+�ÙØŸ
™
 H¨a =Ó1�AØˆE�%‰LðG øô, "ò =Ü$Ð%;Ó<Ð<ð=ús   Á4C6 Ã6Dc                  ó   — y)NT© ©r@   Úkey_names     rH   r<   zHeaderReader._allow_header  s   € Ør'   c                 ó>   — |j                  «       j                  «       S ©N)r8   ÚtitlerL   s     rH   r;   zHeaderReader._transform_key
  s   € à�~‰~Ó×%Ñ%Ó'Ð'r'   rO   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__rI   r<   r;   rK   r'   rH   r   r   È   s   „ ñó
7òró(r'   r   c                   ó"   ‡ — e Zd ZdZˆ fd„Zˆ xZS )r   zDCustom HeaderReader to exclude any headers with underscores in them.c                 ó:   •— t         t        | �  |«      }|xr d|vS )NÚ_)Úsuperr   r<   )r@   rM   ÚorigÚ	__class__s      €rH   r<   z(DropUnderscoreHeaderReader._allow_header  s%   ø€ ÜÔ/°ÑDÀXÓNˆØÒ+˜ 8Ð+Ð+r'   )rQ   rR   rS   rT   r<   Ú__classcell__)rZ   s   @rH   r   r     s   ø„ ÙN÷,ð ,r'   r   c                   óJ   — e Zd ZdZd„ Zd„ Zdd„Zdd„Zdd„Zd„ Z	d	„ Z
d
„ ZeZy)r   z¯Wraps a file-like object, raising MaxSizeExceeded if too large.

    :param rfile: ``file`` of a limited size
    :param int maxlen: maximum length of the file being read
    c                 ó.   — || _         || _        d| _        y)z%Initialize SizeCheckWrapper instance.r   N)rA   ÚmaxlenÚ
bytes_read)r@   rA   r^   s      rH   Ú__init__zSizeCheckWrapper.__init__  s   € àˆŒ
ØˆŒØˆ�r'   c                 óp   — | j                   r*| j                  | j                   kD  rt        j                  ‚y y rO   )r^   r_   r   ÚMaxSizeExceeded©r@   s    rH   Ú_check_lengthzSizeCheckWrapper._check_length$  s+   € Ø�;Š;˜4Ÿ?™?¨T¯[©[Ò8Ü×(Ñ(Ð(ð 9ˆ;r'   Nc                 ó˜   — | j                   j                  |«      }| xj                  t        |«      z  c_        | j	                  «        |S )úÛRead a chunk from ``rfile`` buffer and return it.

        :param size: amount of data to read
        :type size: int

        :returns: chunk from ``rfile``, limited by size if specified
        :rtype: bytes
        )rA   Úreadr_   Úlenrd   ©r@   ÚsizeÚdatas      rH   rg   zSizeCheckWrapper.read(  s9   € ð �z‰z�‰˜tÓ$ˆØ�Šœ3˜t›9Ñ$�Ø×ÑÔØˆr'   c                 ó¶  — |�K| j                   j                  |«      }| xj                  t        |«      z  c_        | j	                  «        |S g }	 | j                   j                  d«      }| xj                  t        |«      z  c_        | j	                  «        |j                  |«       t        |«      dk  s|dd t        k(  rt        j                  |«      S ŒŠ)úÎRead a single line from ``rfile`` buffer and return it.

        :param size: minimum amount of data to read
        :type size: int

        :returns: one line from ``rfile``
        :rtype: bytes
        Né   éÿÿÿÿ)	rA   r2   r_   rh   rd   ÚappendÚLFÚEMPTYr?   )r@   rj   rk   Úress       rH   r2   zSizeCheckWrapper.readline6  s³   € ð ÐØ—:‘:×&Ñ& tÓ,ˆDØ�OŠOœs 4›yÑ(�OØ×ÑÔ ØˆKð ˆØØ—:‘:×&Ñ& sÓ+ˆDØ�OŠOœs 4›yÑ(�OØ×ÑÔ Ø�J‰J�tÔä�4‹y˜3Š $ r s )¬r¢/Ü—z‘z #“Ð&ð r'   c                 ó¸   — d}g }| j                  |«      }|rB|j                  |«       |t        |«      z  }d|cxk  r|k  r	 |S  | j                  |«      }|rŒB|S ©zíRead all lines from ``rfile`` buffer and return them.

        :param sizehint: hint of minimum amount of data to read
        :type sizehint: int

        :returns: lines of bytes read from ``rfile``
        :rtype: list[bytes]
        r   ©r2   rp   rh   ©r@   ÚsizehintÚtotalÚlinesrD   s        rH   Ú	readlineszSizeCheckWrapper.readlinesQ  óm   € ð ˆØˆØ�}‰}˜XÓ&ˆÙØ�L‰L˜ÔØ”S˜“YÑˆEØ�8Ô$˜uÒ$Øàˆð %à—=‘= Ó*ˆDò ð ˆr'   c                 ó8   — | j                   j                  «        y©z*Release resources allocated for ``rfile``.N©rA   Úcloserc   s    rH   r€   zSizeCheckWrapper.closef  ó   € à�
‰
×ÑÕr'   c                 ó   — | S ©zReturn file iterator.rK   rc   s    rH   Ú__iter__zSizeCheckWrapper.__iter__j  ó   € àˆr'   c                 óŒ   — t        | j                  «      }| xj                  t        |«      z  c_        | j	                  «        |S ©zGenerate next file chunk.)ÚnextrA   r_   rh   rd   ©r@   rk   s     rH   Ú__next__zSizeCheckWrapper.__next__n  s3   € ä�D—J‘JÓˆØ�Šœ3˜t›9Ñ$�Ø×ÑÔØˆr'   rO   ©r   )rQ   rR   rS   rT   r`   rd   rg   r2   r{   r€   r„   rŠ   rˆ   rK   r'   rH   r   r     s6   „ ñòò)óó'ó6ò*òòð �Dr'   r   c                   óD   — e Zd ZdZd„ Zd
d„Zd
d„Zdd„Zd„ Zd„ Z	d	„ Z
e
Zy)r   z±Wraps a file-like object, returning an empty string when exhausted.

    :param rfile: ``file`` of a known size
    :param int content_length: length of the file being read
    c                 ó    — || _         || _        y)z%Initialize KnownLengthRFile instance.N)rA   Ú	remaining)r@   rA   Úcontent_lengths      rH   r`   zKnownLengthRFile.__init__  s   € àˆŒ
Ø'ˆ�r'   Nc                 óâ   — | j                   dk(  ry|€| j                   }nt        || j                   «      }| j                  j                  |«      }| xj                   t	        |«      z  c_         |S )zÛRead a chunk from ``rfile`` buffer and return it.

        :param size: amount of data to read
        :type size: int

        :rtype: bytes
        :returns: chunk from ``rfile``, limited by size if specified
        r   r'   )rŽ   ÚminrA   rg   rh   ri   s      rH   rg   zKnownLengthRFile.read„  sZ   € ð �>‰>˜QÒØØˆ<Ø—>‘>‰Dä�t˜TŸ^™^Ó,ˆDà�z‰z�‰˜tÓ$ˆØ�Šœ#˜d›)Ñ#�Øˆr'   c                 óâ   — | j                   dk(  ry|€| j                   }nt        || j                   «      }| j                  j                  |«      }| xj                   t	        |«      z  c_         |S )rm   r   r'   )rŽ   r‘   rA   r2   rh   ri   s      rH   r2   zKnownLengthRFile.readline˜  s\   € ð �>‰>˜QÒØØˆ<Ø—>‘>‰Dä�t˜TŸ^™^Ó,ˆDà�z‰z×"Ñ" 4Ó(ˆØ�Šœ#˜d›)Ñ#�Øˆr'   c                 ó¸   — d}g }| j                  |«      }|rB|j                  |«       |t        |«      z  }d|cxk  r|k  r	 |S  | j                  |«      }|rŒB|S ru   rv   rw   s        rH   r{   zKnownLengthRFile.readlines¬  r|   r'   c                 ó8   — | j                   j                  «        yr~   r   rc   s    rH   r€   zKnownLengthRFile.closeÁ  r�   r'   c                 ó   — | S rƒ   rK   rc   s    rH   r„   zKnownLengthRFile.__iter__Å  r…   r'   c                 ól   — t        | j                  «      }| xj                  t        |«      z  c_        |S r‡   )rˆ   rA   rŽ   rh   r‰   s     rH   rŠ   zKnownLengthRFile.__next__É  s'   € ä�D—J‘JÓˆØ�Šœ#˜d›)Ñ#�Øˆr'   rO   r‹   )rQ   rR   rS   rT   r`   rg   r2   r{   r€   r„   rŠ   rˆ   rK   r'   rH   r   r   x  s1   „ ñò(ó
ó(ó(ò*òòð �Dr'   r   c                   óB   — e Zd ZdZd
d„Zd„ Zdd„Zdd„Zdd„Zd„ Z	d	„ Z
y)r   aª  Wraps a file-like object, returning an empty string when exhausted.

    This class is intended to provide a conforming wsgi.input value for
    request entities that have been encoded with the 'chunked' transfer
    encoding.

    :param rfile: file encoded with the 'chunked' transfer encoding
    :param int maxlen: maximum length of the file being read
    :param int bufsize: size of the buffer used to read the file
    c                 ó`   — || _         || _        d| _        t        | _        || _        d| _        y)z!Initialize ChunkedRFile instance.r   FN)rA   r^   r_   rr   ÚbufferÚbufsizeÚclosed)r@   rA   r^   rš   s       rH   r`   zChunkedRFile.__init__Þ  s,   € àˆŒ
ØˆŒØˆŒÜˆŒØˆŒØˆ�r'   c                 ój  — | j                   ry | j                  j                  «       }| xj                  t	        |«      z  c_        | j
                  r9| j                  | j
                  kD  r t        j                  d| j
                  «      ‚|j                  «       j                  t        d«      }	 |j                  d«      }t        |d«      }|dk  rd| _         y | j
                  r'| j                  |z   | j
                  kD  rt        d«      ‚| j                  j                  |«      }| xj                  t	        |«      z  c_        | xj                   |z  c_        | j                  j                  d«      }|t"        k7  rt        dt%        |«      z   d	z   «      ‚y # t        $ r t        d›�«      ‚w xY w)
NúRequest Entity Too Larger   r   é   zBad chunked transfer size: Té   z2Bad chunked transfer coding (expected '\r\n', got ú))r›   rA   r2   r_   rh   r^   r   rb   r8   r9   Ú	SEMICOLONÚpopÚintr3   ÚIOErrorrg   r™   r4   Úrepr)r@   rD   Ú
chunk_sizeÚchunkÚcrlfs        rH   Ú_fetchzChunkedRFile._fetchç  su  € Ø�;Š;Øà�z‰z×"Ñ"Ó$ˆØ�Šœ3˜t›9Ñ$�à�;Š;˜4Ÿ?™?¨T¯[©[Ò8Ü×(Ñ(Ø*Ø—‘óð ð
 �z‰z‹|×!Ñ!¤)¨QÓ/ˆð	ØŸ™ !›ˆJÜ˜Z¨Ó,ˆJð ˜Š?ØˆDŒKØð �;Š;˜4Ÿ?™?¨ZÑ7¸$¿+¹+ÒEÜÐ4Ó5Ð5à—
‘
—‘ 
Ó+ˆØ�Šœ3˜u›:Ñ%�Ø�Š�uÑ�à�z‰z�‰˜qÓ!ˆØ”4Š<ÜðÜ˜d›ñ$Ø&)ñ*óð ð øô' ò 	ÜØ-¨j¨^Ð<óð ð	ús   Â0F ÆF2Nc                 ó:  — t         }|dk(  r|S 	 |rt        |«      |k\  r|S | j                  s| j                  «        | j                  s|S |r5|t        |«      z
  }|| j                  d| z  }| j                  |d | _        n|| j                  z  }t         | _        ŒŽ)rf   r   N)rr   rh   r™   r©   )r@   rj   rk   rŽ   s       rH   rg   zChunkedRFile.read  s™   € ô ˆà�1Š9ØˆKàÙœ˜D›	 TÒ)Ø�à—;’;Ø—‘”Ø—{’{à�KáØ ¤3 t£9Ñ,�	Ø˜Ÿ™ J YÐ/Ñ/�Ø"Ÿk™k¨)¨*Ð5�•à˜Ÿ™Ñ#�Ü#�”ð! r'   c                 óZ  — t         }|dk(  r|S 	 |rt        |«      |k\  r|S | j                  s| j                  «        | j                  s|S | j                  j	                  t
        «      }|ry|dk(  r5|t        |«      z
  }|| j                  d| z  }| j                  |d | _        n…t        |t        |«      z
  |«      }|| j                  d| z  }| j                  |d | _        nF|dk(  r|| j                  z  }t         | _        n&|| j                  d| z  }| j                  |d | _        �Œ)rm   r   ro   N)rr   rh   r™   r©   Úfindrq   r‘   )r@   rj   rk   Únewline_posrŽ   s        rH   r2   zChunkedRFile.readline2  s   € ô ˆà�1Š9ØˆKàÙœ˜D›	 TÒ)Ø�à—;’;Ø—‘”Ø—{’{à�KàŸ+™+×*Ñ*¬2Ó.ˆKÙØ "Ò$Ø $¤s¨4£yÑ 0�IØ˜DŸK™K¨
¨Ð3Ñ3�DØ"&§+¡+¨i¨jÐ"9�D•Kä # D¬3¨t«9Ñ$4°kÓ B�IØ˜DŸK™K¨
¨Ð3Ñ3�DØ"&§+¡+¨i¨jÐ"9�D•KØ Ò"Ø˜Ÿ™Ñ#�Ü#�•à˜Ÿ™ L [Ð1Ñ1�Ø"Ÿk™k¨+¨,Ð7�”ñ3 r'   c                 ó¸   — d}g }| j                  |«      }|rB|j                  |«       |t        |«      z  }d|cxk  r|k  r	 |S  | j                  |«      }|rŒB|S ru   rv   rw   s        rH   r{   zChunkedRFile.readlines[  r|   r'   c              #   ó‚  K  — | j                   st        d«      ‚	 | j                  j                  «       }|st        d«      ‚| xj                  t        |«      z  c_        | j                  r$| j                  | j                  kD  rt        d«      ‚|t        k(  ry|j                  t        «      st        d«      ‚|–— Œ¤­w)zhRead HTTP headers and yield them.

        :yields: CRLF separated lines
        :ytype: bytes

        z:Cannot read trailers until the request body has been read.r0   r�   r1   N)
r›   r3   rA   r2   r_   rh   r^   r¤   r4   r5   )r@   rD   s     rH   Úread_trailer_lineszChunkedRFile.read_trailer_linesp  s¥   è ø€ ð �{Š{ÜØLóð ð Ø—:‘:×&Ñ&Ó(ˆDÙä Ð!:Ó;Ð;à�OŠOœs 4›yÑ(�OØ�{Š{˜tŸ™°·±Ò<ÜÐ8Ó9Ð9à”tŠ|àØ—=‘=¤Ô&Ü Ð!AÓBÐBàŠJð! ùs   ‚B=B?c                 ó8   — | j                   j                  «        yr~   r   rc   s    rH   r€   zChunkedRFile.closeŽ  r�   r'   )i    rO   r‹   )rQ   rR   rS   rT   r`   r©   rg   r2   r{   r°   r€   rK   r'   rH   r   r   Ò  s-   „ ñ	óò)óV$ó@'8óRò*ó<r'   r   c                   ó„   — e Zd ZdZdZ	 dZ	 i Z	 g Z	 dZ	 dZ		 dZ
	  e«       Z	 dd„Zd„ Zd„ Zd„ Zd„ Zdd	„Zd
„ Zd„ Zd„ Zy)r   zrAn HTTP Request (and response).

    A single HTTP connection may consist of multiple request/response pairs.
    NFc                 ó`  — || _         || _        d| _        d| _        d| _        | j                   j
                  �d| _        d| _        i | _        d| _        g | _	        d| _
        | j                  j                  | _        d| _        | j                  j                  | _        || _        || _        y)a  Initialize HTTP request container instance.

        Args:
            server (HTTPServer): web server object receiving this request
            conn (HTTPConnection): HTTP connection object for this request
            proxy_mode (bool): whether this HTTPServer should behave as a PROXY
            server for certain requests
            strict_mode (bool): whether we should return a 400 Bad Request when
            we encounter a request that a HTTP compliant client should not be
            making
        Fs   httpNs   httpszHTTP/1.0r   )ÚserverÚconnÚreadyÚstarted_requestÚschemeÚssl_adapterÚresponse_protocolÚ	inheadersÚstatusÚ
outheadersÚsent_headersrZ   Úclose_connectionÚchunked_readÚchunked_writeÚ
proxy_modeÚstrict_mode)r@   r´   rµ   rÂ   rÃ   s        rH   r`   zHTTPRequest.__init__¹  sŸ   € ð ˆŒØˆŒ	àˆŒ
Ø$ˆÔØˆŒØ�;‰;×"Ñ"Ð.Ø"ˆDŒKà!+ˆÔØˆŒàˆŒØˆŒØ!ˆÔØ $§¡× ?Ñ ?ˆÔØ!ˆÔØ!Ÿ^™^×9Ñ9ˆÔØ$ˆŒØ&ˆÕr'   c                 ó€  — t        | j                  j                  | j                  j                  «      | _        	 | j                  «       }|sy	 | j                  «       }|syd| _
        y# t        j                  $ r | j                  dd«       Y yw xY w# t        j                  $ r | j                  dd«       Y yw xY w)z;Parse the next HTTP request start-line and message-headers.Nz414 Request-URI Too LongzHThe Request-URI sent with the request exceeds the maximum allowed bytes.ú413 Request Entity Too LargezCThe headers sent with the request exceed the maximum allowed bytes.T)r   rµ   rA   r´   Úmax_request_header_sizeÚread_request_liner   rb   Úsimple_responseÚread_request_headersr¶   )r@   Úsuccesss     rH   Úparse_requestzHTTPRequest.parse_requestÚ  sÆ   € ä%Ø�I‰I�O‰OØ�K‰K×/Ñ/ó
ˆŒ
ð	Ø×,Ñ,Ó.ˆGñ Øð	Ø×/Ñ/Ó1ˆGñ Øàˆ�
øô1 ×%Ñ%ò 	Ø× Ñ Ø*ð!ôñ
 ð	ûô ×%Ñ%ò 	Ø× Ñ Ø.ð!ôñ
 ð	ús#   »A* ÁB Á*%BÂBÂ%B=Â<B=c                 ó¼	  — | j                   j                  «       }d| _        |sy|t        k(  r| j                   j                  «       }|sy|j	                  t        «      s| j                  dd«       y	 |j                  «       j                  t        d«      \  }}}|j                  d«      s| j                  dd«       y|dd	 j                  d
d«      }t        |«      dk7  r| j                  dd«       yt        t        t        |«      «      }|dkD  r| j                  dd«       y	 || _        |j#                  «       | _        | j&                  r$|| j$                  k7  rd}| j                  d|«       y	 t(        j*                  j-                  |«      \  }}}	}
}|xs |}| j$                  dk(  r| j0                  r|r|n|	}	�nÍ| j$                  dk(  rÉ| j0                  s| j                  d«       yt(        j*                  j-                  dj3                  d|f«      «      }|\  }}}}}t4        }t7        j8                  t        «      5  |j:                  }d	d	d	«       ||k7  xs | xs t=        ||||f«      }|r| j                  dd«       y|x}}	t4        x}x}
}nõ| j&                  xr | j0                   xr |}|r	 | j                  dd«       y| j&                  xr |j                  t>        «       xr | }|r	 d}| j                  d|«       y|r| j                  dd«       y|	€| j                  dd«       y	 t@        j                  |	«      D �cg c]!  }t(        j*                  jC                  |«      ‘Œ# }}tF        j3                  |«      }	|	j                  t>        «      s	t>        |	z   }	|t4        ur|| _$        || _%        |	| _&        |
| _'        t        | jP                  jR                  d   «      t        | jP                  jR                  d   «      f}|d   |d   k7  r| j                  d«       y|| _*        dtW        ||«      z  | _,        y# t        t        f$ r | j                  dd«       Y yw xY w# t.        $ r | j                  dd«       Y yw xY w# 1 sw Y   �ŒExY wc c}w # t        $ r)}| j                  d|jD                  d   «       Y d	}~yd	}~ww xY w) zšRead and parse first line of the HTTP request.

        Returns:
            bool: True if the request line is valid or False if it's malformed.

        TFú400 Bad Requestr1   rŸ   s   HTTP/z$Malformed Request-Line: bad protocolé   Nó   .r   z#Malformed Request-Line: bad version)r   r   z505 HTTP Version Not SupportedzCannot fulfill requestzMalformed Request-Linez²Malformed method name: According to RFC 2616 (section 5.1.1) and its successors RFC 7230 (section 3.1.1) and RFC 7231 (section 4.1) method names are case-sensitive and uppercase.zMalformed Request-URIs   OPTIONSs   CONNECTz405 Method Not Allowedr'   s   //zFInvalid path in Request-URI: request-target must match authority-form.z2Absolute URI not allowed if server is not a proxy.z…Invalid path in Request-URI: request-target must contain origin-form which starts with absolute-path (URI starting with a slash "/").z!Illegal #fragment in Request-URI.zInvalid path in Request-URI.r   é   z
HTTP/%s.%s)-rA   r2   r·   r4   r5   rÈ   r8   r9   r6   Ú
startswithrh   ÚtupleÚmapr£   r3   Ú
IndexErrorÚuriÚupperÚmethodrÃ   ÚurllibÚparseÚurlsplitÚUnicodeErrorrÂ   r?   rr   Ú
contextlibÚsuppressÚportÚanyÚFORWARD_SLASHÚQUOTED_SLASH_REGEXÚunquote_to_bytesÚargsÚQUOTED_SLASHr¸   Ú	authorityÚpathÚqsr´   ÚprotocolÚrequest_protocolr‘   rº   )r@   Úrequest_liner×   rÕ   Úreq_protocolÚrpÚrespr¸   rå   ræ   rç   ÚfragmentÚuri_is_absolute_formÚ	uri_splitÚ_schemeÚ
_authorityÚ_pathÚ_qsÚ	_fragmentÚ_portÚinvalid_pathÚdisallowed_absoluteÚxÚatomsÚexÚsps                             rH   rÇ   zHTTPRequest.read_request_lineü  s&  € ð —z‘z×*Ñ*Ó,ˆð  $ˆÔÙØàœ4Òð
  Ÿ:™:×.Ñ.Ó0ˆLÙØà×$Ñ$¤TÔ*Ø× Ñ Ø!Ø0ôð ð	Ø(4×(:Ñ(:Ó(<×(BÑ(BÄ5È!Ó(LÑ%ˆF�C˜Ø×*Ñ*¨8Ô4Ø×$Ñ$Ø%Ø:ôð Ø˜a˜bÐ!×'Ñ'¨¨aÓ0ˆBÜ�2‹w˜!Š|Ø×$Ñ$Ø%Ø9ôð Ü”sœ3 “|Ó$ˆBØ�FŠ{Ø×$Ñ$Ø4Ø,ôð ð ð ˆŒØ—l‘l“nˆŒà×Ò ¨$¯+©+Ò 5ðAð ð × Ñ Ð!2°DÔ9Øð	Ü4:·L±L×4IÑ4IÈ#Ó4NÑ1ˆF�I˜t R¨ð
  &Ò2¨Ðà�;‰;˜*Ò$ð
 —O’OÑ(<ñ ð ò	 ð �[‰[˜JÒ&à—?’?Ø×$Ñ$Ð%=Ô>Øô Ÿ™×-Ñ-¨c¯h©h¸¸s°|Ó.DÓEˆIØ9BÑ6ˆG�Z ¨¨YÜˆEÜ×$Ñ$¤ZÓ0ñ 'Ø!Ÿ™�÷'ð ˜cÑ!ò 9Ø�9ò9ä˜ ¨¨YÐ7Ó8ð ñ
 Ø×$Ñ$Ø%ð8ôð
 à)Ð)ˆI˜Ü%*Ð*ˆFÐ*�R™(ð × Ñ ò )ØŸ™Ð'ò)à(ð  ñ
 #ð CØ×$Ñ$Ø%ØHôð ð × Ñ ò -ØŸ™¤}Ó5Ð5ò-à,Ð,ð ñ
 ð >ð2ð ð
 ×$Ñ$Ð%6¸Ô=ØáØ×$Ñ$Ø%Ø7ôð àˆ|à×$Ñ$Ø%Ø2ôð ð	ô
 0×5Ñ5°dÓ;öàô —L‘L×1Ñ1°!Õ4ð�ð ô  ×$Ñ$ UÓ+ˆDà�‰œ}Ô-Ü  4Ñ'ˆDàœÑØ ˆDŒKØ"ˆŒØˆŒ	ð ˆŒô �—‘×%Ñ% aÑ(Ó)¬3¨t¯{©{×/CÑ/CÀAÑ/FÓ+GÐGˆàˆa‰5�B�q‘EŠ>Ø× Ñ Ð!AÔBØà ,ˆÔØ!-´°B¸³Ñ!;ˆÔàøôO œJÐ'ò 	Ø× Ñ Ð!2Ð4LÔMÙð	ûô& ò 	Ø× Ñ Ð!2Ð4KÔLÙð	ú÷2'ñ 'üòbøô ò Ø×$Ñ$Ð%6¸¿¹À¹
ÔCÜûðúsg   Á4AQ Ã 5Q Ã60Q Å5%Q6 ÉRÌ<R) Í&R$Í9R) Ñ!Q3Ñ2Q3Ñ6RÒRÒR!Ò$R) Ò)	SÒ2SÓSc                 ó`  — 	 | j                  | j                  | j                  «       | j                  j                  }	 t        | j                  j                  dd«      «      }|r||kD  r| j	                  dd«       y| j                  d	k(  r'| j                  j                  d
d«      dk(  r.d| _        n&| j                  j                  d
d«      dk7  rd| _        d}| j                  d	k(  rh| j                  j                  d«      }|rK|j                  d«      D �cg c]1  }|j                  «       sŒ|j                  «       j                  «       ‘Œ3 }}d| _        |r-|D ](  }|dk(  rd| _        Œ| j	                  d«       d| _         y | j                  j                  dd«      dk(  rldj!                  | j                  j"                  j%                  d«      t&        dt(        t(        f«      }	 | j*                  j,                  j/                  |«       yy# t        $ r)}| j	                  d|j
                  d   «       Y d}~yd}~ww xY w# t        $ r | j	                  dd«       Y yw xY wc c}w # t0        j2                  $ r*}|j
                  d   t4        j6                  vr‚ Y d}~yd}~ww xY w)z®Read ``self.rfile`` into ``self.inheaders``.

        Ref: :py:attr:`self.inheaders <HTTPRequest.outheaders>`.

        :returns: success status
        :rtype: bool
        rÍ   r   NFó   Content-Lengthz Malformed Content-Length Header.rÅ   úCThe entity sent with the request exceeds the maximum allowed bytes.úHTTP/1.1r*   r'   ó   closeTó
   Keep-Aliver,   ó   ,ó   chunkedz501 Unimplementedr+   s   100-continueÚasciis   100 Continue)Úheader_readerrA   r»   r3   rÈ   rã   r´   Úmax_request_body_sizer£   r>   rº   r¿   r9   r8   ÚlowerrÀ   r?   rè   Úencoder6   r4   rµ   ÚwfileÚwriteÚsocketÚerrorr   Úsocket_errors_to_ignore)r@   rû   ÚmrbsÚclÚterù   ÚencÚmsgs           rH   rÉ   z HTTPRequest.read_request_headersá  sv  € ð	Ø×Ñ˜tŸz™z¨4¯>©>Ô:ð
 �{‰{×0Ñ0ˆð	Ü�T—^‘^×'Ñ'Ð(9¸1Ó=Ó>ˆBñ �B˜’IØ× Ñ Ø.ð!ôð
 ð ×!Ñ! ZÒ/à�~‰~×!Ñ! -°Ó5¸ÒAØ(,�Õ%à�^‰^×Ñ ¨sÓ3°}ÒDØ$(ˆDÔ!ð ˆØ×!Ñ! ZÒ/Ø—‘×#Ñ#Ð$8Ó9ˆBÙØ13·±¸$³ÖM¨AÀ1Ç7Á7Å9�a—g‘g“i—o‘oÕ'ÐM�ÐMà!ˆÔáØò !�Ø˜*Ò$Ø(,�DÕ%ð ×(Ñ(Ð)<Ô=Ø,0�DÔ)Ù ð!ð6 �>‰>×Ñ˜i¨Ó-°Ò@ð —(‘(à—K‘K×(Ñ(×/Ñ/°Ó8ÜØ#ÜÜðóˆCðØ—	‘	—‘×%Ñ% cÔ*ñ øôo ò 	Ø× Ñ Ð!2°B·G±G¸A±JÔ?Üûð	ûô ò 	Ø× Ñ Ø!Ø2ôñ ð	üò: Nøô^ —<‘<ò Ø—7‘7˜1‘:¤V×%CÑ%CÑCØó DàûðúsL   ‚&H ¿%I
 ÄI+Ä1 I+Ç.%I0 È	IÈIÉIÉ
I(É'I(É0J-Ê J(Ê(J-c                 óf  — | j                   j                  }| j                  r&t        | j                  j
                  |«      | _        npt        | j                  j                  dd«      «      }|r$||k  r| j                  s| j                  dd«       yt        | j                  j
                  |«      | _        | j                   j                  | «      j                  «        | j                  xr | j                  «        | j                   r&| j                  j"                  j%                  d«       yy)z/Call the gateway and write its iterable output.rþ   r   rÅ   rÿ   Ns   0

)r´   r  rÀ   r   rµ   rA   r£   r»   r>   r¾   rÈ   r   ÚgatewayÚrespondr¶   Úensure_headers_sentrÁ   r
  r  )r@   r  r  s      rH   r  zHTTPRequest.respondE  sä   € à�{‰{×0Ñ0ˆØ×ÒÜ% d§i¡i§o¡o°tÓ<ˆD�Jä�T—^‘^×'Ñ'Ð(9¸1Ó=Ó>ˆBÙ˜˜rš	Ø×(Ò(Ø×(Ñ(Ø6ð1ôð
 Ü)¨$¯)©)¯/©/¸2Ó>ˆDŒJà�‰×Ñ˜DÓ!×)Ñ)Ô+Ø�
‰
Ò1�t×/Ñ/Ó1øà×ÒØ�I‰I�O‰O×!Ñ! ,Õ/ð r'   c                 ó¼  — t        |«      }| j                  j                  ›d|›d�}dt        |«      z  }d}|j	                  d«      |j	                  d«      |j	                  d«      g}|dd dv r*d	| _        | j                  d
k(  r|j                  d«       nd}|j                  t        «       |r2t        |t         «      r|j	                  d«      }|j                  |«       	 | j                  j                  j                  t        j                  |«      «       y# t        j                   $ r*}|j"                  d   t$        j&                  vr‚ Y d}~yd}~ww xY w)z+Write a simple response back to the client.ú z
zContent-Length: %s
zContent-Type: text/plain
ú
ISO-8859-1Né   >   Ú413Ú414Tr   s   Connection: close
rÍ   r   )Ústrr´   rè   rh   r	  r¿   rº   rp   r4   Ú
isinstancerµ   r
  r  rr   r?   r  r  rã   r   r  )r@   r¼   r  Úproto_statusr�   Úcontent_typeÚbufrû   s           rH   rÈ   zHTTPRequest.simple_response\  s'  € ä�V“ˆØ&*§k¡k×&:Ó&:ºFÐCˆØ1´C¸³HÑ<ˆØ5ˆà×Ñ Ó-Ø×!Ñ! ,Ó/Ø×Ñ Ó-ð
ˆð �"�1ˆ:˜Ñ'à$(ˆDÔ!Ø×%Ñ%¨Ò3ð —
‘
Ð3Õ4ð +�à�
‰
”4ÔÙÜ˜#œsÔ#Ø—j‘j Ó.�Ø�J‰J�sŒOð	Ø�I‰I�O‰O×!Ñ!¤%§*¡*¨S£/Õ2øÜ�|‰|ò 	Ø�w‰w�q‰z¤×!?Ñ!?Ñ?Øô @ûð	ús   Ã%8D ÄEÄ1 EÅEc                 óL   — | j                   sd| _         | j                  «        yy)z:Ensure headers are sent to the client if not already sent.TN)r¾   Úsend_headersrc   s    rH   r  zHTTPRequest.ensure_headers_sent�  s$   € à× Ò Ø $ˆDÔØ×ÑÕð !r'   c                 óD  — | j                   ro|rmt        t        |«      «      dd j                  d«      }|t        |t        g}| j
                  j                  j                  t        j                  |«      «       y| j
                  j                  j                  |«       y)z$Write unbuffered data to the client.rŸ   Nr  )
rÁ   Úhexrh   r	  r4   rµ   r
  r  rr   r?   )r@   r§   Úchunk_size_hexr"  s       rH   r  zHTTPRequest.write‡  sn   € à×Ò¡%Ü ¤ U£›_¨Q¨RÐ0×7Ñ7¸Ó@ˆNØ!¤4¨´Ð5ˆCØ�I‰I�O‰O×!Ñ!¤%§*¡*¨S£/Õ2à�I‰I�O‰O×!Ñ! %Õ(r'   c                 ó|  — | j                   D ��cg c]  \  }}|j                  «       ‘Œ }}}t        | j                  dd «      }|dk(  rd| _        nZd|vrV|dk  s|dv rnL| j
                  dk(  xr | j                  d	k7  }|r#d| _        | j                   j                  d
«       nd| _        | j                  s| j                  j                  }| | _        d|vr^| j
                  dk(  r(| j                  rC| j                   j                  d«       n'| j                  s| j                   j                  d«       d| j                   v rC| j                   j                  dd| j                  j                  › �j                  d«      f«       | j                  sC| j                  s7t        | j                  dd«      }|dkD  r| j                  j!                  |«       d|vrJ| j                   j                  dt"        j$                  j'                  d¬«      j                  d«      f«       d|vr@| j                   j                  d| j                  j(                  j                  d«      f«       | j                  j*                  j                  d«      }|t,        z   | j                  z   t.        z   g}	| j                   D ].  \  }
}|	j                  |
t0        z   t,        z   |z   t.        z   «       Œ0 |	j                  t.        «       | j2                  j4                  j7                  t8        j;                  |	«      «       yc c}}w )zÁAssert, process, and send the HTTP response message-headers.

        You must set ``self.status``, and :py:attr:`self.outheaders
        <HTTPRequest.outheaders>` before calling this.
        Nr  i�  Ts   content-lengthéÈ   >   é0  éÌ   éÍ   r   s   HEAD)r,   r  s
   connection)r*   r  )r*   r  r  ztimeout=r  rŽ   r   s   dates   Date)Úusegmts   servers   Serverr  )r½   r  r£   r¼   r¿   rº   r×   rÁ   rp   r´   Úcan_add_keepalive_connectionÚtimeoutr	  rÀ   ÚgetattrrA   rg   ÚemailÚutilsÚ
formatdateÚserver_namerè   r6   r4   r:   rµ   r
  r  rr   r?   )r@   ÚkeyÚvalueÚhkeysr¼   Úneeds_chunkedÚcan_keeprŽ   Úprotor"  rF   rE   s               rH   r$  zHTTPRequest.send_headers�  sÄ  € ð 04¯©×?¡  e�—‘•Ð?ˆÑ?Ü�T—[‘[  !�_Ó%ˆà�SŠ=à$(ˆDÕ!Ø eÑ+ð ˜Š|˜v¨Ñ8Øð ×*Ñ*¨jÑ8ò /ØŸ™ wÑ.ð ñ !à)-�DÔ&Ø—O‘O×*Ñ*Ð+MÕNð -1�DÔ)ð ×$Ò$Ø—{‘{×?Ñ?ˆHØ(0 LˆDÔ!à Ñ%Ø×%Ñ%¨Ò3à×(Ò(Ø—O‘O×*Ñ*Ð+DÕEà×*Ò*Ø—‘×&Ñ&Ð'EÔFà)¨T¯_©_Ñ<Ø�O‰O×"Ñ"à!Ø˜tŸ{™{×2Ñ2Ð3Ð4×;Ñ;¸LÓIðôð ×%Ò%°×0AÒ0Aô   §
¡
¨K¸Ó;ˆIØ˜1Š}Ø—
‘
—‘ 	Ô*à˜%ÑØ�O‰O×"Ñ"àÜ—K‘K×*Ñ*°$Ð*Ó7×>Ñ>¸|ÓLðôð ˜EÑ!Ø�O‰O×"Ñ"àØ—K‘K×+Ñ+×2Ñ2°<Ó@ðôð —‘×$Ñ$×+Ñ+¨GÓ4ˆØ”u‰}˜tŸ{™{Ñ*¬TÑ1Ð2ˆØ—O‘Oò 	5‰DˆAˆqØ�J‰J�qœ5‘y¤5Ñ(¨1Ñ,¬tÑ3Õ4ð	5à�
‰
”4ÔØ�	‰	�‰×ÑœeŸj™j¨›oÕ.ùóm @s   �L8)FT)r   )rQ   rR   rS   rT   r´   rµ   r»   r½   r¶   r¿   rÁ   r   r  r`   rË   rÇ   rÉ   r  rÈ   r  r  r$  rK   r'   rH   r   r   “  s�   „ ñð
 €FØ@à€DØDà€IØ$à€JØ;à€Eð@ð Ððð €Mð<ñ !“N€Mðó'òB òDcòJbòH0ó.#òJ ò)ó\/r'   r   c                   óä   — e Zd ZdZdZdZdZej                  Z	ej                  Z
eZdZdZdZefd„Zd„ ZdZd„ Zd„ Zd„ Zd	„ Zed
„ «       Zed„ «       Zed„ «       Zd„ Zed„ «       Zed„ «       Zd„ Zy)r   z#An HTTP connection (active socket).NFc                 ó‚  — || _         || _         ||d| j                  «      | _         ||d| j                  «      | _        d| _        | j                   j                  | _        | j                   j                  | _         t        d¬«      | j                  «      | _
         t        d¬«      | j                  «      | _        y)aB  Initialize HTTPConnection instance.

        Args:
            server (HTTPServer): web server object receiving this request
            sock (socket._socketobject): the raw socket object (usually
                TCP) for this connection
            makefile (file): a fileobject class for reading from the socket
        ÚrbÚwbr   r   )ÚmaxsizeN)r´   r  ÚrbufsizerA   Úwbufsizer
  Úrequests_seenÚpeercreds_enabledÚpeercreds_resolve_enabledr   Úresolve_peer_credsÚget_peer_creds)r@   r´   ÚsockÚmakefiles       rH   r`   zHTTPConnection.__init__þ  sœ   € ð ˆŒØˆŒÙ˜d D¨$¯-©-Ó8ˆŒ
Ù˜d D¨$¯-©-Ó8ˆŒ
ØˆÔà!%§¡×!>Ñ!>ˆÔØ)-¯©×)NÑ)NˆÔ&ð #7¤)°AÔ"6°t×7NÑ7NÓ"OˆÔØ2œi°Ô2°4×3FÑ3FÓGˆÕr'   c                 óÀ  — d}	 | j                  | j                  | «      }|j                  «        | j                  j                  d   r| xj                  dz  c_        |j
                  syd}|j                  «        |j                  sy	 y# t        j                  $ rž}|j                  d   }d}||v r#|rr{|j                  ro| j                  d«       n\|t        j                  vrJ| j                  j                  dt!        |«      z  t"        j$                  d¬	«       | j                  d
«       Y d}~yd}~wt&        t(        f$ r ‚ t        j*                  $ r Y yt        j,                  $ r | j/                  «       Y yt0        $ rQ}| j                  j                  t!        |«      t"        j2                  d¬	«       | j                  d
«       Y d}~yd}~ww xY w)zrRead each request and respond appropriately.

        Returns true if the connection should be kept open.
        FÚEnabledr   Tr   )z	timed outzThe read operation timed outz408 Request Timeoutzsocket.error %s©ÚlevelÚ	tracebackz500 Internal Server ErrorN)ÚRequestHandlerClassr´   rË   ÚstatsrB  r¶   r  r¿   r  r  rã   r·   Ú_conditional_errorr   r  Ú	error_logr¥   ÚloggingÚWARNINGÚKeyboardInterruptÚ
SystemExitÚFatalSSLAlertÚ
NoSSLErrorÚ_handle_no_sslÚ	ExceptionÚERROR)r@   Úrequest_seenÚreqrû   ÚerrnumÚtimeout_errss         rH   ÚcommunicatezHTTPConnection.communicate  sÃ  € ð
 ˆð-	FØ×*Ñ*¨4¯;©;¸Ó=ˆCØ×ÑÔØ�{‰{× Ñ  Ò+Ø×"Ò" aÑ'Õ"Ø—9’9ð àˆLØ�K‰KŒMØ×'Ò'Øð (ðB øô? �|‰|ò 	JØ—W‘W˜Q‘ZˆFàFˆLØ˜Ñ%ñ
 %©#°#×2EÒ2EØ×+Ñ+¨CÐ1FÕGØœv×=Ñ=Ñ=Ø—‘×%Ñ%Ø%¬¨V«Ñ4Ü!Ÿ/™/Ø"ð &ô ð
 ×'Ñ'¨Ð-HÔIûð ûô "¤:Ð.ò 	ØÜ×#Ñ#ò 	Øð ô × Ñ ò 	%Ø×Ñ Õ$ð ô ò 	FØ�K‰K×!Ñ!Ü�R“Ü—m‘mØð "ô ð
 ×#Ñ# CÐ)D×EÐEØûð	Fús8   „A&B Á+B ÂGÂBD8Ä8%GÅ#GÆGÆAGÇGc                 ó  — |r|j                   ry 	 | j                  j                  }t        |d| j                  «      | _        d}|j                  d|«       d| _	        y # t        $ r | j                  j                  }Y ŒYw xY w)Nr>  zUThe client sent a plain HTTP request, but this server only speaks HTTPS on this port.rÍ   T)
r¾   r  Ú_sockÚAttributeErrorÚ_socketr   rA  r
  rÈ   Úlinger)r@   r\  Ú	resp_sockr  s       rH   rX  zHTTPConnection._handle_no_sslM  s~   € Ù�c×&Ò&Øð	,ØŸ™×)Ñ)ˆIô " )¨T°4·=±=ÓAˆŒ
ð:ð 	ð 	×ÑÐ-¨sÔ3Øˆ�øô ò 	,àŸ™×+Ñ+ŠIð	,ús   ‘A ÁBÂ Bc                 óÂ   — |r|j                   ry	 |j                  |«       y# t        j                  $ r Y yt        j                  $ r | j                  |«       Y yw xY w)zvRespond with an error.

        Don't bother writing if a response
        has already started being written.
        N)r¾   rÈ   r   rV  rW  rX  )r@   r\  Úresponses      rH   rP  z!HTTPConnection._conditional_error^  sY   € ñ �c×&Ò&Øð	%Ø×Ñ Õ)øÜ×#Ñ#ò 	ÙÜ× Ñ ò 	%Ø×Ñ Ö$ð	%ús   ‘# £A¸#AÁAc                 ó¦   — | j                   j                  «        | j                  s+| j                  «        | j                  j                  «        yy)z,Close the socket underlying this connection.N)rA   r€   rd  Ú_close_kernel_socketr  rc   s    rH   r€   zHTTPConnection.closen  s<   € à�
‰
×ÑÔà�{Š{Ø×%Ñ%Ô'ð �K‰K×ÑÕð r'   c                 óÂ  — d}t         s'| j                  j                  t        j                  k7  rt	        d«      ‚| j
                  st        d«      ‚	 | j                  j                  t        j                  t        j                  t        j                  |«      «      }t        j                  ||«      \  }}}|||fS # t        j                  $ r}	 t        |‚d}~ww xY w)aš  Return the PID/UID/GID tuple of the peer socket for UNIX sockets.

        This function uses SO_PEERCRED to query the UNIX PID, UID, GID
        of the peer, which is only available if the bind address is
        a UNIX domain socket.

        Raises:
            NotImplementedError: in case of unsupported socket type
            RuntimeError: in case of SO_PEERCRED lookup unsupported or disabled

        Ú3iz5SO_PEERCRED is only supported in Linux kernel and WSLz0Peer creds lookup is disabled within this serverN)Ú
IS_WINDOWSr  ÚfamilyÚAF_UNIXÚNotImplementedErrorrC  ÚRuntimeErrorÚ
getsockoptÚ
SOL_SOCKETr   ÚstructÚcalcsizeÚunpackr  )r@   ÚPEERCRED_STRUCT_DEFÚ
peer_credsÚpidÚuidÚgidÚ
socket_errs          rH   rF  zHTTPConnection.get_peer_creds�  sÑ   € ð #Ðå˜Ÿ™×+Ñ+¬v¯~©~Ò=Ü%ØGóð ð ×%Ò%ÜØBóð ð	!ØŸ™×/Ñ/ô ×!Ñ!Ü×"Ñ"Ü—‘Ð 3Ó4óˆJô" #ŸM™MÐ*=¸zÓJ‰MˆC��cØ˜˜S�=Ð øô �|‰|ò 	/ðô  JÐ.ûð	/ús   ÁAB> Â>CÃCÃCc                 ó.   — | j                  «       \  }}}|S )z,Return the id of the connected peer process.©rF  )r@   rx  rW   s      rH   Úpeer_pidzHTTPConnection.peer_pid­  s   € ð ×'Ñ'Ó)‰	ˆˆQ�Øˆ
r'   c                 ó.   — | j                  «       \  }}}|S )z1Return the user id of the connected peer process.r}  )r@   rW   ry  s      rH   Úpeer_uidzHTTPConnection.peer_uid³  s   € ð ×'Ñ'Ó)‰	ˆˆ3�Øˆ
r'   c                 ó.   — | j                  «       \  }}}|S )z2Return the group id of the connected peer process.r}  )r@   rW   rz  s      rH   Úpeer_gidzHTTPConnection.peer_gid¹  s   € ð ×'Ñ'Ó)‰	ˆˆ1ˆcØˆ
r'   c                 óþ   — t         st        d«      ‚| j                  st        d«      ‚t	        j
                  | j                  «      j                  }t        j                  | j                  «      j                  }||fS )a  Look up the username and group tuple of the ``PEERCREDS``.

        :returns: the username and group tuple of the ``PEERCREDS``

        :raises NotImplementedError: if the OS is unsupported
        :raises RuntimeError: if UID/GID lookup is unsupported or disabled
        z€UID/GID lookup is unavailable under current platform. It can only be done under UNIX-like OS but not under the Google App Enginez-UID/GID lookup is disabled within this server)ÚIS_UID_GID_RESOLVABLEro  rD  rp  ÚpwdÚgetpwuidr€  Úpw_nameÚgrpÚgetgrgidr‚  Úgr_name)r@   ÚuserÚgroups      rH   rE  z!HTTPConnection.resolve_peer_creds¿  sp   € õ %Ü%ð6óð ð
 ×-Ò-ÜØ?óð ô �|‰|˜DŸM™MÓ*×2Ñ2ˆÜ—‘˜TŸ]™]Ó+×3Ñ3ˆà�Uˆ{Ðr'   c                 ó,   — | j                  «       \  }}|S )z2Return the username of the connected peer process.©rE  )r@   r‹  rW   s      rH   Ú	peer_userzHTTPConnection.peer_user×  s   € ð ×)Ñ)Ó+‰ˆˆaØˆr'   c                 ó,   — | j                  «       \  }}|S )z/Return the group of the connected peer process.rŽ  )r@   rW   rŒ  s      rH   Ú
peer_groupzHTTPConnection.peer_groupÝ  s   € ð ×*Ñ*Ó,‰ˆˆ5Øˆr'   c                 ó*  — t        | j                  d| j                  j                  «      }	  |t        j                  «       y# t        j
                  $ r Y yt        j                  $ r'}|j                  t        j                  vr‚ Y d}~yd}~ww xY w)z0Terminate the connection at the transport level.Úsock_shutdownN)	r0  r  ÚshutdownÚ	SHUT_RDWRr   Ú#acceptable_sock_shutdown_exceptionsr  ÚerrnoÚ$acceptable_sock_shutdown_error_codes)r@   r”  Úes      rH   ri  z#HTTPConnection._close_kernel_socketã  sx   € ô Ø�K‰KØØ�K‰K× Ñ ó
ˆð	Ù”V×%Ñ%Õ&øÜ×9Ñ9ò 	ÙÜ�|‰|ò 	Ø�w‰wœf×IÑIÑIØô Jûð	ús   ­A ÁBÁBÁ+BÂB) rQ   rR   rS   rT   Úremote_addrÚremote_portÚssl_envÚioÚDEFAULT_BUFFER_SIZEr@  rA  r   rN  rC  rD  Ú	last_usedr
   r`   r_  rd  rX  rP  r€   rF  Úpropertyr~  r€  r‚  rE  r�  r‘  ri  rK   r'   rH   r   r   ï  sÜ   „ Ù-à€KØ€KØ€GØ×%Ñ%€HØ×%Ñ%€HØ%ÐØÐØ %Ðð €Ià.6ó Hò.4ðl €Fòò"%ò ò&*!ðX ñó ðð
 ñó ðð
 ñó ðò
ð0 ñó ðð
 ñó ðó
r'   r   c                   óø  — e Zd ZdZdZdZdZ	 dZ	 dZ	 dZ		 dZ
	 dZ	 dZ	 dZ	 dZ	 de›�Z	 dZ	 d	Z	 d
Z	 d
Z	 dZ	 eZ	 dZ	 d	Z	 d	Z	 d	Z	 dZ	 	 	 	 	 	 	 d&d„Zd„ Zd„ Zd„ Z e!d„ «       Z"e"jF                  d„ «       Z"d„ Z$d„ Z%d„ Z&d„ Z'd„ Z(e)jT                  d„ «       Z+e!d„ «       Z,d„ Z-d'd„Z.d(d„Z/d„ Z0e1d„ «       Z2e3	 d)d„«       Z4e1d„ «       Z5e1d „ «       Z6d!„ Z7e!d"„ «       Z8e!d#„ «       Z9e8jF                  d$„ «       Z8d%„ Z:y)*r   zAn HTTP server.z	127.0.0.1Nr   rÎ   é
   g      à?zCheroot/Fr   Tc	                 ó  — || _         || _        t        j                  | |xs d|¬«      | _        |s| j
                  }|| _        || _        |xr || _        || _	        | j                  «        t        j                  «       | _        y)a  Initialize HTTPServer instance.

        Args:
            bind_addr (tuple): network interface to listen to
            gateway (Gateway): gateway for processing HTTP requests
            minthreads (int): minimum number of threads for HTTP thread pool
            maxthreads (int): maximum number of threads for HTTP thread pool
            server_name (str): web server name to be advertised via Server
                HTTP header
            reuse_port (bool): if True SO_REUSEPORT option would be set to
                socket
        r   )r‘   ÚmaxN)Ú	bind_addrr  r   Ú
ThreadPoolÚrequestsÚversionr4  rC  rD  Ú
reuse_portÚclear_statsÚqueueÚQueueÚ_unservicable_conns)	r@   r¥  r  Ú
minthreadsÚ
maxthreadsr4  rC  rD  r©  s	            rH   r`   zHTTPServer.__init__U  sƒ   € ð. #ˆŒØˆŒä"×-Ñ-ØØ’˜aØô
ˆŒñ ØŸ,™,ˆKØ&ˆÔØ!2ˆÔà%Ò;Ð*;ð 	Ô&ð %ˆŒØ×ÑÔä#(§;¡;£=ˆÕ r'   c                 ó  ‡ — d‰ _         d‰ _        i dd“dˆ fd„“dˆ fd„“d	d“d
ˆ fd„“dˆ fd„“dˆ fd„“dˆ fd„“dd“dd„ “dd„ “dd„ “dd„ “dd„ “dd„ “di “‰ _        ‰ j                  t        j                  d t        ‰ «      z  <   y)!zReset server stat counters..Nr   rJ  FzBind Addressc                 ó.   •— t        ‰j                  «      S rO   )r¥   r¥  ©Úsr@   s    €rH   ú<lambda>z(HTTPServer.clear_stats.<locals>.<lambda>‡  s   ø€ ¤d¨4¯>©>Ó&:€ r'   zRun timec                 ó<   •— | d    xr dxs ‰j                  «       S )NrJ  ro   ©Úruntimer²  s    €rH   r´  z(HTTPServer.clear_stats.<locals>.<lambda>ˆ  s$   ø€ ¨¨)©Ð$4Ò#<¸"ò #Ø�|‰|‹~ð r'   ÚAcceptszAccepts/secc                 ó0   •— | d   ‰j                  «       z  S )Nr¸  r¶  r²  s    €rH   r´  z(HTTPServer.clear_stats.<locals>.<lambda>‹  s   ø€  Q y¡\°D·L±L³NÑ%B€ r'   r¬  c                 ó2   •— t        ‰j                  dd «      S )NÚqsize©r0  r§  r²  s    €rH   r´  z(HTTPServer.clear_stats.<locals>.<lambda>Œ  s   ø€ œw t§}¡}°g¸tÓD€ r'   ÚThreadsc                 óD   •— t        t        ‰j                  dg «      «      S )NÚ_threads)rh   r0  r§  r²  s    €rH   r´  z(HTTPServer.clear_stats.<locals>.<lambda>�  s   ø€ ¤¤W¨T¯]©]¸JÈÓ%KÓ!L€ r'   zThreads Idlec                 ó2   •— t        ‰j                  dd «      S )NÚidler¼  r²  s    €rH   r´  z(HTTPServer.clear_stats.<locals>.<lambda>Ž  s   ø€ ¤g¨d¯m©m¸VÀTÓ&J€ r'   zSocket ErrorsÚRequestsc                 ób   — | d    xr dxs$ t        d„ | d   j                  «       D «       d«      S )NrJ  ro   c              3   ó2   K  — | ]  } |d    |«      –— Œ y­w)rÂ  NrK   ©Ú.0Úws     rH   ú	<genexpr>z;HTTPServer.clear_stats.<locals>.<lambda>.<locals>.<genexpr>’  s   è ø€ ÒH a���:‘˜q×!ÑHùó   ‚úWorker Threadsr   ©ÚsumÚvalues©r³  s    rH   r´  z(HTTPServer.clear_stats.<locals>.<lambda>�  s<   € ¨¨)©Ð$4Ò#<¸"ò #ÜÙH¨1Ð-=Ñ+>×+EÑ+EÓ+GÔHØóð r'   ú
Bytes Readc                 ób   — | d    xr dxs$ t        d„ | d   j                  «       D «       d«      S )NrJ  ro   c              3   ó2   K  — | ]  } |d    |«      –— Œ y­w)rÏ  NrK   rÅ  s     rH   rÈ  z;HTTPServer.clear_stats.<locals>.<lambda>.<locals>.<genexpr>—  s   è ø€ ÒJ¨���<‘ ×#ÑJùrÉ  rÊ  r   rË  rÎ  s    rH   r´  z(HTTPServer.clear_stats.<locals>.<lambda>•  s<   € ¨!¨I©,Ð&6Ò%>¸Bò %ÜÙJ¨QÐ/?Ñ-@×-GÑ-GÓ-IÔJØóð r'   úBytes Writtenc                 ób   — | d    xr dxs$ t        d„ | d   j                  «       D «       d«      S )NrJ  ro   c              3   ó2   K  — | ]  } |d    |«      –— Œ y­w)rÒ  NrK   rÅ  s     rH   rÈ  z;HTTPServer.clear_stats.<locals>.<lambda>.<locals>.<genexpr>œ  s   è ø€ ÒM¨1Ð#��?Ñ# A×&ÑMùrÉ  rÊ  r   rË  rÎ  s    rH   r´  z(HTTPServer.clear_stats.<locals>.<lambda>š  s<   € ¨Q¨y©\Ð)9Ò(A¸rò (ÜÙM°Ð2BÑ0C×0JÑ0JÓ0LÔMØóð r'   ú	Work Timec                 ób   — | d    xr dxs$ t        d„ | d   j                  «       D «       d«      S )NrJ  ro   c              3   ó2   K  — | ]  } |d    |«      –— Œ y­w)rÕ  NrK   rÅ  s     rH   rÈ  z;HTTPServer.clear_stats.<locals>.<lambda>.<locals>.<genexpr>¡  s   è ø€ ÒI q���;‘ ×"ÑIùrÉ  rÊ  r   rË  rÎ  s    rH   r´  z(HTTPServer.clear_stats.<locals>.<lambda>Ÿ  s<   € ¨¨9©Ð%5Ò$=¸2ò $ÜÙI¨AÐ.>Ñ,?×,FÑ,FÓ,HÔIØóð r'   zRead Throughputc                 ób   — | d    xr dxs$ t        d„ | d   j                  «       D «       d«      S )NrJ  ro   c              3   óR   K  — | ]  } |d    |«       |d   |«      xs dz  –— Œ! y­w)rÏ  rÕ  ç�íµ ÷Æ°>NrK   rÅ  s     rH   rÈ  z;HTTPServer.clear_stats.<locals>.<lambda>.<locals>.<genexpr>¦  s8   è ø€ ò àð $�A�l‘O AÓ&¨.¨!¨K©.¸Ó*;Ò*C¸tÕDñùó   ‚%'rÊ  r   rË  rÎ  s    rH   r´  z(HTTPServer.clear_stats.<locals>.<lambda>¤  sC   € ¨q°©|Ð+;Ò*CÀò *ÜñàÐ/Ñ0×7Ñ7Ó9ôð óð r'   zWrite Throughputc                 ób   — | d    xr dxs$ t        d„ | d   j                  «       D «       d«      S )NrJ  ro   c              3   óR   K  — | ]  } |d    |«       |d   |«      xs dz  –— Œ! y­w)rÒ  rÕ  rÚ  NrK   rÅ  s     rH   rÈ  z;HTTPServer.clear_stats.<locals>.<lambda>.<locals>.<genexpr>®  s9   è ø€ ò àð '�A�oÑ& qÓ)¨^¨Q¨{©^¸AÓ->Ò-FÀ$ÕGñùrÛ  rÊ  r   rË  rÎ  s    rH   r´  z(HTTPServer.clear_stats.<locals>.<lambda>¬  sC   € °°)±Ð,<Ò+DÀ"ò +ÜñàÐ/Ñ0×7Ñ7Ó9ôð óð r'   rÊ  zCheroot HTTPServer %d)Ú_start_timeÚ	_run_timerO  rR  r-   Úidrc   s   `rH   rª  zHTTPServer.clear_stats�  s  ø€ àˆÔØˆŒð0
Ø�uð0
àÓ:ð0
ð ó ð0
ð
 �qð0
ð ÓBð0
ð ÓDð0
ð ÓLð0
ð ÓJð0
ð ˜Qð0
ð ñ ð0
ð  ñ ð!0
ð* ñ ð+0
ð4 ñ ð50
ð> ñ  ð?0
ðN ñ !ðO0
ð^ ˜bð_0
ˆŒ
ðb BFÇÁŒ×ÑÐ2´R¸³XÑ=Ò>r'   c                 óŽ   — | j                   €| j                  S | j                  t        j                  «       | j                   z
  z   S )zReturn server uptime.)rÞ  rß  Útimerc   s    rH   r·  zHTTPServer.runtime¸  s8   € à×ÑÐ#Ø—>‘>Ð!Ø�~‰~¤§¡£¨t×/?Ñ/?Ñ!?Ñ@Ð@r'   c                 óh   — | j                   ›d| j                  j                  ›d| j                  ›d�S )z1Render Server instance representing bind address.ú.ú(r    )rR   rZ   rQ   r¥  rc   s    rH   Ú__str__zHTTPServer.__str__¾  s)   € ð �O‹OØ�N‰N×#Ó#Ø�N‹Nð
ð 	
r'   c                 ó   — | j                   S )a³  Return the interface on which to listen for connections.

        For TCP sockets, a (host, port) tuple. Host values may be any
        :term:`IPv4` or :term:`IPv6` address, or any valid hostname.
        The string 'localhost' is a synonym for '127.0.0.1' (or '::1',
        if your hosts file prefers :term:`IPv6`).
        The string '0.0.0.0' is a special :term:`IPv4` entry meaning
        "any active interface" (INADDR_ANY), and '::' is the similar
        IN6ADDR_ANY for :term:`IPv6`.
        The empty string or :py:data:`None` are not allowed.

        For UNIX sockets, supply the file name as a string.

        Systemd socket activation is automatic and doesn't require tempering
        with this variable.

        .. glossary::

           :abbr:`IPv4 (Internet Protocol version 4)`
              Internet Protocol version 4

           :abbr:`IPv6 (Internet Protocol version 6)`
              Internet Protocol version 6
        )Ú
_bind_addrrc   s    rH   r¥  zHTTPServer.bind_addrÆ  s   € ð4 �‰Ðr'   c                 óV   — t        |t        «      r|d   dv rt        d«      ‚|| _        y)z5Set the interface on which to listen for connections.r   >   Nr   zzHost values of '' or None are not allowed. Use '0.0.0.0' (IPv4) or '::' (IPv6) instead to listen on all active interfaces.N)r  rÒ   r3   rè  )r@   r6  s     rH   r¥  zHTTPServer.bind_addrâ  s6   € ô �eœUÔ#¨¨a©°JÑ(>ô ð6óð ð
  ˆ�r'   c                 óÀ   — 	 | j                  «        y# t        $ r}| j                  }|s|| _        ||‚d}~wt        $ r}| j                  }|s|| _        ||‚d}~ww xY w)z4Run the server forever, and stop it cleanly on exit.N)ÚstartrT  Ú	interruptrU  )r@   Úkb_intr_excÚunderlying_interruptÚsys_exit_excs       rH   Ú
safe_startzHTTPServer.safe_start÷  sc   € ð	9Ø�J‰J�LøÜ ò 	8Ø#'§>¡>Ð Ù'Ø!,�”ØÐ#7Ð7ûÜò 	9Ø#'§>¡>Ð Ù'Ø!-�”ØÐ$8Ð8ûð		9ús   ‚ “	Aœ4´AÁ AÁAc                 óÞ  — d| _         | j                  €d| j                  z  | _        d| _        d}t	        j
                  dd«      r9t        j                  dt        j                  t        j                  «      | _        nµt        | j                  t        t        f«      r	 | j                  | j                  «       nx| j                  \  }}	 t        j                  ||t        j                   t        j                  d	t        j"                  «      }|D ]  }|\  }	}
}}}	 | j)                  |	|
|«        n | j                  st        j                  |«      ‚| j                  j-                  d«       | j                  j/                  | j0                  «       t3        j4                  | «      | _        | j8                  j;                  «        d| _        t?        j>                  «       | _         y# t        j                  $ r0}|›d| j                  ›d|›d�}t        j                  |«      |‚d}~ww xY w# t        j$                  $ rO t        j                  }| j                  }d
|v rt        j&                  }|dz   }|t        j                  d	d|fg}Y �Œ�w xY w# t        j                  $ rC}|›d|›d|›d�}| j                  r| j                  j+                  «        d| _        Y d}~�ŒÔd}~ww xY w)zšPrepare server to serving requests.

        It binds a socket's port, setups the socket to ``listen()`` and does
        other preparing things.
        Nz	%s ServerzNo socket could be createdÚ
LISTEN_PIDr  z -- (z: r    r   ú:)r   r   r   r   T)!Ú
_interruptÚsoftwarer¨  r  ÚosÚgetenvÚfromfdÚAF_INETÚSOCK_STREAMr  r¥  r  ÚbytesÚbind_unix_socketr  ÚgetaddrinfoÚ	AF_UNSPECÚ
AI_PASSIVEÚgaierrorr   Úbindr€   Ú
settimeoutÚlistenÚrequest_queue_sizer   ÚConnectionManagerÚ_connectionsr§  rë  r¶   râ  rÞ  )r@   r  ÚserrÚhostrÞ   ÚinfoÚ	sock_typer¥  rs   ÚafÚsocktyper:  Ú
_canonnameÚsas                 rH   ÚpreparezHTTPServer.prepare  s^  € ð ˆŒà�=‰=Ð Ø'¨$¯,©,Ñ6ˆDŒMð ˆŒØ*ˆÜ�9‰9�\ 4Ô(ä Ÿ-™-¨¬6¯>©>¼6×;MÑ;MÓNˆD�KÜ˜Ÿ™¬¬e¨Ô5ð2Ø×%Ñ% d§n¡nÕ5ð Ÿ™‰JˆD�$ðKÜ×)Ñ)ØØÜ×$Ñ$Ü×&Ñ&ØÜ×%Ñ%ó�ð$ ò 	'�Ø69Ñ3��H˜e Z°ð'Ø—I‘I˜b (¨EÔ2Ùð		'ð �{Š{Ü—,‘,˜sÓ#Ð#ð 	�‰×Ñ˜qÔ!Ø�‰×Ñ˜4×2Ñ2Ô3ô (×9Ñ9¸$Ó?ˆÔð 	�‰×ÑÔàˆŒ
ÜŸ9™9›;ˆÕøôi —<‘<ò 2Ú*-¨t¯~«~ºtÐD�Ü—l‘l 3Ó'¨TÐ1ûð2ûô" —?‘?ò KÜ"ŸN™N�	Ø ŸN™N�	à˜$‘;Ü &§¡�IØ )¨FÑ 2�Ià"¤F×$6Ñ$6¸¸2¸yÐIÐJ“ðKûô —|‘|ò 'Ú.1²2²tÐ<�CØ—{’{ØŸ™×)Ñ)Ô+Ø"&�D—K’Kûð	'úsD   Â!G+ ÃAH1 ÄJÇ+H.Ç>+H)È)H.È1AJÊJÊK,Ê)8K'Ë'K,c                 ó²  — | j                   rf| j                  j                  «       }|t        u ryt	        | |«      }	 |j                  d«       d|_        |j!                  «        | j                   rŒeyy# t        t        j                  f$ r Y ŒŽt        $ r?}| j                  j                  t        |«      t        j                  d¬«       Y d}~Œƒd}~ww xY w)z(Serve connections we can't handle a 503.Nz503 Service UnavailableTrK  )r¶   r­  r>   Ú_STOPPING_FOR_INTERRUPTr   rÈ   ÚOSErrorr   rV  rY  r´   rQ  r¥   rR  rZ  rd  r€   )r@   rµ   Úrequestrû   s       rH   Ú_serve_unservicablezHTTPServer._serve_unservicableQ  s½   € à�jŠjØ×+Ñ+×/Ñ/Ó1ˆDØÔ.Ñ.ØÜ! $¨Ó-ˆGðØ×'Ñ'Ð(AÔBð ˆDŒKØ�J‰JŒLð+ �j�jøô œV×1Ñ1Ð2ò ñ Üò ð —‘×%Ñ%Ü˜“HÜ!Ÿ-™-Ø"ð &÷ ñ ûð	ús   ½A4 Á4CÂCÂ5CÃCc                 ó4  — t        j                  | j                  ¬«      j                  «        | j                  rK| j
                  s?	 | j                  j                  | j                  «       | j                  r| j
                  sŒ?| j
                  rG| j                  r"t!        j"                  d«       | j                  rŒ"| j
                  r| j
                  ‚yy# t        t        f$ r ‚ t        $ r% | j                  dt        j                  d¬«       Y Œ©w xY w)z1Serve requests, after invoking :func:`prepare()`.©ÚtargetzError in HTTPServer.serveTrK  gš™™™™™¹?N)Ú	threadingÚThreadr  rë  r¶   rì  r  ÚrunÚexpiration_intervalrT  rU  rY  rQ  rR  rZ  Ú_stopping_for_interruptrâ  Úsleeprc   s    rH   ÚservezHTTPServer.servej  sÞ   € ô
 	×Ñ × 8Ñ 8Ô9×?Ñ?ÔAà�jŠj §¢ð	Ø×!Ñ!×%Ñ% d×&>Ñ&>Ô?ð �jŠj §£ð �>Š>Ø×.Ò.Ü—
‘
˜3”ð ×.Ó.à�~Š~Ø—n‘nÐ$ð ð øô &¤zÐ2ò ØÜò Ø—‘Ø/Ü!Ÿ-™-Ø"ð ö ðús   Á%C Ã:DÄDc                 óD   — | j                  «        | j                  «        y)zmRun the server forever.

        It is shortcut for invoking :func:`prepare()` then :func:`serve()`.
        N)r  r  rc   s    rH   rë  zHTTPServer.start…  s   € ð 	�‰ŒØ�
‰
�r'   c              #   óî   K  — | j                  «        t        j                  | j                  ¬«      }d|_        |j                  «        	 |–— | j                  «        y# | j                  «        w xY w­w)z4Context manager for running this server in a thread.r  TN)r  r  r  r  Údaemonrë  Ústop)r@   Úthreads     rH   Ú_run_in_threadzHTTPServer._run_in_thread‘  sQ   è ø€ ð 	�‰ŒÜ×!Ñ!¨¯©Ô4ˆØˆŒØ�‰Œð	ØŠLà�I‰I�KøˆD�I‰I�Küs   ‚AA5ÁA  ÁA5Á A2Á2A5c                 óJ   — | j                   xr | j                  j                  S )z>Flag whether it is allowed to add a new keep-alive connection.)r¶   r  r.  rc   s    rH   r.  z'HTTPServer.can_add_keepalive_connection�  s   € ð �z‰zÒL˜d×/Ñ/×LÑLÐLr'   c                 ót   — | j                   r| j                  j                  |«       y|j                  «        y)z7Put an idle connection back into the ConnectionManager.N)r¶   r  Úputr€   ©r@   rµ   s     rH   Úput_connzHTTPServer.put_conn¢  s(   € à�:Š:Ø×Ñ×!Ñ! $Õ'ð �J‰J�Lr'   c                 ó,  — t         j                  j                  |›d�«       t         j                  j                  «        |rRt	        j
                  «       }t         j                  j                  |«       t         j                  j                  «        yy)zôWrite error message to log.

        :param msg: error message
        :type msg: str

        :param level: logging level
        :type level: int

        :param traceback: add traceback to output or not
        :type traceback: bool
        ú
N)ÚsysÚstderrr  ÚflushÚ
traceback_Ú
format_exc)r@   r  rL  rM  Útbliness        rH   rQ  zHTTPServer.error_logª  sd   € ô 	�
‰
×Ñ˜C˜7 "˜Ô&Ü�
‰
×ÑÔÙÜ ×+Ñ+Ó-ˆGÜ�J‰J×Ñ˜WÔ%Ü�J‰J×ÑÕð r'   c           	      óö   — | j                  | j                  |||| j                  | j                  | j                  «      }| j                  || j                  «      x}| _        | j                  |«      | _        |S )z.Create (or recreate) the actual socket object.)Úprepare_socketr¥  Únodelayr¹   r©  Úbind_socketr  Úresolve_real_bind_addr)r@   rm  Útyper:  rG  s        rH   r  zHTTPServer.bind¾  so   € à×"Ñ"Ø�N‰NØØØØ�L‰LØ×ÑØ�O‰Oó
ˆð "×-Ñ-¨d°D·N±NÓCÐCˆˆtŒ{Ø×4Ñ4°TÓ:ˆŒØˆr'   c           	      óÚ  — t         r	 t        d«      ‚d}	 t        j                  | j                  «       | j                  |t        j                  t        j                  d| j                  | j                  | j                  ¬	«      }	 	 t        j                  |j!                  «       |«       d
}	 | j#                  ||«      }| j)                  |«      }	 	 |s	 t        j*                  ||«       d
}|s!| j1                  dt2        j4                  ¬«       || _        || _	        |S # t
        $ r Y Œùt        $ r}t        |«      }d|vr‚ Y d}~�Œd}~wt        $ r#}t        |«      }d|vr	d|vrd|vr‚ Y d}~�ŒAd}~ww xY w# t
        $ r d}Y ŒÜw xY w# t        j$                  $ r |j'                  «        ‚ w xY w# t,        $ r t        j.                  ||d¬«       Y Œìw xY w# t
        $ r Y Œùw xY w)z*Create (or recreate) a UNIX socket object.z0AF_UNIX sockets are not supported under Windows.iÿ  zJremove() argument 1 must be encoded string without null bytes, not unicodeNz'unlink: embedded null character in pathzembedded null bytez0argument must be a string without NUL charactersr   )r¥  rm  r7  r:  r4  r¹   r©  TF)Úfollow_symlinksz(Failed to set socket fs mode permissions)rL  )rl  r3   rö  Úunlinkr¥  r  Ú	TypeErrorr  r3  r  rn  rú  r4  r¹   r©  ÚfchmodÚfilenor5  r  r€   r6  Úlchmodrb  ÚchmodrQ  rR  rS  )r@   r¥  Úfs_permissionsÚtyp_errÚerr_msgÚval_errrG  ÚFS_PERMS_SETs           rH   rü  zHTTPServer.bind_unix_socketÍ  s  € åðô ØBóð ð ˆð	ä�I‰I�d—n‘nÔ%ð, ×"Ñ"ØÜ—>‘>Ü×#Ñ#ØØ—L‘LØ×(Ñ(Ø—‘ð #ó 
ˆð	!ØBä�I‰I�d—k‘k“m ^Ô4ØˆLð	Ø×#Ñ# D¨)Ó4ˆDð
 ×/Ñ/°Ó5ˆ	ð		ØCÙðOÜ—I‘I˜i¨Ô8ð  $�ñ Ø�N‰NØ:Ü—o‘oð ô ð
 #ˆŒØˆŒØˆøôE ò 	ñô ò 	Ü˜'“lˆGð9Ø@GñHð õHûô ò 	Ü˜'“lˆGà9ÀÑHØ(°Ñ7ØFØñð ÿùð	ûô2 ò 	!Ø ŠLð	!ûô
 �|‰|ò 	Ø�J‰JŒLØð	ûô &ò OÜ—H‘H˜Y¨È×NðOûô ò 	Ùð	ús}   –D# Â'E> Â0F ÃG ÃF7 Ã.G Ä#	E;Ä.E;Ä6EÅE;ÅE6Å6E;Å>FÆFÆ%F4Æ7!GÇG ÇGÇG Ç	G*Ç)G*c                 ó&  — |d d \  }}|dk(  }| j                   t        j                  t        j                  hvrt	        d«      ‚|rt	        d«      ‚t        t        d«      r0| j                  t        j                  t        j                  d«       y t        t        d«      r0| j                  t        j                  t        j                  d«       y t        r0| j                  t        j                  t        j                  d«       y t        d«      ‚)	NrŸ   r   zCannot reuse a non-IP socketz"Cannot reuse an ephemeral port (0)ÚSO_REUSEPORT_LBr   ÚSO_REUSEPORTz,Current platform does not support port reuse)rm  r  rù  r   r3   ÚhasattrÚ
setsockoptrr  rF  rG  rl  ÚSO_REUSEADDRro  )Úsocket_r¥  Ú_hostrÞ   ÚIS_EPHEMERAL_PORTs        rH   Ú_make_socket_reusablez HTTPServer._make_socket_reusable!  sÓ   € à  �m‰ˆˆtØ  A™IÐà�>‰>¤&§.¡.´&·/±/Ð!BÑBÜÐ;Ó<Ð<áÜÐAÓBÐBô ”6Ð,Ô-Ø×Ñœv×0Ñ0´&×2HÑ2HÈ!ÕLÜ”V˜^Ô,Ø×Ñœv×0Ñ0´&×2EÑ2EÀqÕIÝØ×Ñœv×0Ñ0´&×2EÑ2EÀqÕIä%Ø>óð r'   c                 óþ  — t        j                   |||«      }t        j                  |«       |dd \  }	}
|
dk(  }|r| j                  ||¬«       t        s2|s0	 |j                  t         j                  t         j                  d«       |rEt        |t        t        f«      s/|j                  t         j                  t         j                  d«       |�|j                  |«      }t        t         d«      xr |t         j                  k(  xr |	dv }|rbt!        j"                  t$        t         j&                  «      5  |j                  t         j(                  t         j*                  d«       ddd«       |S |S # 1 sw Y   |S xY w)z%Create and prepare the socket object.NrŸ   r   ©rK  r¥  r   r   >   ú::ú::0ú	::0.0.0.0)r  r   Úprevent_socket_inheritancerN  rl  rI  rr  rJ  r  r  rû  ÚIPPROTO_TCPÚTCP_NODELAYr  rH  r   rÜ   rÝ   rb  r  r   r   )Úclsr¥  rm  r7  r:  r4  r¹   r©  rG  r  rÞ   rM  Úlistening_ipv6s                rH   r3  zHTTPServer.prepare_socket;  sL  € ô �}‰}˜V T¨5Ó1ˆÜ×.Ñ.¨tÔ4à˜r �]‰
ˆˆdØ  A™IÐáØ×%Ñ%¨d¸iÐ%ÔHåÑ/ð	ð �O‰OœF×-Ñ-¬v×/BÑ/BÀAÔFÙœ: i´#´u°Ô>Ø�O‰OœF×.Ñ.´×0BÑ0BÀAÔFàÐ"Ø×#Ñ# DÓ)ˆDô ”F˜JÓ'ò 3Øœ&Ÿ/™/Ñ)ò3àÐ2Ð2ð 	ñ
 Ü×$Ñ$¤^´V·\±\ÓBñ ð —‘Ü×'Ñ'Ü×&Ñ&Øô÷ð ˆˆtˆ÷ð ˆús   Ä60E2Å2E<c                 ó(   — | j                  |«       | S )z#Bind the socket to given interface.)r  rP  s     rH   r5  zHTTPServer.bind_socketv  s   € ð 	�‰�YÔØˆr'   c                 óÀ   — | j                  «       }| j                  t        j                  t        j                  hv r	 |dd S t        |t        «      rt        |«      }|S )z/Retrieve actual bind address from bound socket.NrŸ   )Úgetsocknamerm  r  rù  r   r  rû  r	   rP  s     rH   r6  z!HTTPServer.resolve_real_bind_addr|  s]   € ð
 ×'Ñ'Ó)ˆ	Ø�>‰>ä�N‰NÜ�O‰Oð
ñ 
ð
ð ˜R˜a�=Ð ä�i¤Ô'Ü˜Y›ˆIàÐr'   c                 ó¤   — 	 | j                   j                  |«       y# t        j                  $ r | j                  j                  |«       Y yw xY w)z#Process an incoming HTTPConnection.N)r§  r'  r«  ÚFullr­  r(  s     rH   Úprocess_connzHTTPServer.process_conn’  s@   € ð	/Ø�M‰M×Ñ˜dÕ#øÜ�z‰zò 	/Ø×$Ñ$×(Ñ(¨Ö.ð	/ús   ‚ ž.AÁAc                 ó   — | j                   S )zFlag interrupt of the server.)rô  rc   s    rH   rì  zHTTPServer.interrupt™  s   € ð �‰Ðr'   c                 ó&   — | j                   t        u S )z8Return whether the server is responding to an interrupt.)rô  r  rc   s    rH   r  z"HTTPServer._stopping_for_interruptž  s   € ð �‰Ô"9Ð9Ð9r'   c                 óÌ   — t         | _        t        |t        «      r| j	                  d«       t        |t
        «      r| j	                  d«       | j                  «        || _        y)a  Perform the shutdown of this server and save the exception.

        Typically invoked by a worker thread in
        :py:mod:`~cheroot.workers.threadpool`, the exception is raised
        from the thread running :py:meth:`serve` once :py:meth:`stop`
        has completed.
        z!Keyboard Interrupt: shutting downz SystemExit raised: shutting downN)r  rô  r  rT  rQ  rU  r"  )r@   rì  s     rH   rì  zHTTPServer.interrupt£  sJ   € ô 2ˆŒä�iÔ!2Ô3Ø�N‰NÐ>Ô?ä�i¤Ô,Ø�N‰NÐ=Ô>à�	‰	ŒØ#ˆ�r'   c                 ór  — | j                   syd| _         | j                  j                  t        «       | j                  �4| xj
                  t        j                  «       | j                  z
  z  c_        d| _        | j                  j                  «        t        | dd«      }|rêt        | j                  t        t        f«      s§	 |j                  «       dd \  }}t        j                   ||t        j"                  t        j$                  «      D ]X  }|\  }}}}}	d}
	 t        j                  |||«      }
|
j'                  d«       |
j)                  ||f«       |
j+                  «        ŒZ 	 t5        |d«      r|j+                  «        d| _        | j                  j+                  «        | j6                  j                  | j8                  «       y# t        j,                  $ r |
r|
j+                  «        Y Œæw xY w# t        j,                  $ r*}|j.                  d   t0        j2                  vr‚ Y d}~ŒÆd}~ww xY w)z5Gracefully shutdown a server that is serving forever.NFr  rŸ   g      ð?r   r€   )r¶   r­  r'  r  rÞ  rß  râ  r  r"  r0  r  r¥  r  rû  r[  r  rý  rþ  rú  r  Úconnectr€   r  rã   r   r  rH  r§  Úshutdown_timeout)r@   rG  r  rÞ   rs   r  r  r:  r  Ú_sar³  rû   s               rH   r"  zHTTPServer.stop·  sÙ  € à�zŠzØàˆŒ
ð 	× Ñ ×$Ñ$Ô%<Ô=à×ÑÐ'Ø�NŠNœdŸi™i›k¨D×,<Ñ,<Ñ<Ñ<�NØˆÔà×Ñ×ÑÔ ä�t˜X tÓ,ˆÙÜ˜dŸn™n¬s´E¨lÔ;ð*Ø!%×!1Ñ!1Ó!3°B°QÐ!7‘J�D˜$ô  &×1Ñ1ØØÜ×(Ñ(Ü×*Ñ*ó	 ò *˜ð @CÑ<˜˜H e¨Z¸Ø ˜ð
*Ü &§¡¨b°(¸EÓ B˜Að ŸL™L¨Ô-ØŸI™I t¨T lÔ3ØŸG™G�Iñ*ô& �t˜WÔ%Ø—
‘
”ØˆDŒKà×Ñ×ÑÔ!Ø�‰×Ñ˜4×0Ñ0Õ1øô  &Ÿ|™|ò *Ù Ø !§¡¤	ùð*ûô7 —|‘|ò Ø—w‘w˜q‘z¬×)GÑ)GÑGð ô	 Hûðús+   ÃG9 ÄAGÇ%G6Ç5G6Ç9H6È H1È1H6)r¢  ro   NFFF)r   é   Fr‹   )F);rQ   rR   rS   rT   rè  rô  r  r®  r¯  r4  rè   r  rd  r/  r  r   r¨  rõ  r¶   rÆ   r  r4  r   ÚConnectionClassr¹   rC  rD  r©  Úkeep_alive_conn_limitr`   rª  r·  ræ  r   r¥  Úsetterrð  r  r  r  rë  rÜ   Úcontextmanagerr$  r.  r)  rQ  r  rü  ÚstaticmethodrN  Úclassmethodr3  r5  r6  r^  rì  r  r"  rK   r'   rH   r   r   õ  sJ  „ Ùà€JØ€Jà€GØà€JØFà€Jðð €KØ?à€Hð&ð
 Ðð/ð Ððð €GØGàÐðð ˜˜Ð(€GØ.à€Hðð
 €EØMàÐØMàÐØLà€GØNà$€OØ9à€Kðð Ððð
 !&Ððð
 €JØ2àÐðAð ØØØØ"'Øó*1òX5LònAò
ð ñó ðð6 ×Ññ ó ð ò(9òI'òVò2%ò6
ð ×Ññ	ó ð	ð ñMó ðMòóó(òRðh ñó ðð2 ð ò8ó ð8ðt ñó ðð
 ñó ðò*/ð ñó ðð ñ:ó ð:ð ×Ññ$ó ð$ó&:2r'   r   c                   ó   — e Zd ZdZd„ Zd„ Zy)r   zDBase class to interface HTTPServer with other systems, such as WSGI.c                 ó   — || _         y)zuInitialize Gateway instance with request.

        Args:
            req (HTTPRequest): current HTTP request
        N)r\  )r@   r\  s     rH   r`   zGateway.__init__÷  s   € ð ˆ�r'   c                 ó   — t         ‚)z>Process the current request. Must be overridden in a subclass.)ro  rc   s    rH   r  zGateway.respondÿ  s   € ä!Ð!r'   N)rQ   rR   rS   rT   r`   r  rK   r'   rH   r   r   ô  s   „ ÙNòó"r'   r   z%cheroot.ssl.builtin.BuiltinSSLAdapterz&cheroot.ssl.pyopenssl.pyOpenSSLAdapter)ÚbuiltinÚ	pyopensslc                 ó‚  — t         | j                  «          }t        |t        «      rJ|j	                  d«      }||dz   d }|d| }	 t
        j                  |   }|€t        ‚	 	 t        ||«      }|S |S # t        $ r" t        |t        «       t        «       dg«      }Y Œ;w xY w# t        $ r t        d|›d|›d�«      ‚w xY w)z/Return an SSL adapter class for the given name.rä  r   Nr   ú'z' object has no attribute ')Ússl_adaptersr  r  r  Úrfindr,  ÚmodulesÚKeyErrorÚ
__import__ÚglobalsÚlocalsr0  rb  )ÚnameÚadapterÚlast_dotÚ	attr_nameÚmod_pathÚmods         rH   r   r   	  sÓ   € ä˜4Ÿ:™:›<Ñ(€GÜ�'œ3ÔØ—=‘= Ó%ˆØ˜H q™L˜NÐ+ˆ	Ø˜9˜HÐ%ˆð	BÜ—+‘+˜hÑ'ˆCØˆ{Ü�ð ð	Ü˜c 9Ó-ˆGð €Nˆ7€Nøô ò 	Bä˜X¤w£y´&³(¸R¸DÓAŠCð	Bûô ò 	Ý Ú7?ÂÐKóð ð	ús   ÁA4 Á$B" Á4(BÂBÂ"B>)rp  )KrT   rÜ   Úemail.utilsr1  r�  rR  rö  Úplatformr«  Úrer  r,  r  râ  rM  r/  Úurllib.parserØ   Ú	functoolsr   r   r   r   r   Ú_compatr   r	   rH  r
   r   Úworkersr   Ú__all__Úsystemrl  r÷  rÑ   ÚIS_GAEr„  rˆ  r…  ÚImportErrorrs  rH  r   r   r   rq   r4   r7   r6   r:   r¡   rr   ÚASTERISKrà   rä   Úcompiler?   rá   rY  r  r=   r-   r   r   r   r   r   r   r   r   r   rt  r   rK   r'   rH   ú<module>rŽ     s<  ðñAóF Û Û 	Û Û 	Û Û Û 	Û Û 
Û Û Û Û Ý ç .Ñ .ß !ß ,Ý ð€ð ˆX�_‰_Ó )Ñ+€
Ø ?ð 
ˆ�‰Ð$ bÓ	)×	4Ñ	4Ð5IÓ	J€ðð '˜Ò5¨v¨:Ð Ø Nñ ð
ÛÛô à'Ñ€Cˆˆfñ ‘'˜& *Ô-Ù�6˜>Ô*Ø ˆÔÙ�6˜=Ô)ØˆÔñ ˆv�}Ô%ðñ
  &™¨2€FÔð €Ø€Ø€Ø€Ø€Ø€	Ø€Ø€Ø€Ø€Ø�R—Z‘Z §¡¨'°<Ð)@Ó AÓBÐ ñ $›+Ð òÐ ñ6 ˆw˜Ô%Ø€GÔ÷D(ñ D(ôN, ô ,÷^ñ ^÷BWñ W÷t~ñ ~÷BY	/ñ Y	/÷xCñ C÷L|2ñ |2÷~"ñ "ð& 7Ø9ñ€ôøðaD ò ð	ð
 !&ÐØ‰ˆ‹Sðús   Â'F1 Æ1GÇG