U
    ¨t‡bŠ  ã                   @  s¬   d dl mZ d dl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 d d	lmZ d
ZdZdZdZdZdZG dd„ deƒZG dd„ deƒZdS )é    )ÚannotationsN)ÚAny)ÚParseResultÚurlparse)ÚHttpRequestÚHttpResponse)Úpatch_vary_headers)ÚMiddlewareMixin)Úconf)Úcheck_request_enabledzAccess-Control-Allow-OriginzAccess-Control-Expose-Headersz Access-Control-Allow-CredentialszAccess-Control-Allow-HeaderszAccess-Control-Allow-MethodszAccess-Control-Max-Agec                   @  sB   e Zd Zdddœdd„Zdddœdd„Zdddddd	œd
d„ZdS )ÚCorsPostCsrfMiddlewarer   ÚNone©ÚrequestÚreturnc                 C  s0   t jr,d|jkr,|jd }||jd< |jd= dS )zj
        Put the HTTP_REFERER back to its original value and delete the
        temporary storage
        ÚORIGINAL_HTTP_REFERERÚHTTP_REFERERN)r
   ÚCORS_REPLACE_HTTPS_REFERERÚMETA)Úselfr   Úhttp_referer© r   ú:/tmp/pip-unpacked-wheel-h03uz43q/corsheaders/middleware.pyÚ_https_referer_replace_reverse   s    

z5CorsPostCsrfMiddleware._https_referer_replace_reversec                 C  s   |   |¡ d S ©N©r   ©r   r   r   r   r   Úprocess_request!   s    
z&CorsPostCsrfMiddleware.process_requestr   ©r   ÚcallbackÚcallback_argsÚcallback_kwargsr   c                 C  s   |   |¡ d S r   r   ©r   r   r   r    r!   r   r   r   Úprocess_view%   s    
z#CorsPostCsrfMiddleware.process_viewN)Ú__name__Ú
__module__Ú__qualname__r   r   r#   r   r   r   r   r      s   
r   c                   @  s¦   e Zd Zdddœdd„Zdddœdd„Zdd	d	d	dd
œdd„Zddddœdd„Zddddœdd„Zdddœdd„Zdddœdd„Z	dddœdd„Z
dddœdd „Zd!S )"ÚCorsMiddlewarer   r   r   c                 C  s–   |j  d¡}| ¡ r’|r’d|j kr’t|ƒ}tjs@|  ||¡s@dS z<|j d }d|j d  }|j  ¡ |_ ||j d< ||j d< W n tk
r�   Y nX dS )a  
        When https is enabled, django CSRF checking includes referer checking
        which breaks when using CORS. This function updates the HTTP_REFERER
        header to make sure it matches HTTP_HOST, provided that our cors logic
        succeeds
        ÚHTTP_ORIGINr   Nr   zhttps://%s/Z	HTTP_HOST)	r   ÚgetZ	is_securer   r
   ÚCORS_ALLOW_ALL_ORIGINSÚorigin_found_in_white_listsÚcopyÚKeyError)r   r   ÚoriginÚurlr   Z	http_hostr   r   r   Ú_https_referer_replace1   s*    ÿþýÿ
þ

z%CorsMiddleware._https_referer_replacezHttpResponse | Nonec                 C  sL   |   |¡|_|jrHtjr"|  |¡ |jdkrHd|jkrHtƒ }d|d< |S dS )a  
        If CORS preflight header, then create an
        empty body response (200 OK) and return it

        Django won't bother calling any other request
        view/exception middleware along with the requested view;
        it will call any response middlewares
        ÚOPTIONSZ"HTTP_ACCESS_CONTROL_REQUEST_METHODÚ0zContent-LengthN)Ú
is_enabledÚ_cors_enabledr
   r   r0   Úmethodr   r   )r   r   Úresponser   r   r   r   P   s    	
ÿþzCorsMiddleware.process_requestr   r   c                 C  s   |j rtjr|  |¡ dS )z9
        Do the referer replacement here as well
        N)r4   r
   r   r0   r"   r   r   r   r#   g   s    

zCorsMiddleware.process_viewr   )r   r6   r   c                 C  s  t |ddƒ}|dkr|  |¡}|s&|S t|dgƒ |j d¡}|sF|S zt|ƒ}W n tk
rj   | Y S X tjrzd|t	< tj
sš|  ||¡sš|  |¡sš|S tj
r°tjs°d|t< n||t< ttjƒrÒd tj¡|t< |jdk�rd tj¡|t< d tj¡|t< tj�rttjƒ|t< |S )	z1
        Add the respective CORS headers
        r4   NZOriginr(   ÚtrueÚ*z, r1   )Úgetattrr3   r   r   r)   r   Ú
ValueErrorr
   ZCORS_ALLOW_CREDENTIALSÚ ACCESS_CONTROL_ALLOW_CREDENTIALSr*   r+   Úcheck_signalÚACCESS_CONTROL_ALLOW_ORIGINÚlenZCORS_EXPOSE_HEADERSÚjoinÚACCESS_CONTROL_EXPOSE_HEADERSr5   ZCORS_ALLOW_HEADERSÚACCESS_CONTROL_ALLOW_HEADERSZCORS_ALLOW_METHODSÚACCESS_CONTROL_ALLOW_METHODSZCORS_PREFLIGHT_MAX_AGEÚstrÚACCESS_CONTROL_MAX_AGE)r   r   r6   Úenabledr.   r/   r   r   r   Úprocess_responseu   sF    

ÿ
þý

ÿzCorsMiddleware.process_responserC   r   Úbool)r.   r/   r   c                 C  s&   |dkr|t jkp$|  |¡p$|  |¡S )NÚnull)r
   ÚCORS_ALLOWED_ORIGINSÚ_url_in_whitelistÚregex_domain_match)r   r.   r/   r   r   r   r+   ©   s
    ÿýz*CorsMiddleware.origin_found_in_white_lists)r.   r   c                   s   t ‡ fdd„tjD ƒƒS )Nc                 3  s   | ]}t  |ˆ ¡V  qd S r   )ÚreÚmatch)Ú.0Zdomain_pattern©r.   r   r   Ú	<genexpr>±   s   ÿz4CorsMiddleware.regex_domain_match.<locals>.<genexpr>)Úanyr
   ZCORS_ALLOWED_ORIGIN_REGEXES)r   r.   r   rO   r   rK   °   s    þz!CorsMiddleware.regex_domain_matchc                 C  s   t t tj|j¡ƒp|  |¡S r   )rG   rL   rM   r
   ZCORS_URLS_REGEXZ	path_infor<   r   r   r   r   r3   ¶   s
    ÿþzCorsMiddleware.is_enabledc                 C  s    t jd |d�}tdd„ |D ƒƒS )N)Zsenderr   c                 s  s   | ]\}}|V  qd S r   r   )rN   ÚfunctionZreturn_valuer   r   r   rP   ½   s     z.CorsMiddleware.check_signal.<locals>.<genexpr>)r   ÚsendrQ   )r   r   Zsignal_responsesr   r   r   r<   »   s    zCorsMiddleware.check_signal)r/   r   c                   s&   dd„ t jD ƒ}t‡ fdd„|D ƒƒS )Nc                 S  s   g | ]}t |ƒ‘qS r   )r   )rN   Úor   r   r   Ú
<listcomp>À   s     z4CorsMiddleware._url_in_whitelist.<locals>.<listcomp>c                 3  s&   | ]}|j ˆ j ko|jˆ jkV  qd S r   )ÚschemeÚnetloc)rN   r.   ©r/   r   r   rP   Á   s   ÿz3CorsMiddleware._url_in_whitelist.<locals>.<genexpr>)r
   rI   rQ   )r   r/   Zoriginsr   rX   r   rJ   ¿   s    þz CorsMiddleware._url_in_whitelistN)r$   r%   r&   r0   r   r#   rF   r+   rK   r3   r<   rJ   r   r   r   r   r'   0   s   4r'   )Ú
__future__r   rL   Útypingr   Úurllib.parser   r   Zdjango.httpr   r   Zdjango.utils.cacher   Zdjango.utils.deprecationr	   Zcorsheaders.confr
   Zcorsheaders.signalsr   r=   r@   r;   rA   rB   rD   r   r'   r   r   r   r   Ú<module>   s    