
    ^j                    ~    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          Z	dd
Z
ddZ G d d          ZdS )    )annotationsN)ASGI3ApplicationASGIReceiveCallableASGISendCallableScopec                  $    e Zd ZdZddd	Z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                <    || _         t          |          | _        d S N)r   _TrustedHostsr   )selfr   r   s      R/home/drrone/venv/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py__init__zProxyHeadersMiddleware.__init__   s    *=99    scoper   receiver   sendr   c                  K   |d         dk    r|                      |||           d {V S |                    d          }|r|d         nd }|| j        v rd }g }|d         D ])\  }}	|dk    r|	}|dk    r|                    |	           *|V|                    d                                          }
|
d	v r+|d         d
k    r|
                    dd          |d<   n|
|d<   |rNd                    |                              d          }| j                            |          \  }}|r||f|d<   |                      |||           d {V 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ports                 r   __call__zProxyHeadersMiddleware.__call__   s     =J&&%$777777777ii))(3=k!nn$,,,48#24"$Y/ 9 9e///.3++///*11%888&2$;$B$B8$L$L$R$R$T$T!$(FFFV}33*;*C*CFD*Q*Qh*;h% 3"'**-C"D"D"K"KH"U"U!/JJ?[[
d 3 (,TlE(OXXeWd333333333r   N)r
   )r   r   r   r   r   r   )r   r   r   r   r   r   r   r   )__name__
__module____qualname____doc__r   r7    r   r   r	   r	   	   sK         : : : : :#4 #4 #4 #4 #4 #4r   r	   r2   strr   	list[str]c                @    d |                      d          D             S )Nc                6    g | ]}|                                 S r<   )r)   ).0items     r   
<listcomp>z$_parse_raw_hosts.<locals>.<listcomp>C   s     666TDJJLL666r   ,)split)r2   s    r   _parse_raw_hostsrF   B   s"    66U[[%5%56666r   tuple[str, int]c                   |                      d          r|                     d          }|dk    r| dfS | d|         }| |dz   d         }|s|dfS |                     d          s| dfS 	 |t          |dd                   fS # t          $ r |dfcY S w xY w|                     d          dk    r?|                     dd          \  }}	 |t          |          fS # t          $ r | dfcY S w xY 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)r2   bracket_endr5   	remainderr6   s        r   _parse_host_portrV   F   sO     jjoo"!8OQ{]#+/++,	 	7N##C(( 	!8O	Yqrr]++++ 	 	 	7NNN	 {{31\\#q))
d	T?" 	 	 	!8OOO	 !8Os$   ,B BBC C.-C.c                  2    e Zd ZdZddZdd
ZddZddZdS )r   z(Container for trusted hosts and networksr   r   r   r   c                   |ddgfv | _         t                      | _        t                      | _        t                      | _        | j         st          |t                    rt          |          }|D ]}d|v rX	 | j                            t          j
        |                     4# t          $ r | j                            |           Y Zw xY w	 | j                            t          j        |                     # t          $ r | j                            |           Y w xY w t          j        d          | j                  | _        d S )N*/i   )maxsize)always_trustsettrusted_literalsr   trusted_networks
isinstancer=   rF   add	ipaddress
ip_networkrQ   
ip_address	functools	lru_cache_compute_trust_trusts)r   r   r5   s      r   r   z_TrustedHosts.__init__l   sp   "/C#<"?*-%%QTQVQVTWTYTY   	8--- @ 0 ? ?% 8 8
 $;;8-11)2Ft2L2LMMMM% 8 8 8-11$7777788*..y/CD/I/IJJJJ% 8 8 8-11$777778 9y*48889LMMs$   :,B''$CC,C??$D&%D&r5   
str | Noneboolc                    | j         rdS |sdS t          |          dk    r|                     |          S |                     |          S )NTF   )r\   lenrg   rh   )r   r5   s     r   __contains__z_TrustedHosts.__contains__   sV     	4 	5 t99s??&&t,,,||D!!!r   r=   c                    	 t          j        |          | j        v pt          fd| j        D                       S # t
          $ r || j        v cY S w xY w)Nc              3      K   | ]}|v V  	d S r   r<   )rA   netips     r   	<genexpr>z/_TrustedHosts._compute_trust.<locals>.<genexpr>   s'      2^2^292^2^2^2^2^2^r   )rb   rd   r   anyr_   rQ   r^   )r   r5   rr   s     @r   rg   z_TrustedHosts._compute_trust   sz    	1%d++B++^s2^2^2^2^H]2^2^2^/^/^^ 	1 	1 	1400000	1s   <A   AAr4   rG   c                    t          |          }| j        rt          |d                   S t          |          D ]}t          |          \  }}|| vr||fc S 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   )rF   r\   rV   reversed)r   r4   x_forwarded_for_hosts	host_portr5   r6   s         r   r,   z(_TrustedHosts.get_trusted_client_address   s    
 !1 A A 	>#$9!$<=== ""788 	" 	"I))44JD$4Tz!!!  
   5a 8999r   N)r   r   r   r   )r5   ri   r   rj   )r5   r=   r   rj   )r4   r=   r   rG   )r8   r9   r:   r;   r   rn   rg   r,   r<   r   r   r   r   i   so        22'N 'N 'N 'NR" " " "1 1 1 1: : : : : :r   r   )r2   r=   r   r>   )r2   r=   r   rG   )
__future__r   re   rb   uvicorn._typesr   r   r   r   r	   rF   rV   r   r<   r   r   <module>r{      s    " " " " " "         Y Y Y Y Y Y Y Y Y Y Y Y64 64 64 64 64 64 64 64r7 7 7 7       FR: R: R: R: R: R: R: R: R: R:r   