o
    Qœ_Ã<  ã                   @   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.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`: simple single-process::

            server = HTTPServer(app)
            server.listen(8888)
            IOLoop.current().start()

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

    2. `~tornado.tcpserver.TCPServer.bind`/`~tornado.tcpserver.TCPServer.start`:
       simple multi-process::

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

       When using this interface, an `.IOLoop` must *not* be passed
       to the `HTTPServer` constructor.  `~.TCPServer.start` will always start
       the server on the default singleton `.IOLoop`.

    3. `~tornado.tcpserver.TCPServer.add_sockets`: advanced multi-process::

            sockets = tornado.netutil.bind_sockets(8888)
            tornado.process.fork_processes(0)
            server = HTTPServer(app)
            server.add_sockets(sockets)
            IOLoop.current().start()

       The `~.TCPServer.add_sockets` interface is more complicated,
       but it can be used with `tornado.process.fork_processes` to
       give you more flexibility in when the fork happens.
       `~.TCPServer.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`.

    .. 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   ú4/usr/lib/python3/dist-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$   Úheader_timeoutr'   r&   r   )r    r(   Ú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   r1   r   r2   r3   r   r   r   Úconfigurable_defaultÈ   r6   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/   ÚaddÚstart_serving)r   r=   r>   Úcontextr;   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   rD   rE   Údelegater   r   r   rH   ç   s   
zHTTPServer.start_requestc                 C   s   | j  t t|¡¡ d S r   )r/   ÚremoveÚtypingÚcastr   )r   rD   r   r   r   Úon_closeô   s   zHTTPServer.on_close)FFNNFNNNNNNN©r   N)$Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r
   r   rG   r   ÚHTTPServerRequestÚboolr   r   ÚstrÚsslÚ
SSLContextÚintÚfloatr   r0   Úclassmethodr   r	   r5   r7   r<   r   ÚIOStreamr   rC   ÚobjectÚHTTPConnectionÚHTTPMessageDelegaterH   rO   r   r   r   r   r   .   s|    aïÿÿþúùø	÷
öõôóòñð
ï
î,
ÿÿ
þ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 )rI   r   NrE   r   c                 C   s"   || _ || _d | _d | _g | _d S r   )Ú
connectionr   ÚrequestrK   Ú_chunks)r   r   rE   r   r   r   r   ù   s
   
z_CallableAdapter.__init__Ú
start_lineÚheadersc                 C   s"   t j| jt t j|¡|d�| _d S )N)ra   rd   re   )r   rU   ra   rM   rN   ÚRequestStartLinerb   ©r   rd   re   r   r   r   Úheaders_received  s   ýz!_CallableAdapter.headers_receivedÚchunkc                 C   s   | j  |¡ d S r   )rc   Úappend©r   ri   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ó    )rb   Újoinrc   ÚbodyÚ_parse_bodyr   ©r   r   r   r   Úfinish  s   
z_CallableAdapter.finishc                 C   s   | ` d S r   )rc   rq   r   r   r   Úon_connection_close  s   z$_CallableAdapter.on_connection_closerP   )rQ   rR   rS   r   r   rU   r_   r   r
   rf   ÚResponseStartLineÚHTTPHeadersr   r   rh   Úbytesrl   rr   rs   r   r   r   r   rI   ø   s$    þý
üþý

ü
rI   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!   rF   r   Ú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   )
r{   ry   r|   r}   r~   rF   r>   rv   r   rW   rq   r   r   r   Ú__str__A  s
   

z_HTTPRequestContext.__str__re   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>Q  s   € z6_HTTPRequestContext._apply_xheaders.<locals>.<genexpr>ú,z	X-Real-IpzX-SchemezX-Forwarded-Protoéÿÿÿÿ)rx   rw   N)	Úgetr~   ÚreversedÚsplitr)   r   Úis_valid_ipr!   rƒ   )r   re   ÚipÚproto_headerr   r   r   Ú_apply_xheadersL  s    
ÿ
ÿ
ÿz#_HTTPRequestContext._apply_xheadersc                 C   s   | j | _| j| _dS )z›Undo changes from `_apply_xheaders`.

        Xheaders are per-request so they should not leak to the next
        request on the same connection.
        N)r€   r~   r�   r!   rq   r   r   r   Ú_unapply_xheadersb  s   z%_HTTPRequestContext._unapply_xheadersr   rP   )rQ   rR   rS   r   r]   r   r   rW   r   r   r‚   r   ru   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 )rJ   rK   rE   r   Nc                 C   s   || _ || _d S r   )ra   rK   )r   rK   rE   r   r   r   r   m  s   
z_ProxyAdapter.__init__rd   re   c                 C   s   | j j |¡ | j ||¡S r   )ra   rB   r�   rK   rh   rg   r   r   r   rh   u  s   z_ProxyAdapter.headers_receivedri   c                 C   s   | j  |¡S r   )rK   rl   rk   r   r   r   rl     s   z_ProxyAdapter.data_receivedc                 C   ó   | j  ¡  |  ¡  d S r   )rK   rr   Ú_cleanuprq   r   r   r   rr   ‚  ó   
z_ProxyAdapter.finishc                 C   r‘   r   )rK   rs   r’   rq   r   r   r   rs   †  r“   z!_ProxyAdapter.on_connection_closec                 C   s   | j j ¡  d S r   )ra   rB   r�   rq   r   r   r   r’   Š  s   z_ProxyAdapter._cleanuprP   )rQ   rR   rS   r   r`   r_   r   r
   rf   rt   ru   r   r   rh   rv   rl   rr   rs   r’   r   r   r   r   rJ   l  s&    þý
üþý

ü


rJ   )%rT   ry   rX   Útornado.escaper   Útornado.http1connectionr   r   Útornador   r   r   Útornado.tcpserverr   Útornado.utilr	   rM   r
   r   r   r   r   r   r   r   r   ÚTYPE_CHECKINGr   rG   r   r`   rI   r^   r?   rJ   rU   ÚHTTPRequestr   r   r   r   Ú<module>   s(   , K&N
"