o
    
jg                     @  s`   d dl mZ d dlZd dlmZmZmZmZ G dd dZdd
dZ	dddZ
G dd dZdS )    )annotationsN)ASGI3ApplicationASGIReceiveCallableASGISendCallableScopec                   @  s&   e Zd ZdZddd	d
ZdddZdS )ProxyHeadersMiddlewareaB  Middleware for handling known proxy headers

    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.

    References:
    - <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#Proxies>
    - <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For>
    	127.0.0.1appr   trusted_hostslist[str] | strreturnNonec                 C  s   || _ t|| _d S N)r	   _TrustedHostsr
   )selfr	   r
    r   S/home/kuhnn/.local/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py__init__   s   zProxyHeadersMiddleware.__init__scoper   receiver   sendr   c                   s   |d dkr|  |||I d H S |d}|r|d nd }|| jv rht|d }d|v rM|d d }|dv rM|d d	krI|d
d|d< n||d< d|v rh|d d}| j|\}	}
|	rh|	|
f|d< |  |||I d H S )Ntypelifespanclientr   headerss   x-forwarded-protolatin1>   wswsshttphttps	websocketr   r   schemes   x-forwarded-for)r	   getr
   dictdecodestripreplaceget_trusted_client_address)r   r   r   r   client_addrclient_hostr   x_forwarded_protox_forwarded_forhostportr   r   r   __call__   s&   

zProxyHeadersMiddleware.__call__N)r   )r	   r   r
   r   r   r   )r   r   r   r   r   r   r   r   )__name__
__module____qualname____doc__r   r.   r   r   r   r   r      s    r   valuestrr   	list[str]c                 C  s   dd |  dD S )Nc                 S  s   g | ]}|  qS r   )r%   ).0itemr   r   r   
<listcomp><   s    z$_parse_raw_hosts.<locals>.<listcomp>,)split)r3   r   r   r   _parse_raw_hosts;   s   r;   tuple[str, int]c                 C  s   |  drH| d}|dkr| dfS | d| }| |d d }|s&|dfS | ds/| dfS z|t|dd fW S  tyG   |df Y S w | ddkrl| dd\}}z|t|fW S  tyk   | df Y S w | dfS )a&  Parse a forwarded host value into host and optional port.

    Accepts bare IPs, IPv4 `host:port`, and bracketed IPv6 `[host]:port`.
    Any unrecognized or malformed value is treated conservatively and returned
    without a port so trust checks do not silently normalize arbitrary input.
    []r      N:)
startswithfindint
ValueErrorcountrsplit)r3   bracket_endr,   	remainderr-   r   r   r   _parse_host_port?   s.   


rJ   c                   @  s.   e Zd ZdZdddZdddZdddZdS )r   z(Container for trusted hosts and networksr
   r   r   r   c              	   C  s   |ddgfv | _ t | _t | _t | _| j s^t|tr t|}|D ]=}d|v rCz| jt	
| W q" tyB   | j| Y q"w z| jt	| W q" ty]   | j| Y q"w d S d S )N*/)always_trustsettrusted_literalsr
   trusted_networks
isinstancer4   r;   add	ipaddress
ip_networkrE   
ip_address)r   r
   r,   r   r   r   r   e   s*   
z_TrustedHosts.__init__r,   
str | Noneboolc                   sd   | j rdS |s	dS zt|  | jv rW dS t fdd| jD W S  ty1   || jv  Y S w )NTFc                 3  s    | ]} |v V  qd S r   r   )r6   netipr   r   	<genexpr>   s    z-_TrustedHosts.__contains__.<locals>.<genexpr>)rM   rS   rU   r
   anyrP   rE   rO   )r   r,   r   rY   r   __contains__   s   

z_TrustedHosts.__contains__r+   r4   r<   c                 C  sT   t |}| jrt|d S t|D ]}t|\}}|| vr#||f  S qt|d S )zExtract the client address from x_forwarded_for header.

        In general this is the first "untrusted" host in the forwarded for list.
        r   )r;   rM   rJ   reversed)r   r+   x_forwarded_for_hosts	host_portr,   r-   r   r   r   r'      s   z(_TrustedHosts.get_trusted_client_addressN)r
   r   r   r   )r,   rV   r   rW   )r+   r4   r   r<   )r/   r0   r1   r2   r   r]   r'   r   r   r   r   r   b   s
    

'r   )r3   r4   r   r5   )r3   r4   r   r<   )
__future__r   rS   uvicorn._typesr   r   r   r   r   r;   rJ   r   r   r   r   r   <module>   s    
3
#