U
    f9                     @   s   d dl Z d dlZd dlZd dlmZmZ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 d dlmZmZ d dlmZ d d	lmZ d
dlmZ edZG dd dZdd Zee dS )    N)async_to_synciscoroutinefunctionsync_to_async)settings)ImproperlyConfiguredMiddlewareNotUsed)request_finished)connectionstransaction)get_resolverset_urlconf)log_response)import_string   )convert_exception_to_responsezdjango.requestc                   @   sr   e Zd ZdZdZdZdZdddZdddZdd Z	d	d
 Z
dd Zdd Zdd ZdddZdd Zdd ZdS )BaseHandlerNFc                 C   s  g | _ g | _g | _|r| jn| j}t|}|}ttjD ]X}t	|}t
|dd}t
|dd}|st|sttd| n|s|rd}	n|}	z&| j|	||tjd| d}
||
}W nV tk
r } z6tjrt|rtd|| ntd	| W Y q8W 5 d
}~X Y nX |
}|d
krtd| t|drB| j d| ||j t|drd| j| ||j t|dr| j| d|j t|}|	}q8| |||}|| _d
S )z
        Populate middleware lists from settings.MIDDLEWARE.

        Must be called after the environment is fixed (see __call__ in subclasses).
        Zsync_capableTZasync_capableFzOMiddleware %s must have at least one of sync_capable/async_capable set to True.zmiddleware %s)debugnamezMiddlewareNotUsed(%r): %szMiddlewareNotUsed: %rNz$Middleware factory %s returned None.process_viewr   process_template_responseprocess_exception)_view_middleware_template_response_middleware_exception_middleware_get_response_async_get_responser   reversedr   Z
MIDDLEWAREr   getattrRuntimeErroradapt_method_modeDEBUGr   strloggerr   r   hasattrinsertr   appendr   r   _middleware_chain)selfis_asyncget_responsehandlerZhandler_is_asyncZmiddleware_pathZ
middlewareZmiddleware_can_syncZmiddleware_can_asyncZmiddleware_is_asyncZadapted_handlerZmw_instanceexc r,   =/tmp/pip-unpacked-wheel-_jot26k8/django/core/handlers/base.pyload_middleware   sv    
 zBaseHandler.load_middlewarec                 C   sl   |dkrt |}|r&|s&|p$d|j }|rL|sh|r>td| t|ddS n|rh|r`td| t|S |S )a\  
        Adapt a method to be in the correct "mode":
        - If is_async is False:
          - Synchronous methods are left alone
          - Asynchronous methods are wrapped with async_to_sync
        - If is_async is True:
          - Synchronous methods are wrapped with sync_to_async()
          - Asynchronous methods are left alone
        Nzmethod %s()z#Synchronous handler adapted for %s.TZthread_sensitivez$Asynchronous handler adapted for %s.)r   __qualname__r"   r   r   r   )r'   r(   methodZmethod_is_asyncr   r   r,   r,   r-   r   h   s    zBaseHandler.adapt_method_modec                 C   sF   t tj | |}|j|j |jdkrBtd|j	|j
||d |S )z8Return an HttpResponse object for the given HttpRequest.  %s: %sresponserequest)r   r   ROOT_URLCONFr&   _resource_closersr%   closestatus_coder   reason_phrasepathr'   r6   r5   r,   r,   r-   r)      s    


zBaseHandler.get_responsec                    sZ   t tj | |I dH }|j|j |jdkrVtt	ddd|j
|j||dI dH  |S )z
        Asynchronous version of get_response.

        Funneling everything, including WSGI, into a single async
        get_response() is too slow. Avoid the context switch by using
        a separate async response path.
        Nr2   Fr/   r3   r4   )r   r   r7   r&   r8   r%   r9   r:   r   r   r;   r<   r=   r,   r,   r-   get_response_async   s    	


zBaseHandler.get_response_asyncc           	   
   C   sJ  d}|  |\}}}| jD ]}|||||}|r q6q|dkr| |}t|rXt|}z||f||}W n8 tk
r } z| ||}|dkr W 5 d}~X Y nX | || t|drFt	|j
rF| jD ]*}|||}| j||d|jjjf d qz|
 }W n< tk
rD } z| ||}|dkr4 W 5 d}~X Y nX |S )
        Resolve and call the view, then apply view, exception, and
        template_response middleware. This method is everything that happens
        inside the request/response middleware.
        Nrender%s.process_template_responser   )resolve_requestr   make_view_atomicr   r   	Exceptionprocess_exception_by_middlewarecheck_responser#   callabler@   r   __self__	__class____name__	r'   r6   r5   callbackcallback_argscallback_kwargsmiddleware_methodZwrapped_callbacker,   r,   r-   r      sN    
   




zBaseHandler._get_responsec           	   
      s  d}|  |\}}}| jD ] }|||||I dH }|r q<q|dkr| |}t|sbt|dd}z||f||I dH }W nF tk
r } z(t| jdd||I dH }|dkr W 5 d}~X Y nX | || t|drt	|j
r| jD ]0}|||I dH }| j||d|jjjf d qz6t|j
r>|
 I dH }nt|j
dd I dH }W nJ tk
r } z*t| jdd||I dH }|dkr W 5 d}~X Y nX t|rtd|S )r?   NTr/   r@   rA   rB   zResponse is still a coroutine.)rC   r   rD   r   r   rE   rF   rG   r#   rH   r@   r   rI   rJ   rK   asyncioiscoroutiner   rL   r,   r,   r-   r      s    
   

  


  

zBaseHandler._get_response_asyncc                 C   s>   t |dr"|j}t| t|}nt }||j}||_|S )zw
        Retrieve/set the urlconf for the request. Return the view resolved,
        with its args and kwargs.
        urlconf)r#   rT   r   r   resolveZ	path_inforesolver_match)r'   r6   rT   resolverrV   r,   r,   r-   rC   ,  s    

zBaseHandler.resolve_requestc                 C   sz   |dkst |sdS |sJt|tjr8d|j|jf }nd|j|jjf }|dkr`td| nt |rvtd| dS )zT
        Raise an error if the view returned None or an uncalled coroutine.
        NzThe view %s.%szThe view %s.%s.__call__zB%s didn't return an HttpResponse object. It returned None instead.z%s didn't return an HttpResponse object. It returned an unawaited coroutine instead. You may need to add an 'await' into your view.)	rR   rS   
isinstancetypesFunctionType
__module__rK   rJ   
ValueError)r'   r5   rM   r   r,   r,   r-   rG   =  s*    
zBaseHandler.check_responsec                 C   sV   t |dt }tj D ]8\}}|d r||krt|r@tdtj|d|}q|S )NZ_non_atomic_requestsZATOMIC_REQUESTSz0You cannot use ATOMIC_REQUESTS with async views.)Zusing)	r   setr	   r   itemsr   r   r
   Zatomic)r'   viewZnon_atomic_requestsaliasZsettings_dictr,   r,   r-   rD   Y  s    zBaseHandler.make_view_atomicc                 C   s&   | j D ]}|||}|r|  S qdS )z
        Pass the exception to the exception middleware. If no middleware
        return a response for this exception, return None.
        N)r   )r'   	exceptionr6   rP   r5   r,   r,   r-   rF   d  s
    


z+BaseHandler.process_exception_by_middleware)F)NFN)N)rK   r[   r0   r   r   r   r&   r.   r   r)   r>   r   r   rC   rG   rD   rF   r,   r,   r,   r-   r      s"   
R   
 6H
r   c                 K   s   t d dS )z1Reset the URLconf after each request is finished.N)r   )Zsenderkwargsr,   r,   r-   reset_urlconfp  s    rc   )rR   loggingrY   Zasgiref.syncr   r   r   Zdjango.confr   Zdjango.core.exceptionsr   r   Zdjango.core.signalsr   Z	django.dbr	   r
   Zdjango.urlsr   r   Zdjango.utils.logr   Zdjango.utils.module_loadingr   ra   r   	getLoggerr"   r   rc   connectr,   r,   r,   r-   <module>   s"   
  ^