o
    òT·jý  ã                   @  sh   d dl mZ d dl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   úc/home/dinkstrade/pdmp-scanner/venv/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 r|d }g }|d D ]\}}	|dkr6|	}q+|dkr?| |	¡ q+|d urb| d¡ ¡ }
|
d	v rb|d d
kr^|
 dd¡|d< n|
|d< |r|d |¡ d¡}| j |¡\}}|r|||f|d< |   |||¡I d H S )NÚtypeÚlifespanÚclientr   Úheaderss   x-forwarded-protos   x-forwarded-forÚlatin1>   ÚwsÚwssÚhttpÚhttpsÚ	websocketr   r   Úschemes   , )	r	   Úgetr
   ÚappendÚdecodeÚstripÚreplaceÚjoinÚget_trusted_client_address)r   r   r   r   Úclient_addrÚclient_hostÚx_forwarded_proto_valueÚx_forwarded_for_valuesÚnameÚvalueÚx_forwarded_protoÚx_forwarded_forÚhostÚportr   r   r   Ú__call__   s4   €


€zProxyHeadersMiddleware.__call__N)r   )r	   r   r
   r   r   r   )r   r   r   r   r   r   r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r3   r   r   r   r   r   	   s    r   r.   Ústrr   ú	list[str]c                 C  s   dd„ |   d¡D ƒS )Nc                 S  s   g | ]}|  ¡ ‘qS r   )r%   )Ú.0Úitemr   r   r   Ú
<listcomp>C   s    z$_parse_raw_hosts.<locals>.<listcomp>ú,)Úsplit)r.   r   r   r   Ú_parse_raw_hostsB   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)r.   Úbracket_endr1   Ú	remainderr2   r   r   r   Ú_parse_host_portF   s.   


ÿÿrN   c                   @  s8   e Zd ZdZdd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 tjdd�| jƒ| _d S )NÚ*ú/i   )Úmaxsize)Úalways_trustÚsetÚtrusted_literalsr
   Útrusted_networksÚ
isinstancer8   r?   ÚaddÚ	ipaddressÚ
ip_networkrI   Ú
ip_addressÚ	functoolsÚ	lru_cacheÚ_compute_trustÚ_trusts)r   r
   r1   r   r   r   r   l   s(   
þþz_TrustedHosts.__init__r1   ú
str | NoneÚboolc                 C  s2   | j rdS |s	dS t|ƒdkr|  |¡S |  |¡S )NTFéý   )rR   Úlenr]   r^   ©r   r1   r   r   r   Ú__contains__•   s   

z_TrustedHosts.__contains__r8   c                   sL   zt  |¡‰ ˆ | jv pt‡ fdd„| jD ƒƒW S  ty%   || jv  Y S w )Nc                 3  s   � | ]}ˆ |v V  qd S r   r   )r:   Únet©Úipr   r   Ú	<genexpr>¥   s   € z/_TrustedHosts._compute_trust.<locals>.<genexpr>)rX   rZ   r
   ÚanyrU   rI   rT   rc   r   rf   r   r]   ¢   s   
$ÿz_TrustedHosts._compute_trustr0   r@   c                 C  sT   t |ƒ}| jrt|d ƒS t|ƒD ]}t|ƒ\}}|| vr#||f  S qt|d ƒS )z’Extract the client address from x_forwarded_for header.

        In general this is the first "untrusted" host in the forwarded for list.
        r   )r?   rR   rN   Úreversed)r   r0   Úx_forwarded_for_hostsÚ	host_portr1   r2   r   r   r   r(   ©   s   ÿz(_TrustedHosts.get_trusted_client_addressN)r
   r   r   r   )r1   r_   r   r`   )r1   r8   r   r`   )r0   r8   r   r@   )r4   r5   r6   r7   r   rd   r]   r(   r   r   r   r   r   i   s    

)
r   )r.   r8   r   r9   )r.   r8   r   r@   )Ú
__future__r   r[   rX   Úuvicorn._typesr   r   r   r   r   r?   rN   r   r   r   r   r   Ú<module>   s    
9
#