B
    h]<                 @   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rd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               @   s   e Zd ZdZeeddddZdeeje	ej
gdf f eeeeeef ejf eeeeeeeeee dddd	Zeee d
ddZeee d
ddZdd
ddZejeddddZeejej dddZ!edd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.
    N)argskwargsreturnc             O   s   d S )N )selfr   r   r   r   OC:\Users\sanjo\AppData\Local\Qlobot\Launcher\ext_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_downstreamr   c          	   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.initialize)r   c             C   s   t S )N)r   )clsr   r   r   configurable_base   s    zHTTPServer.configurable_basec             C   s   t S )N)r   )r.   r   r   r   configurable_default   s    zHTTPServer.configurable_defaultc                s,   x&| j r&tt| j }| I dH  qW 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 caled with ``await``.

        N)r,   nextiterclose)r   connr   r   r   close_all_connections   s    z HTTPServer.close_all_connections)streamaddressr   c             C   s:   t ||| j| j}t|| j|}| j| ||  d S )N)_HTTPRequestContextr    r(   r   r*   r,   addZstart_serving)r   r6   r7   contextr4   r   r   r   handle_stream   s
    zHTTPServer.handle_stream)server_connrequest_connr   c             C   s>   t | jtjr| j||}nt| j|}| jr:t||}|S )N)
isinstancer   r   HTTPServerConnectionDelegatestart_request_CallableAdapterr   _ProxyAdapter)r   r<   r=   delegater   r   r   r@      s    
zHTTPServer.start_request)r<   r   c             C   s   | j tt| d S )N)r,   removetypingcastr   )r   r<   r   r   r   on_close   s    zHTTPServer.on_close)FFNNFNNNNNNN)#__name__
__module____qualname____doc__r   r   r
   r   r?   r   HTTPServerRequestboolr   strssl
SSLContextintfloatr   r-   classmethodr   r	   r/   r0   r5   r   IOStreamr   r;   objectHTTPConnectionHTTPMessageDelegater@   rG   r   r   r   r   r   .   s0   `           H	r   c               @   s   e Zd Zeejgdf ejddddZeej	ej
f ejeed  dddZeeed  dd	d
ZddddZddddZdS )rA   N)r   r=   r   c             C   s"   || _ || _d | _d | _g | _d S )N)
connectionr   requestrC   _chunks)r   r   r=   r   r   r   r      s
    z_CallableAdapter.__init__)
start_lineheadersr   c             C   s"   t j| jtt j||d| _d S )N)rX   r[   r\   )r   rL   rX   rE   rF   RequestStartLinerY   )r   r[   r\   r   r   r   headers_received  s
    
z!_CallableAdapter.headers_received)chunkr   c             C   s   | j | d S )N)rZ   append)r   r_   r   r   r   data_received  s    z_CallableAdapter.data_received)r   c             C   s8   | j d k	std| j| j _| j   | | j  d S )N    )rY   AssertionErrorjoinrZ   bodyZ_parse_bodyr   )r   r   r   r   finish  s    
z_CallableAdapter.finishc             C   s   | ` d S )N)rZ   )r   r   r   r   on_connection_close  s    z$_CallableAdapter.on_connection_close)rH   rI   rJ   r   r   rL   rV   r   r
   r]   ResponseStartLineHTTPHeadersr   r   r^   bytesra   rf   rg   r   r   r   r   rA      s   	rA   c               @   s\   e Zd Zdejeee ee ddddZ	edddZ
ejddd	d
ZddddZdS )r8   N)r6   r7   r    r(   r   c             C   s   || _ |jd k	r|jj| _nd | _| jtjtjfkrH|d k	rH|d | _nd| _|rZ|| _nt|t	j
rnd| _nd| _| j| _| j| _t|pg | _d S )Nr   z0.0.0.0httpshttp)r7   socketfamilyaddress_familyAF_INETAF_INET6	remote_ipr    r>   r   ZSSLIOStream_orig_remote_ip_orig_protocolr+   r(   )r   r6   r7   r    r(   r   r   r   r     s     
z_HTTPRequestContext.__init__)r   c             C   s<   | j tjtjfkr| jS t| jtr.t| jS t	| jS d S )N)
ro   rm   rp   rq   rr   r>   r7   rj   r   rN   )r   r   r   r   __str__A  s
    
z_HTTPRequestContext.__str__)r\   r   c             C   s   | d| j}x,dd t|dD D ]}|| jkr(P q(W | d|}t|rX|| _| d| d| j}|r|dd  }|d	kr|| _d
S )z2Rewrite the ``remote_ip`` and ``protocol`` fields.zX-Forwarded-Forc             s   s   | ]}|  V  qd S )N)strip).0Zcandr   r   r   	<genexpr>Q  s    z6_HTTPRequestContext._apply_xheaders.<locals>.<genexpr>,z	X-Real-IpzX-SchemezX-Forwarded-Proto)rl   rk   N)	getrr   reversedsplitr(   r   Zis_valid_ipr    rv   )r   r\   ipZproto_headerr   r   r   _apply_xheadersL  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)rs   rr   rt   r    )r   r   r   r   _unapply_xheadersb  s    z%_HTTPRequestContext._unapply_xheaders)N)rH   rI   rJ   r   rT   r   r   rN   r   r   ru   r   ri   r   r   r   r   r   r   r8     s
   r8   c               @   s   e Zd ZejejddddZeejej	f ej
eed  dddZeeed  dd	d
ZddddZddddZddddZdS )rB   N)rC   r=   r   c             C   s   || _ || _d S )N)rX   rC   )r   rC   r=   r   r   r   r   m  s    z_ProxyAdapter.__init__)r[   r\   r   c             C   s   | j j| | j||S )N)rX   r:   r   rC   r^   )r   r[   r\   r   r   r   r^   u  s    z_ProxyAdapter.headers_received)r_   r   c             C   s   | j |S )N)rC   ra   )r   r_   r   r   r   ra     s    z_ProxyAdapter.data_received)r   c             C   s   | j   |   d S )N)rC   rf   _cleanup)r   r   r   r   rf     s    
z_ProxyAdapter.finishc             C   s   | j   |   d S )N)rC   rg   r   )r   r   r   r   rg     s    
z!_ProxyAdapter.on_connection_closec             C   s   | j j  d S )N)rX   r:   r   )r   r   r   r   r     s    z_ProxyAdapter._cleanup)rH   rI   rJ   r   rW   rV   r   r
   r]   rh   ri   r   r   r^   rj   ra   rf   rg   r   r   r   r   r   rB   l  s   rB   )%rK   rm   rO   Ztornado.escaper   Ztornado.http1connectionr   r   Ztornador   r   r   Ztornado.tcpserverr   Ztornado.utilr	   rE   r
   r   r   r   r   r   r   r   r   TYPE_CHECKINGr   r?   r   rW   rA   rU   r8   rB   rL   ZHTTPRequestr   r   r   r   <module>   s&   , K&N"