σ
¨[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 Z d d l	 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 d l m Z m Z e rδ d d l j Z n d d l Z e e k rd   Z d   Z n d   Z d   Z d e j f d     YZ d   Z d e j  f d     YZ! d e" f d     YZ# d e" f d     YZ$ d e" f d     YZ% e j& Z' d S(   sͺ  WSGI support for the Tornado web framework.

WSGI is the Python standard for web servers, and allows for interoperability
between Tornado and other Python web frameworks and servers.  This module
provides WSGI support in two ways:

* `WSGIAdapter` converts a `tornado.web.Application` to the WSGI application
  interface.  This is useful for running a Tornado app on another
  HTTP server, such as Google App Engine.  See the `WSGIAdapter` class
  documentation for limitations that apply.
* `WSGIContainer` lets you run other WSGI applications and frameworks on the
  Tornado HTTP server.  For example, with this class you can mix Django
  and Tornado handlers in a single server.
i    (   t   absolute_importt   divisiont   print_functionN(   t   BytesIO(   t   Future(   t   escape(   t   httputil(   t
   access_log(   t   web(   t
   native_str(   t   unicode_typet   PY3c         C` s"   t  |  t  s t  |  j d  S(   Nt   latin1(   t
   isinstancet   bytest   AssertionErrort   decode(   t   s(    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyt   to_wsgi_str9   s    c         C` s"   t  |  t  s t  |  j d  S(   NR   (   R   t   strR   t   encode(   R   (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyt   from_wsgi_str=   s    c         C` s   t  |  t  s t  |  S(   N(   R   R   R   (   R   (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyR   A   s    c         C` s   t  |  t  s t  |  S(   N(   R   R   R   (   R   (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyR   E   s    t   WSGIApplicationc           B` s   e  Z d  Z d   Z RS(   sΚ   A WSGI equivalent of `tornado.web.Application`.

    .. deprecated:: 4.0

       Use a regular `.Application` and wrap it in `WSGIAdapter` instead.
       This class will be removed in Tornado 6.0.
    c         C` s   t  |   | |  S(   N(   t   WSGIAdapter(   t   selft   environt   start_response(    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyt   __call__R   s    (   t   __name__t
   __module__t   __doc__R   (    (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyR   J   s   c          C` s   t    }  |  j d   |  S(   N(   R   t
   set_resultt   None(   t   f(    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyt   _dummy_futureX   s    	t   _WSGIConnectionc           B` s>   e  Z d    Z d   Z d d d  Z d d  Z d   Z RS(   c         C` sC   | |  _  | |  _ | |  _ g  |  _ t |  _ d  |  _ d  |  _ d  S(   N(	   t   methodR   t   contextt   _write_buffert   Falset	   _finishedR    t   _expected_content_remainingt   _error(   R   R$   R   R%   (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyt   __init___   s    						c         C` s   d  S(   N(    (   R   t   callback(    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyt   set_close_callbackh   s    c         C` sΣ   |  j  d k r d |  _ n+ d | k r= t | d  |  _ n	 d  |  _ |  j d | j | j f g  | j   D]$ \ } } t |  t |  f ^ ql  | d  k	 rΆ |  j	 | |  n | d  k	 rΜ |   n  t
   S(   Nt   HEADi    s   Content-Lengths   %s %s(   R$   R)   t   intR    R   t   codet   reasont   get_allR	   t   writeR"   (   R   t
   start_linet   headerst   chunkR,   t   kt   v(    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyt   write_headersm   s    	8
c         C` s   |  j  d  k	 rT |  j  t |  8_  |  j  d k  rT t j d  |  _ |  j  qT n  |  j j |  | d  k	 rz |   n  t   S(   Ni    s,   Tried to write more data than Content-Length(	   R)   R    t   lenR   t   HTTPOutputErrorR*   R&   t   appendR"   (   R   R6   R,   (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyR3   }   s    
c         C` sP   |  j  d  k	 rC |  j  d k rC t j d |  j   |  _ |  j  n  t |  _ d  S(   Ni    s0   Tried to write %d bytes less than Content-Length(   R)   R    R   R;   R*   t   TrueR(   (   R   (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyt   finish   s    N(   R   R   R+   R-   R    R9   R3   R>   (    (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyR#   ^   s
   			t   _WSGIRequestContextc           B` s   e  Z d    Z d   Z RS(   c         C` s   | |  _  | |  _ d  S(   N(   t	   remote_ipt   protocol(   R   R@   RA   (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyR+      s    	c         C` s   |  j  S(   N(   R@   (   R   (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyt   __str__   s    (   R   R   R+   RB   (    (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyR?      s   	R   c           B` s    e  Z d  Z d   Z d   Z RS(   s  Converts a `tornado.web.Application` instance into a WSGI application.

    Example usage::

        import tornado.web
        import tornado.wsgi
        import wsgiref.simple_server

        class MainHandler(tornado.web.RequestHandler):
            def get(self):
                self.write("Hello, world")

        if __name__ == "__main__":
            application = tornado.web.Application([
                (r"/", MainHandler),
            ])
            wsgi_app = tornado.wsgi.WSGIAdapter(application)
            server = wsgiref.simple_server.make_server('', 8888, wsgi_app)
            server.serve_forever()

    See the `appengine demo
    <https://github.com/tornadoweb/tornado/tree/stable/demos/appengine>`_
    for an example of using this module to run a Tornado app on Google
    App Engine.

    In WSGI mode asynchronous methods are not supported.  This means
    that it is not possible to use `.AsyncHTTPClient`, or the
    `tornado.auth` or `tornado.websocket` modules.

    In multithreaded WSGI servers on Python 3, it may be necessary to
    permit `asyncio` to create event loops on any thread. Run the
    following at startup (typically import time for WSGI
    applications)::

        import asyncio
        from tornado.platform.asyncio import AnyThreadEventLoopPolicy
        asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())

    .. versionadded:: 4.0

    .. deprecated:: 5.1

       This class is deprecated and will be removed in Tornado 6.0.
       Use Tornado's `.HTTPServer` instead of a WSGI container.
    c         ` sA   t  j d t  t   t  r4   f d   |  _ n	   |  _ d  S(   Ns;   WSGIAdapter is deprecated, use Tornado's HTTPServer insteadc         ` s   t  j j   |   S(   N(   R   t   ApplicationR   (   t   request(   t   application(    s+   lib/python2.7/site-packages/tornado/wsgi.pyt   <lambda>Ξ   s   	(   t   warningst   warnt   DeprecationWarningR   R   RE   (   R   RE   (    (   RE   s+   lib/python2.7/site-packages/tornado/wsgi.pyR+   Κ   s
    	c         C` s  | d } t  j t | j d d    } | t  j t | j d d    7} | j d  rt | d | d 7} n  t j   } | j d  r  | d | d <n  | j d	  rΐ | d	 | d
 <n  x> | D]6 } | j d  rΗ | | | | d j d d  <qΗ qΗ W| j d
  r0| d j t	 | d
   } n d } | d } | j d d  }	 | j d  rn| d }
 n
 | d }
 t
 | | t |	 |   } t j | | d d | d | d |
 d | } | j   |  j |  | j rμ| j  n  | j st d   n  | j S(   Nt   REQUEST_METHODt   SCRIPT_NAMEt    t	   PATH_INFOt   QUERY_STRINGt   ?t   CONTENT_TYPEs   Content-Typet   CONTENT_LENGTHs   Content-Lengtht   HTTP_i   t   _t   -s
   wsgi.inputs   wsgi.url_schemet   REMOTE_ADDRt	   HTTP_HOSTt   SERVER_NAMEs   HTTP/1.1R5   t   bodyt   hostt
   connections$   request did not finish synchronously(   t   urllib_parset   quoteR   t   getR   t   HTTPHeaderst
   startswitht   replacet   readR/   R#   R?   t   HTTPServerRequestt   _parse_bodyRE   R*   R(   t	   ExceptionR&   (   R   R   R   R$   t   uriR5   t   keyRX   RA   R@   RY   RZ   RD   (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyR   Σ   sD    
!%%


	
		(   R   R   R   R+   R   (    (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyR      s   -		t   WSGIContainerc           B` s8   e  Z d  Z d   Z d   Z e d    Z d   Z RS(   s’  Makes a WSGI-compatible function runnable on Tornado's HTTP server.

    .. warning::

       WSGI is a *synchronous* interface, while Tornado's concurrency model
       is based on single-threaded asynchronous execution.  This means that
       running a WSGI app with Tornado's `WSGIContainer` is *less scalable*
       than running the same app in a multi-threaded WSGI server like
       ``gunicorn`` or ``uwsgi``.  Use `WSGIContainer` only when there are
       benefits to combining Tornado and WSGI in the same process that
       outweigh the reduced scalability.

    Wrap a WSGI function in a `WSGIContainer` and pass it to `.HTTPServer` to
    run it. For example::

        def simple_app(environ, start_response):
            status = "200 OK"
            response_headers = [("Content-type", "text/plain")]
            start_response(status, response_headers)
            return ["Hello world!\n"]

        container = tornado.wsgi.WSGIContainer(simple_app)
        http_server = tornado.httpserver.HTTPServer(container)
        http_server.listen(8888)
        tornado.ioloop.IOLoop.current().start()

    This class is intended to let other frameworks (Django, web.py, etc)
    run on the Tornado HTTP server and I/O loop.

    The `tornado.web.FallbackHandler` class is often useful for mixing
    Tornado and WSGI apps in the same server.  See
    https://github.com/bdarnell/django-tornado-demo for a complete example.
    c         C` s   | |  _  d  S(   N(   t   wsgi_application(   R   Rh   (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyR+     s    c         ` sμ  i    g   d     f d  } |  j t j |  |  } z   j |  d j   } Wd  t | d  r{ | j   n  X  s t d   n    d j	 d d  \ } } t
 |  }   d } t d	   | D  } t j |  } | d
 k rAd | k r"| j d t t |   f  n  d | k rA| j d  qAn  d | k rj| j d d t j f  n  t j d | |  }	 t j   }
 x$ | D] \ } } |
 j | |  qW| j j |	 |
 d | | j j   |  j | |  d  S(   Nc         ` s   |    d <|   d < j  S(   Nt   statusR5   (   R<   (   Ri   t   response_headerst   exc_info(   t   datat   response(    s+   lib/python2.7/site-packages/tornado/wsgi.pyR   #  s    

RL   t   closes$   WSGI app did not call start_responseRi   t    i   R5   c         s` s!   |  ] \ } } | j    Vq d  S(   N(   t   lower(   t   .0R7   R8   (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pys	   <genexpr>5  s    i0  s   content-lengths   Content-Lengths   content-types   Content-Types   text/html; charset=UTF-8t   servert   Servers   TornadoServer/%ss   HTTP/1.1R6   (   s   Content-Types   text/html; charset=UTF-8(   R    Rh   Rg   R   t   extendt   joint   hasattrRn   Rd   t   splitR/   t   setR   t   utf8R<   R   R:   t   tornadot   versionR   t   ResponseStartLineR^   t   addRZ   R9   R>   t   _log(   R   RD   R   t   app_responseRX   t   status_codeR1   R5   t
   header_setR4   t
   header_objRf   t   value(    (   Rl   Rm   s+   lib/python2.7/site-packages/tornado/wsgi.pyR     s>    
"c         C` s°  |  j  j d  } t |  d k rA | d } t | d  } n$ |  j  } |  j d k r_ d n d } i |  j d 6d	 d
 6t t j |  j	 d d! d t  d 6|  j d 6|  j d 6| d 6t |  d 6|  j d 6d" d 6|  j d 6t t j |  j   d 6t j d 6t d 6t d 6t d 6} d |  j k rD|  j j d  | d <n  d |  j k rl|  j j d  | d <n  x= |  j j   D], \ } } | | d | j d d   j   <q|W| S(#   sO   Converts a `tornado.httputil.HTTPServerRequest` to a WSGI environment.
        t   :i   i    i   t   httpsi»  iP   RJ   RL   RK   t   encodingt   plusRM   RN   RU   RW   t   SERVER_PORTt   SERVER_PROTOCOLs   wsgi.versions   wsgi.url_schemes
   wsgi.inputs   wsgi.errorss   wsgi.multithreads   wsgi.multiprocesss   wsgi.run_onces   Content-TypeRP   s   Content-LengthRQ   RR   RT   RS   N(   i   i    (   RY   Rw   R:   R/   RA   R$   R   R   t   url_unescapet   pathR    R'   t   queryR@   R   R{   R   Ry   RX   t   syst   stderrR=   R5   t   popt   itemsR`   t   upper(   RD   t   hostportRY   t   portR   Rf   R   (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyR   G  s<    
	
	





$c         C` s   | d k  r t  j } n! | d k  r0 t  j } n	 t  j } d | j   } | j d | j d | j d } | d | | |  d  S(   Ni  iτ  g     @@Ro   s    (t   )s   %d %s %.2fms(   R   t   infot   warningt   errort   request_timeR$   Re   R@   (   R   R   RD   t
   log_methodR   t   summary(    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyR~   l  s    	#(   R   R   R   R+   R   t   staticmethodR   R~   (    (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyRg   ϊ   s
   !		(%((   R   t
   __future__R    R   R   R   t   ioR   Rz   RG   t   tornado.concurrentR   R   R   t   tornado.logR   R   t   tornado.escapeR	   t   tornado.utilR
   R   t   urllib.parset   parseR[   t   urllibR   R   R   RC   R   R"   t   HTTPConnectionR#   t   objectR?   R   Rg   Rb   t   HTTPRequest(    (    (    s+   lib/python2.7/site-packages/tornado/wsgi.pyt   <module>   s6   				5	^