
v^                 @   s`   d  d l  m Z d  d l m Z d  d l m Z m Z Gd d   d  Z Gd d   d  Z d S)	    )BytesIO)SpooledTemporaryFile)AsyncToSyncsync_to_asyncc               @   s.   e  Z d  Z d Z d d   Z d d   Z d S)
WsgiToAsgizG
    Wraps a WSGI application to make it into an ASGI application.
    c             C   s   | |  _  d  S)N)wsgi_application)selfr    r	   //tmp/pip-build-8lau8j11/asgiref/asgiref/wsgi.py__init__   s    zWsgiToAsgi.__init__c                s"   t  |  j  | | |  Id Hd S)z
        ASGI application instantiation point.
        We return a new WsgiToAsgiInstance here with the WSGI app
        and the scope, ready to respond when it is __call__ed.
        N)WsgiToAsgiInstancer   )r   scopereceivesendr	   r	   r
   __call__   s    zWsgiToAsgi.__call__N)__name__
__module____qualname____doc__r   r   r	   r	   r	   r
   r      s   r   c               @   s[   e  Z d  Z d Z d d   Z d d   Z d d   Z d d	 d
  Z e d d    Z	 d S)r   z;
    Per-socket instance of a wrapped WSGI application
    c             C   s   | |  _  d |  _ d  S)NF)r   response_started)r   r   r	   r	   r
   r      s    	zWsgiToAsgiInstance.__init__c                s   | d d k r t  d   | |  _ t d d   } xW |   Id  H} | d d k rd t  d   | j | j d d	   | j d
  s: Pq: W| j d  t |  |  _ |  j |  Id  HWd  QRXd  S)Ntypehttpz&WSGI wrapper received a non-HTTP scopemax_sizei   zhttp.requestz0WSGI wrapper received a non-HTTP-request messagebody    	more_bodyr   )	
ValueErrorr   r   writegetseekr   	sync_sendrun_wsgi_app)r   r   r   r   r   messager	   r	   r
   r   !   s    	zWsgiToAsgiInstance.__call__c             C   s  d | d d | j  d d  d | d d | d	 j d
  d d | d d d, d | j  d d  d | d t   d d d d d d i } d | k r | d d | d <t | d d  | d <n d | d <d | d <d  | k r | d  d | d! <x |  j j  d" g   D] \ } } | j d#  } | d$ k r7d% } n1 | d& k rLd' } n d( | j   j d) d*  } | j d#  } | | k r| | d+ | } | | | <qW| S)-zM
        Builds a scope and request body into a WSGI environ object.
        REQUEST_METHODmethodZSCRIPT_NAME	root_path Z	PATH_INFOpathQUERY_STRINGZquery_stringasciiZSERVER_PROTOCOLzHTTP/%shttp_versionzwsgi.version   r   zwsgi.url_schemeschemer   z
wsgi.inputzwsgi.errorszwsgi.multithreadTzwsgi.multiprocesszwsgi.run_onceFserverZSERVER_NAMEZSERVER_PORT	localhost80clientZREMOTE_ADDRheaderslatin1zcontent-lengthCONTENT_LENGTHzcontent-typeCONTENT_TYPEzHTTP_%s-_,)r+   r   )r   decoder   strr   upperreplace)r   r   r   environnamevalueZcorrected_namer	   r	   r
   build_environ4   s>    

	

"		z WsgiToAsgiInstance.build_environNc             C   s   |  j  r  | d j | d   t |  d  rG | d k rG t d   | j d d  \ } } t |  } d d   | D } d	 d
 d | d | i |  _ d S)z/
        WSGI start_response callable.
        r+      response_startNz=You cannot call start_response a second time without exc_info c             S   s:   g  |  ]0 \ } } | j    j d   | j d   f  q S)r)   )lowerencode).0r=   r>   r	   r	   r
   
<listcomp>r   s   	z5WsgiToAsgiInstance.start_response.<locals>.<listcomp>r   zhttp.response.startstatusr1   )r   with_tracebackhasattrr   splitintrA   )r   rG   response_headersexc_infostatus_coder6   r1   r	   r	   r
   start_responsea   s    			
z!WsgiToAsgiInstance.start_responsec             C   s   |  j  |  j |  } x^ |  j | |  j  D]G } |  j sS d |  _ |  j |  j  |  j d d d | d d i  q+ W|  j s d |  _ |  j |  j  |  j d d i  d S)z
        Called in a subthread to run the WSGI app. We encapsulate like
        this so that the start_response callable is called in the same thread.
        Tr   zhttp.response.bodyr   r   N)r?   r   r   rO   r   r    rA   )r   r   r<   outputr	   r	   r
   r!   |   s    				zWsgiToAsgiInstance.run_wsgi_app)
r   r   r   r   r   r   r?   rO   r   r!   r	   r	   r	   r
   r      s   -r   N)	ior   tempfiler   Zasgiref.syncr   r   r   r   r	   r	   r	   r
   <module>   s   