U
    5øi[8  ã                   @   sÂ   d dl Z d dlZd dl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 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Ú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‚|r‚d}	n|}	z&| j|	||tjd| d�}
||
ƒ}W nV tk
�r } z6tjrêt|ƒrÞt 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-gcyiijx6/django/core/handlers/base.pyÚload_middleware   sp    ÿÿ   þ
ÿþÿÿzBaseHandler.load_middlewarec                 C   sn   |dkrt  |¡}|r(|s(|p&d|j }|rN|sj|r@t d|¡ t|dd�S n|rj|rbt 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 %s adapted.T©Zthread_sensitivezAsynchronous %s adapted.)ÚasyncioÚiscoroutinefunctionÚ__qualname__r!   r   r   r   )r&   r'   ÚmethodZmethod_is_asyncr   r   r+   r+   r,   r   c   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&   r7   r6   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.
        Nr3   Fr.   r4   r5   )r   r   r8   r%   r9   r$   r:   r;   r   r   r<   r=   r>   r+   r+   r,   Úget_response_asyncŒ   s    	


  ýzBaseHandler.get_response_asyncc           	   
   C   sL  d}|   |¡\}}}| jD ]}|||||ƒ}|r q6q|dkr¨|  |¡}t |¡rZt|ƒ}z||f|ž|Ž}W n8 tk
r¦ } z|  ||¡}|dkr–‚ W 5 d}~X Y nX |  ||¡ t	|dƒ�rHt
|jƒ�rH| jD ]*}|||ƒ}| j||d|jjjf d� qÒz| ¡ }W n< tk
�rF } z|  ||¡}|dk�r6‚ 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/   r0   r   Ú	ExceptionÚprocess_exception_by_middlewareÚcheck_responser"   ÚcallablerA   r   Ú__self__Ú	__class__Ú__name__©	r&   r7   r6   ÚcallbackÚcallback_argsÚcallback_kwargsÚmiddleware_methodZwrapped_callbackÚer+   r+   r,   r       sD    




ÿý
zBaseHandler._get_responsec           	   
   Ã   s¾  d}|   |¡\}}}| jD ] }|||||ƒI dH }|r q<q|dkrÆ|  |¡}t |¡sdt|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ƒ�r¦t
|jƒ�r¦| jD ]0}|||ƒI dH }| j||d|jjjf d� qðz8t |j¡�rB| ¡ 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 |¡�rºtdƒ‚|S )r@   NTr.   rA   rB   rC   zResponse is still a coroutine.)rD   r   rE   r/   r0   r   rF   rG   rH   r"   rI   rA   r   rJ   rK   rL   Úiscoroutiner   rM   r+   r+   r,   r   Ô   sd    


þ ý

ÿýþ ý

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&   r7   rT   ÚresolverrV   r+   r+   r,   rD     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.)	r/   rS   Ú
isinstanceÚtypesÚFunctionTypeÚ
__module__rL   rK   Ú
ValueError)r&   r6   rN   r   r+   r+   r,   rH   &  s*    þÿÿ
þÿzBaseHandler.check_responsec                 C   sX   t |dtƒ ƒ}t ¡ D ]<}|jd r|j|krt |¡r@tdƒ‚t	j
|jd�|ƒ}q|S )NZ_non_atomic_requestsZATOMIC_REQUESTSz0You cannot use ATOMIC_REQUESTS with async views.)Zusing)r   Úsetr   ÚallZsettings_dictÚaliasr/   r0   r   r	   Zatomic)r&   ÚviewZnon_atomic_requestsÚdbr+   r+   r,   rE   B  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&   Ú	exceptionr7   rQ   r6   r+   r+   r,   rG   M  s
    


z+BaseHandler.process_exception_by_middleware)F)NFN)N)rL   r[   r1   r   r   r   r%   r-   r   r(   r?   r   r   rD   rH   rE   rG   r+   r+   r+   r,   r      s"   
J     ÿ
4A
r   c                 K   s   t dƒ dS )z1Reset the URLconf after each request is finished.N)r   )ZsenderÚkwargsr+   r+   r,   Úreset_urlconfY  s    rd   )r/   ÚloggingrY   Zasgiref.syncr   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   rb   r   Ú	getLoggerr!   r   rd   Úconnectr+   r+   r+   r,   Ú<module>   s"   
  G