
    @lj                    p    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y)    )annotationsN)ASGI3ApplicationASGIReceiveCallableASGISendCallableScopec                  "    e Zd ZdZdddZddZy)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>
    c                2    || _         t        |      | _        y N)app_TrustedHoststrusted_hosts)selfr   r   s      S/root/.hermes/venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py__init__zProxyHeadersMiddleware.__init__   s    *=9    c                b  K   |d   dk(  r| j                  |||       d {   S |j                  d      }|r|d   nd }|| j                  v rd }g }|d   D ]$  \  }}	|dk(  r|	}|dk(  s|j                  |	       & |F|j	                  d      j                         }
|
d	v r#|d   d
k(  r|
j                  dd      |d<   n|
|d<   |rGdj                  |      j	                  d      }| j                  j                  |      \  }}|r||f|d<   | j                  |||       d {   S 7 	7 w)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   scopereceivesend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ii)(3k!n$,,,48#24"$Y/ 9e//.3+//*11%8	9 '2$;$B$B8$L$R$R$T!$(FFV}3*;*C*CFD*Qh*;h%"'**-C"D"K"KH"U!//JJ?[
d (,TlE(OXXeWd333C 8B 4s)   D/D*AD/+B:D/%D-&D/-D/N)z	127.0.0.1)r   r   r   list[str] | strreturnNone)r&   r   r'   r   r(   r   r5   r6   )__name__
__module____qualname____doc__r   r3    r   r   r	   r	   	   s    :#4r   r	   c                f    | j                  d      D cg c]  }|j                          c}S c c}w )N,)splitr"   )r.   items     r   _parse_raw_hostsr@   B   s%    %*[[%56TDJJL666s   .c                   | j                  d      rS| j                  d      }|dk(  r| dfS | d| }| |dz   d }|s|dfS |j                  d      s| dfS 	 |t        |dd       fS | j	                  d      dk(  r#| j                  dd      \  }}	 |t        |      fS | dfS # t        $ r |dfcY S w xY w# t        $ r | dfcY S w xY w)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   s        r   _parse_host_portrO   F   s    jjo"!8OQ{#+/+,	7N##C(!8O	Yqr]+++ {{31\\#q)
d	T?" !8O  	7N	  	!8O	s$   B  B3  B0/B03CCc                  0    e Zd ZdZddZddZd	dZd
dZy)r   z(Container for trusted hosts and networksc                   |ddgfv | _         t               | _        t               | _        t               | _        | j                   st        |t              rt        |      }|D ]e  }d|v r0	 | j                  j                  t        j                  |             7	 | j                  j                  t        j                  |             g  t        j                  d      | j                        | _        y # t        $ r | j                  j                  |       Y w xY w# t        $ r | j                  j                  |       Y w xY w)N*/i   )maxsize)always_trustsettrusted_literalsr   trusted_networks
isinstancestrr@   add	ipaddress
ip_networkrJ   
ip_address	functools	lru_cache_compute_trust_trusts)r   r   r1   s      r   r   z_TrustedHosts.__init__l   s   "/C#<"?*-%QTQVTWTY   -- 0 ?% 8
 $;8--11)2F2Ft2LM
8**..y/C/CD/IJ8& 9y**489L9LM & 8--11$78 & 8--11$78s$   +.C7.D!7$DD!$EEc                    | j                   ry|syt        |      dkD  r| j                  |      S | j                  |      S )NTF   )rU   lenra   rb   )r   r1   s     r   __contains__z_TrustedHosts.__contains__   sA     t9s?&&t,,||D!!r   c                    	 t        j                  |      | j                  v xs t        fd| j                  D              S # t
        $ r || j                  v cY S w xY w)Nc              3  &   K   | ]  }|v  
 y wr   r;   ).0netips     r   	<genexpr>z/_TrustedHosts._compute_trust.<locals>.<genexpr>   s     2^292^s   )r\   r^   r   anyrX   rJ   rW   )r   r1   rk   s     @r   ra   z_TrustedHosts._compute_trust   s_    	1%%d+B+++^s2^H]H]2^/^^ 	140000	1s   AA A A c                    t        |      }| j                  rt        |d         S t        |      D ]  }t        |      \  }}|| vs||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   )r@   rU   rO   reversed)r   r0   x_forwarded_for_hosts	host_portr1   r2   s         r   r%   z(_TrustedHosts.get_trusted_client_address   ss    
 !1 A#$9!$<== ""78 	"I))4JD$4Tz!	"   5a 899r   N)r   r4   r5   r6   )r1   z
str | Noner5   bool)r1   rZ   r5   rr   )r0   rZ   r5   tuple[str, int])r7   r8   r9   r:   r   rf   ra   r%   r;   r   r   r   r   i   s    2'NR"1:r   r   )r.   rZ   r5   z	list[str])r.   rZ   r5   rs   )
__future__r   r_   r\   uvicorn._typesr   r   r   r   r	   r@   rO   r   r;   r   r   <module>rv      s6    "   Y Y64 64r7 FR: R:r   