o
    4ήc                      @   sZ   d Z ddlmZmZmZmZmZmZ er$ddlm	Z	m
Z
mZmZmZmZ G dd dZdS )a  
This middleware can be used when a known proxy is fronting the application,
and is trusted to be properly setting the `X-Forwarded-Proto` and
`X-Forwarded-For` headers with the connecting client information.

Modifies the `client` and `scheme` information so that they reference
the connecting client, rather that the connecting proxy.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#Proxies
    )TYPE_CHECKINGListOptionalTupleUnioncast)ASGI3ApplicationASGIReceiveCallableASGISendCallable	HTTPScopeScopeWebSocketScopec                   @   sf   e Zd Z	ddddeee ef ddfddZd	ee dee fd
dZ								dddZ	dS )ProxyHeadersMiddleware	127.0.0.1appr   trusted_hostsreturnNc                 C   sB   || _ t|trdd |dD | _nt|| _d| jv | _d S )Nc                 S   s   h | ]}|  qS  strip.0itemr   r   G/tmp/pip-target-vg8gfxp4/lib/python/uvicorn/middleware/proxy_headers.py	<setcomp>    s    z2ProxyHeadersMiddleware.__init__.<locals>.<setcomp>,*)r   
isinstancestrsplitr   setalways_trust)selfr   r   r   r   r   __init__   s
   

zProxyHeadersMiddleware.__init__x_forwarded_for_hostsc                 C   s2   | j r|d S t|D ]}|| jvr|  S qd S )Nr   )r!   reversedr   )r"   r$   hostr   r   r   get_trusted_client_host%   s   
z.ProxyHeadersMiddleware.get_trusted_client_hostscoper   receiver	   sendr
   c                    s   |d dv r\t td |}|d}|r|d nd }| js#|| jv r\t|d }d|v r:|d d}| |d	< d
|v r\|d
 d}dd |dD }	| 	|	}
d}|
|f|d< | 
|||I d H S )Ntype)http	websocket)r   r   clientr   headerss   x-forwarded-protolatin1schemes   x-forwarded-forc                 S   s   g | ]}|  qS r   r   r   r   r   r   
<listcomp>G   s    z3ProxyHeadersMiddleware.__call__.<locals>.<listcomp>r   )r   r   getr!   r   dictdecoder   r   r'   r   )r"   r(   r)   r*   client_addrclient_hostr/   x_forwarded_protox_forwarded_forr$   r&   portr   r   r   __call__1   s&   

zProxyHeadersMiddleware.__call__)r   )r(   r   r)   r	   r*   r
   r   N)
__name__
__module____qualname__r   r   r   r#   r   r'   r;   r   r   r   r   r      s.    

r   N)__doc__typingr   r   r   r   r   r   asgiref.typingr   r	   r
   r   r   r   r   r   r   r   r   <module>   s
     
 
