
v^>,                 @   s(  d  d l  Z  d  d l Z d  d l 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 m Z d  d l m Z d  d l m Z m Z m Z m Z m Z m Z m Z d  d l m Z d  d	 l m Z e j d
  Z Gd d   d e  Z Gd d   d e j  Z  d S)    N)sync_to_async)settings)signals)RequestAbortedRequestDataTooBig)base)FileResponseHttpRequestHttpResponseHttpResponseBadRequestHttpResponseServerError	QueryDictparse_cookie)set_script_prefix)cached_propertyzdjango.requestc                   s   e  Z d  Z d Z d Z d d   Z e d d    Z   f d d   Z d	 d
   Z	 d d   Z
 d d   Z e e	 e
  Z e e  Z e d d    Z   S)ASGIRequestzv
    Custom request subclass that decodes from an ASGI-standard request dict
    and wraps request body handling.
    <   c             C   s  | |  _  d |  _ d |  _ d  |  _ |  j  j d d  |  _ |  j r~ | d j |  j  r~ | d t |  j  d   |  _ n | d |  _ |  j r d |  j j	 d  |  j j
 d d d  f |  _ n | d |  _ |  j  d j   |  _ |  j  j d	 d  } t | t  r| j   } d
 |  j d | d |  j d |  j d d d d i |  _ |  j  j d  r|  j  d d |  j d <|  j d |  j d <|  j  d d |  j d <|  j  j d  r|  j  d d |  j d <t |  j  d d  |  j d <n d |  j d <d |  j d <x |  j  j d g   D] \ } } | j d  } | d k rRd } n1 | d k rgd  } n d! | j   j
 d" d#  } | j d  } | |  j k r|  j | d$ | } | |  j | <q"W|  j |  j  | |  _ d  |  _ d  S)%NF	root_path pathz%s/%s/   methodquery_stringREQUEST_METHODQUERY_STRINGZSCRIPT_NAMEZ	PATH_INFOzwsgi.multithreadTzwsgi.multiprocessclientr   ZREMOTE_ADDRZREMOTE_HOSTZREMOTE_PORTserverZSERVER_NAMEZSERVER_PORTunknown0headerslatin1zcontent-lengthCONTENT_LENGTHzcontent-typeCONTENT_TYPEzHTTP_%s-_,)scopeZ_post_parse_errorZ_read_startedZresolver_matchgetscript_name
startswithlenZ	path_inforstripreplacer   upperr   
isinstancebytesdecodeMETAstrZ_set_content_type_params_stream)selfr'   	body_filer   namevalueZcorrected_name r9   ;/tmp/pip-build-8lau8j11/django/django/core/handlers/asgi.py__init__    s\    				#	"			!"			zASGIRequest.__init__c             C   s   t  |  j d  S)Nr   )r   r2   )r5   r9   r9   r:   GETc   s    zASGIRequest.GETc                s   |  j  j d  p t   j   S)Nscheme)r'   r(   super_get_scheme)r5   )	__class__r9   r:   r?   g   s    zASGIRequest._get_schemec             C   s    t  |  d  s |  j   |  j S)N_post)hasattr_load_post_and_filesrA   )r5   r9   r9   r:   	_get_postj   s    
zASGIRequest._get_postc             C   s   | |  _  d  S)N)rA   )r5   postr9   r9   r:   	_set_posto   s    zASGIRequest._set_postc             C   s    t  |  d  s |  j   |  j S)N_files)rB   rC   rG   )r5   r9   r9   r:   
_get_filesr   s    
zASGIRequest._get_filesc             C   s   t  |  j j d d   S)NZHTTP_COOKIEr   )r   r2   r(   )r5   r9   r9   r:   COOKIESz   s    zASGIRequest.COOKIES)__name__
__module____qualname____doc__Zbody_receive_timeoutr;   r   r<   r?   rD   rF   rH   propertyPOSTZFILESrI   r9   r9   )r@   r:   r      s   Cr   c                   s   e  Z d  Z d Z e Z d Z   f d d   Z d d   Z d d	   Z	 d
 d   Z
   f d d   Z d d   Z e d d    Z d d   Z   S)ASGIHandlerzHandler for ASGI requests.      c                s   t    j   |  j   d  S)N)r>   r;   Zload_middleware)r5   )r@   r9   r:   r;      s    zASGIHandler.__init__c                sO  | d d k r$ t  d | d   y |  j |  Id H} Wn t k
 rT d SYn Xt |  j |   t t j j  d |  j	 d |  Id H|  j
 | |  \ } } | d k r |  j | |  Id Hd St j |  j  r |  j |  Id H} n t |  j  |  Id H} |  j	 | _ t | t  r6|  j | _ |  j | |  Id Hd S)zV
        Async entrypoint - parses the request and hands off to get_response.
        typehttpz5Django can only handle ASGI/HTTP connections, not %s.NZsenderr'   )
ValueError	read_bodyr   r   get_script_prefixr   r   Zrequest_startedsendr@   create_requestsend_responseasyncioZiscoroutinefunctionZget_responseZ_handler_classr/   r   
chunk_size
block_size)r5   r'   receiverX   r6   requestZerror_responseresponser9   r9   r:   __call__   s*    	'zASGIHandler.__call__c                s   t  j d t j d d  } x[ |   Id H} | d d k rE t    d | k rb | j | d  | j d d	  s Pq W| j d
  | S)z*Reads a HTTP body from an ASGI connection.max_sizemodezw+bNrS   zhttp.disconnectbody	more_bodyFr   )tempfileSpooledTemporaryFiler   ZFILE_UPLOAD_MAX_MEMORY_SIZEr   writer(   seek)r5   r^   r6   messager9   r9   r:   rV      s    	zASGIHandler.read_bodyc             C   s   y |  j  | |  d f SWnk t k
 r` t j d d t j   d d d i d t   f SYn( t k
 r d t d d d	 f SYn Xd S)
z
        Create the Request object and returns either (request, None) or
        (None, response) if there is an error response.
        Nz Bad Request (UnicodeDecodeError)exc_infoextrastatus_codei  z413 Payload too largestatusi  )	request_classUnicodeDecodeErrorloggerwarningsysrk   r   r   r
   )r5   r'   r6   r9   r9   r:   rY      s    zASGIHandler.create_requestc                sX   y t    j | | |  SWn7 t k
 rS t t j rB t j   n d d d SYn Xd S)z#Last-chance handler for exceptions.zInternal Server Errorcontent_typez
text/plainN)r>   handle_uncaught_exception	Exceptionr   r   DEBUG	traceback
format_exc)r5   r_   resolverrk   )r@   r9   r:   ru      s    z%ASGIHandler.handle_uncaught_exceptionc          	      s  g  } xu | j    D]g \ } } t | t  r= | j d  } t | t  r[ | j d  } | j t |  t |  f  q WxE | j j   D]4 } | j d | j d d  j d  j	   f  q W| d d d | j
 d	 | i  Id
 H| j r]xO | D]G } x> |  j |  D]- \ } }	 | d d d | d d i  Id
 HqWq W| d d i  Id
 HnE xB |  j | j  D]. \ } }
 | d d d | d |
 i  Id
 HqpW| j   d
 S)z)Encode and send a response out over ASGI.asciir!   s
   Set-Cookieheaderr   rS   zhttp.response.startrn   r    Nzhttp.response.bodyrd   re   T)itemsr/   r3   encodeappendr0   cookiesvaluesoutputstriprm   Z	streamingchunk_bytescontentclose)r5   r`   rX   response_headersr|   r8   cpartchunkr%   lastr9   r9   r:   rZ      s8    #,		zASGIHandler.send_responsec             c   st   d } | s | d f Vd SxR | t  |  k  ro | | | |  j  | |  j t  |  k f V| |  j 7} q Wd S)z
        Chunks some data up so it can be sent in reasonable size messages.
        Yields (chunk, last_chunk) tuples.
        r   TN)r+   r\   )clsdatapositionr9   r9   r:   r     s    zASGIHandler.chunk_bytesc             C   s&   t  j r t  j S| j d d  p% d S)zU
        Return the script prefix to use from either the scope or a setting.
        r   r   )r   ZFORCE_SCRIPT_NAMEr(   )r5   r'   r9   r9   r:   rW     s    	zASGIHandler.get_script_prefixi   )rJ   rK   rL   rM   r   ro   r\   r;   ra   rV   rY   ru   rZ   classmethodr   rW   r9   r9   )r@   r:   rP      s   &/rP   )!r[   loggingrs   rf   rx   Zasgiref.syncr   Zdjango.confr   Zdjango.corer   Zdjango.core.exceptionsr   r   Zdjango.core.handlersr   Zdjango.httpr   r	   r
   r   r   r   r   Zdjango.urlsr   Zdjango.utils.functionalr   	getLoggerrq   r   BaseHandlerrP   r9   r9   r9   r:   <module>   s   4h