
[c           @` s(  d  Z  d d l m Z m Z m 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 m Z d e e e j f d     YZ d e j f d     YZ d e f d     YZ d e j f d     YZ e j Z d S(   s  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.
i    (   t   absolute_importt   divisiont   print_functionN(   t
   native_str(   t   HTTP1ServerConnectiont   HTTP1ConnectionParameters(   t   gen(   t   httputil(   t   iostream(   t   netutil(   t	   TCPServer(   t   Configurablet
   HTTPServerc           B` s   e  Z d  Z d   Z e e d	 d	 e d	 d	 d	 d	 d	 d	 d	 d  Z e d    Z e d    Z	 e
 j d    Z d   Z d   Z d   Z RS(
   s  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.
    c         O` s   d  S(   N(    (   t   selft   argst   kwargs(    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   __init__   s    c         C` s   | |  _  | |  _ | |  _ t d | d | d | d |	 p< d d | d |
 d |  |  _ t j |  d	 | d
 | d | t   |  _ | |  _	 d  S(   Nt
   decompresst
   chunk_sizet   max_header_sizet   header_timeouti  t   max_body_sizet   body_timeoutt   no_keep_alivet   ssl_optionst   max_buffer_sizet   read_chunk_size(
   t   request_callbackt   xheaderst   protocolR   t   conn_paramsR
   R   t   sett   _connectionst   trusted_downstream(   R   R   R   R   R   R   t   decompress_requestR   R   t   idle_connection_timeoutR   R   R   R!   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt
   initialize   s     			c         C` s   t  S(   N(   R   (   t   cls(    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   configurable_base   s    c         C` s   t  S(   N(   R   (   R%   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   configurable_default   s    c         c` s4   x- |  j  r/ t t |  j    } | j   Vq Wd  S(   N(   R    t   nextt   itert   close(   R   t   conn(    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   close_all_connections   s    c         C` sQ   t  | | |  j |  j  } t | |  j |  } |  j j |  | j |   d  S(   N(   t   _HTTPRequestContextR   R!   R   R   R    t   addt   start_serving(   R   t   streamt   addresst   contextR+   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   handle_stream   s    	c         C` s^   t  |  j t j  r- |  j j | |  } n t |  j |  } |  j rZ t | |  } n  | S(   N(   t
   isinstanceR   R   t   HTTPServerConnectionDelegatet   start_requestt   _CallableAdapterR   t   _ProxyAdapter(   R   t   server_connt   request_connt   delegate(    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyR6      s    	c         C` s   |  j  j |  d  S(   N(   R    t   remove(   R   R9   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   on_close   s    N(   t   __name__t
   __module__t   __doc__R   t   Falset   NoneR$   t   classmethodR&   R'   R   t	   coroutineR,   R3   R6   R=   (    (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyR   *   s   a					R7   c           B` s5   e  Z d    Z d   Z d   Z d   Z d   Z RS(   c         C` s1   | |  _  | |  _ d  |  _ d  |  _ g  |  _ d  S(   N(   t
   connectionR   RB   t   requestR;   t   _chunks(   R   R   R:   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyR      s
    				c         C` s(   t  j d |  j d | d |  |  _ d  S(   NRE   t
   start_linet   headers(   R   t   HTTPServerRequestRE   RF   (   R   RH   RI   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   headers_received   s    	c         C` s   |  j  j |  d  S(   N(   RG   t   append(   R   t   chunk(    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   data_received   s    c         C` s9   d j  |  j  |  j _ |  j j   |  j |  j  d  S(   Nt    (   t   joinRG   RF   t   bodyt   _parse_bodyR   (   R   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   finish   s    c         C` s   d  |  _ d  S(   N(   RB   RG   (   R   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   on_connection_close   s    (   R>   R?   R   RK   RN   RS   RT   (    (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyR7      s
   				R-   c           B` s/   e  Z d d   Z d   Z d   Z d   Z RS(   c         C` s   | |  _  | j d  k	 r* | j j |  _ n	 d  |  _ |  j t j t j f k rj | d  k	 rj | d |  _ n	 d |  _ | r | |  _ n' t	 | t
 j  r d |  _ n	 d |  _ |  j |  _ |  j |  _ t | p g   |  _ d  S(   Ni    s   0.0.0.0t   httpst   http(   R1   t   socketRB   t   familyt   address_familyt   AF_INETt   AF_INET6t	   remote_ipR   R4   R   t   SSLIOStreamt   _orig_remote_ipt   _orig_protocolR   R!   (   R   R0   R1   R   R!   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyR      s     				c         C` sR   |  j  t j t j f k r" |  j St |  j t  rA t |  j  St	 |  j  Sd  S(   N(
   RY   RW   RZ   R[   R\   R4   R1   t   bytesR   t   str(   R   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   __str__  s
    c         C` s   | j  d |  j  } x: d   t | j d   D D] } | |  j k r5 Pq5 q5 W| j  d |  } t j |  r | |  _ n  | j  d | j  d |  j   } | r | j d  d j   } n  | d k r | |  _ n  d
 S(   s2   Rewrite the ``remote_ip`` and ``protocol`` fields.s   X-Forwarded-Forc         s` s   |  ] } | j    Vq d  S(   N(   t   strip(   t   .0t   cand(    (    s1   lib/python2.7/site-packages/tornado/httpserver.pys	   <genexpr>  s    t   ,s	   X-Real-Ips   X-Schemes   X-Forwarded-ProtoiRV   RU   N(   RV   RU   (	   t   getR\   t   reversedt   splitR!   R	   t   is_valid_ipR   Rc   (   R   RI   t   ipt   proto_header(    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   _apply_xheaders  s    &c         C` s   |  j  |  _ |  j |  _ d S(   s   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   (   R   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   _unapply_xheaders(  s    N(   R>   R?   RB   R   Rb   Rm   Rn   (    (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyR-      s   		R8   c           B` s>   e  Z d    Z d   Z d   Z d   Z d   Z d   Z RS(   c         C` s   | |  _  | |  _ d  S(   N(   RE   R;   (   R   R;   R:   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyR   3  s    	c         C` s&   |  j  j j |  |  j j | |  S(   N(   RE   R2   Rm   R;   RK   (   R   RH   RI   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyRK   7  s    c         C` s   |  j  j |  S(   N(   R;   RN   (   R   RM   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyRN   ;  s    c         C` s   |  j  j   |  j   d  S(   N(   R;   RS   t   _cleanup(   R   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyRS   >  s    c         C` s   |  j  j   |  j   d  S(   N(   R;   RT   Ro   (   R   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyRT   B  s    c         C` s   |  j  j j   d  S(   N(   RE   R2   Rn   (   R   (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyRo   F  s    (   R>   R?   R   RK   RN   RS   RT   Ro   (    (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyR8   2  s   					(   R@   t
   __future__R    R   R   RW   t   tornado.escapeR   t   tornado.http1connectionR   R   t   tornadoR   R   R   R	   t   tornado.tcpserverR
   t   tornado.utilR   R5   R   t   HTTPMessageDelegateR7   t   objectR-   R8   RJ   t   HTTPRequest(    (    (    s1   lib/python2.7/site-packages/tornado/httpserver.pyt   <module>   s    	F