o
    )Zh	?                     @   s  d Z ddlZddlZddlmZ ddlmZmZ ddlm	Z	 ddlm
Z
 ddlmZ ddlmZ dd	lmZ ddlZdd
lmZmZmZmZmZmZmZmZmZ ejrYddlmZ G dd deee	jZG dd de	jZG dd de Z!G dd de	jZ"e	j#Z$dS )a  A non-blocking, single-threaded HTTP server.

Typical applications have little direct interaction with the `HTTPServer`
class except to start a server at the beginning of the process
(and even that is often done indirectly via `tornado.web.Application.listen`).

.. versionchanged:: 4.0

   The ``HTTPRequest`` class that used to live in this module has been moved
   to `tornado.httputil.HTTPServerRequest`.  The old name remains as an alias.
    N)
native_str)HTTP1ServerConnectionHTTP1ConnectionParameters)httputil)iostream)netutil)	TCPServer)Configurable)	UnionAnyDictCallableListTypeTupleOptional	Awaitable)Setc                   @   sL  e Zd ZdZdededdfddZ												d(d	eeje	ej
gdf f d
ededeeeeef ejf  dee dedee dee dee dee dee dee deee  ddfddZedee fddZedee fddZd)ddZdejdeddfd d!Zd"ed#ej dej!fd$d%Z"d"eddfd&d'Z#dS )*
HTTPServera  A non-blocking, single-threaded HTTP server.

    A server is defined by a subclass of `.HTTPServerConnectionDelegate`,
    or, for backwards compatibility, a callback that takes an
    `.HTTPServerRequest` as an argument. The delegate is usually a
    `tornado.web.Application`.

    `HTTPServer` supports keep-alive connections by default
    (automatically for HTTP/1.1, or for HTTP/1.0 when the client
    requests ``Connection: keep-alive``).

    If ``xheaders`` is ``True``, we support the
    ``X-Real-Ip``/``X-Forwarded-For`` and
    ``X-Scheme``/``X-Forwarded-Proto`` headers, which override the
    remote IP and URI scheme/protocol for all requests.  These headers
    are useful when running Tornado behind a reverse proxy or load
    balancer.  The ``protocol`` argument can also be set to ``https``
    if Tornado is run behind an SSL-decoding proxy that does not set one of
    the supported ``xheaders``.

    By default, when parsing the ``X-Forwarded-For`` header, Tornado will
    select the last (i.e., the closest) address on the list of hosts as the
    remote host IP address.  To select the next server in the chain, a list of
    trusted downstream hosts may be passed as the ``trusted_downstream``
    argument.  These hosts will be skipped when parsing the ``X-Forwarded-For``
    header.

    To make this server serve SSL traffic, send the ``ssl_options`` keyword
    argument with an `ssl.SSLContext` object. For compatibility with older
    versions of Python ``ssl_options`` may also be a dictionary of keyword
    arguments for the `ssl.SSLContext.wrap_socket` method.::

       ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
       ssl_ctx.load_cert_chain(os.path.join(data_dir, "mydomain.crt"),
                               os.path.join(data_dir, "mydomain.key"))
       HTTPServer(application, ssl_options=ssl_ctx)

    `HTTPServer` initialization follows one of three patterns (the
    initialization methods are defined on `tornado.tcpserver.TCPServer`):

    1. `~tornado.tcpserver.TCPServer.listen`: single-process::

            async def main():
                server = HTTPServer()
                server.listen(8888)
                await asyncio.Event.wait()

            asyncio.run(main())

       In many cases, `tornado.web.Application.listen` can be used to avoid
       the need to explicitly create the `HTTPServer`.

       While this example does not create multiple processes on its own, when
       the ``reuse_port=True`` argument is passed to ``listen()`` you can run
       the program multiple times to create a multi-process service.

    2. `~tornado.tcpserver.TCPServer.add_sockets`: multi-process::

            sockets = bind_sockets(8888)
            tornado.process.fork_processes(0)
            async def post_fork_main():
                server = HTTPServer()
                server.add_sockets(sockets)
                await asyncio.Event().wait()
            asyncio.run(post_fork_main())

       The ``add_sockets`` interface is more complicated, but it can be used with
       `tornado.process.fork_processes` to run a multi-process service with all
       worker processes forked from a single parent.  ``add_sockets`` can also be
       used in single-process servers if you want to create your listening
       sockets in some way other than `~tornado.netutil.bind_sockets`.

       Note that when using this pattern, nothing that touches the event loop
       can be run before ``fork_processes``.

    3. `~tornado.tcpserver.TCPServer.bind`/`~tornado.tcpserver.TCPServer.start`:
       simple **deprecated** multi-process::

            server = HTTPServer()
            server.bind(8888)
            server.start(0)  # Forks multiple sub-processes
            IOLoop.current().start()

       This pattern is deprecated because it requires interfaces in the
       `asyncio` module that have been deprecated since Python 3.10. Support for
       creating multiple processes in the ``start`` method will be removed in a
       future version of Tornado.

    .. versionchanged:: 4.0
       Added ``decompress_request``, ``chunk_size``, ``max_header_size``,
       ``idle_connection_timeout``, ``body_timeout``, ``max_body_size``
       arguments.  Added support for `.HTTPServerConnectionDelegate`
       instances as ``request_callback``.

    .. versionchanged:: 4.1
       `.HTTPServerConnectionDelegate.start_request` is now called with
       two arguments ``(server_conn, request_conn)`` (in accordance with the
       documentation) instead of one ``(request_conn)``.

    .. versionchanged:: 4.2
       `HTTPServer` is now a subclass of `tornado.util.Configurable`.

    .. versionchanged:: 4.5
       Added the ``trusted_downstream`` argument.

    .. versionchanged:: 5.0
       The ``io_loop`` argument has been removed.
    argskwargsreturnNc                 O   s   d S N )selfr   r   r   r   I/var/www/html/lang_env/lib/python3.10/site-packages/tornado/httpserver.py__init__   s   zHTTPServer.__init__Frequest_callbackno_keep_alivexheadersssl_optionsprotocoldecompress_request
chunk_sizemax_header_sizeidle_connection_timeoutbody_timeoutmax_body_sizemax_buffer_sizetrusted_downstreamc              	   C   sR   || _ || _|| _t||||	pd||
|d| _tj| |||d t | _|| _	d S )Ni  )
decompressr#   r$   Zheader_timeoutr'   r&   r   )r    r(   Zread_chunk_size)
r   r   r!   r   conn_paramsr   r   set_connectionsr)   )r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r   r   r   
initialize   s(   	
zHTTPServer.initializec                 C      t S r   r   clsr   r   r   configurable_base      zHTTPServer.configurable_basec                 C   r/   r   r0   r1   r   r   r   configurable_default   r4   zHTTPServer.configurable_defaultc                    s2   | j rtt| j }| I dH  | j sdS dS )a&  Close all open connections and asynchronously wait for them to finish.

        This method is used in combination with `~.TCPServer.stop` to
        support clean shutdowns (especially for unittests). Typical
        usage would call ``stop()`` first to stop accepting new
        connections, then ``await close_all_connections()`` to wait for
        existing connections to finish.

        This method does not currently close open websocket connections.

        Note that this method is a coroutine and must be called with ``await``.

        N)r-   nextiterclose)r   connr   r   r   close_all_connections   s
   z HTTPServer.close_all_connectionsstreamaddressc                 C   s:   t ||| j| j}t|| j|}| j| ||  d S r   )_HTTPRequestContextr!   r)   r   r+   r-   addZstart_serving)r   r;   r<   contextr9   r   r   r   handle_stream   s   zHTTPServer.handle_streamserver_connrequest_connc                 C   s>   t | jtjr| j||}nt| j|}| jrt||}|S r   )
isinstancer   r   HTTPServerConnectionDelegatestart_request_CallableAdapterr   _ProxyAdapter)r   rA   rB   delegater   r   r   rE      s   
zHTTPServer.start_requestc                 C   s   | j tt| d S r   )r-   removetypingcastr   )r   rA   r   r   r   on_close   s   zHTTPServer.on_close)FFNNFNNNNNNNr   N)$__name__
__module____qualname____doc__r   r   r
   r   rD   r   HTTPServerRequestboolr   r   strssl
SSLContextintfloatr   r.   classmethodr   r	   r3   r5   r:   r   IOStreamr   r@   objectHTTPConnectionHTTPMessageDelegaterE   rL   r   r   r   r   r   .   s|    m	


,

r   c                   @   s   e Zd Zdeejgdf dejddfddZdeej	ej
f dejdeed  fd	d
Zdedeed  fddZdddZdddZdS )rF   r   NrB   r   c                 C   s"   || _ || _d | _d | _g | _d S r   )
connectionr   requestrH   _chunks)r   r   rB   r   r   r   r     s
   
z_CallableAdapter.__init__
start_lineheadersc                 C   s"   t j| jtt j||d| _d S )N)r^   ra   rb   )r   rR   r^   rJ   rK   RequestStartLiner_   r   ra   rb   r   r   r   headers_received  s   z!_CallableAdapter.headers_receivedchunkc                 C   s   | j | d S r   )r`   appendr   rf   r   r   r   data_received  s   z_CallableAdapter.data_receivedc                 C   s8   | j d usJ d| j| j _| j   | | j  d S )N    )r_   joinr`   bodyZ_parse_bodyr   r   r   r   r   finish   s   
z_CallableAdapter.finishc                 C   s   | ` d S r   )r`   rm   r   r   r   on_connection_close&  s   z$_CallableAdapter.on_connection_closerM   )rN   rO   rP   r   r   rR   r\   r   r
   rc   ResponseStartLineHTTPHeadersr   r   re   bytesri   rn   ro   r   r   r   r   rF     s$    



rF   c                   @   sh   e Zd Z	ddejdedee deee  ddf
ddZ	defd	d
Z
dejddfddZdddZdS )r=   Nr;   r<   r!   r)   r   c                 C   s   || _ |jd ur|jj| _nd | _| jtjtjfv r$|d ur$|d | _nd| _|r-|| _nt|t	j
r7d| _nd| _| j| _| j| _t|pFg | _d S )Nr   z0.0.0.0httpshttp)r<   socketfamilyaddress_familyAF_INETAF_INET6	remote_ipr!   rC   r   ZSSLIOStream_orig_remote_ip_orig_protocolr,   r)   )r   r;   r<   r!   r)   r   r   r   r   +  s    
z_HTTPRequestContext.__init__c                 C   s8   | j tjtjfv r| jS t| jtrt| jS t	| jS r   )
rw   ru   rx   ry   rz   rC   r<   rr   r   rT   rm   r   r   r   __str__M  s
   

z_HTTPRequestContext.__str__rb   c                 C   s   | d| j}dd t|dD D ]	}|| jvr nq| d|}t|r+|| _| d| d| j}|rA|dd  }|d	v rJ|| _d
S d
S )z2Rewrite the ``remote_ip`` and ``protocol`` fields.zX-Forwarded-Forc                 s   s    | ]}|  V  qd S r   )strip).0candr   r   r   	<genexpr>]  s    z6_HTTPRequestContext._apply_xheaders.<locals>.<genexpr>,z	X-Real-IpzX-SchemezX-Forwarded-Proto)rt   rs   N)	getrz   reversedsplitr)   r   Zis_valid_ipr!   r~   )r   rb   ipZproto_headerr   r   r   _apply_xheadersX  s    


z#_HTTPRequestContext._apply_xheadersc                 C   s   | j | _| j| _dS )zUndo changes from `_apply_xheaders`.

        Xheaders are per-request so they should not leak to the next
        request on the same connection.
        N)r{   rz   r|   r!   rm   r   r   r   _unapply_xheadersn  s   z%_HTTPRequestContext._unapply_xheadersr   rM   )rN   rO   rP   r   rZ   r   r   rT   r   r   r}   r   rq   r   r   r   r   r   r   r=   *  s     

"r=   c                   @   s   e Zd ZdejdejddfddZdeejej	f dej
deed  fd	d
Zdedeed  fddZdddZdddZdddZdS )rG   rH   rB   r   Nc                 C   s   || _ || _d S r   )r^   rH   )r   rH   rB   r   r   r   r   y  s   
z_ProxyAdapter.__init__ra   rb   c                 C   s   | j j| | j||S r   )r^   r?   r   rH   re   rd   r   r   r   re     s   z_ProxyAdapter.headers_receivedrf   c                 C   s   | j |S r   )rH   ri   rh   r   r   r   ri     s   z_ProxyAdapter.data_receivedc                 C      | j   |   d S r   )rH   rn   _cleanuprm   r   r   r   rn        
z_ProxyAdapter.finishc                 C   r   r   )rH   ro   r   rm   r   r   r   ro     r   z!_ProxyAdapter.on_connection_closec                 C   s   | j j  d S r   )r^   r?   r   rm   r   r   r   r     s   z_ProxyAdapter._cleanuprM   )rN   rO   rP   r   r]   r\   r   r
   rc   rp   rq   r   r   re   rr   ri   rn   ro   r   r   r   r   r   rG   x  s&    





rG   )%rQ   ru   rU   Ztornado.escaper   Ztornado.http1connectionr   r   tornador   r   r   Ztornado.tcpserverr   Ztornado.utilr	   rJ   r
   r   r   r   r   r   r   r   r   TYPE_CHECKINGr   rD   r   r]   rF   r[   r=   rG   rR   ZHTTPRequestr   r   r   r   <module>   s(   , W&N
"