
    @OOf 4                     X   d Z ddlZddlZddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ  ed      Zeeeef   Z	 dZ	  G d de      Z G d d      ZeZ  G d de      Z!e	 G d de             Z"y)z!
Base class for protocol layers.
    N)abstractmethod)Callable)	Generator)	dataclass)DEBUG)Any)ClassVar)
NamedTuple)TypeVar)
Connection)commands)events)Command)	StartHook)ContextTi   c                   :    e Zd ZU dZej
                  ed<   eed<   y)PausedzS
    State of a layer that's paused because it is waiting for a command reply.
    command	generatorN)__name__
__module____qualname____doc__r   r   __annotations__CommandGenerator     V/var/www/premiumrankchecker/venv/lib/python3.12/site-packages/mitmproxy/proxy/layer.pyr   r   #   s     r   r   c                   P   e Zd ZU dZdZee   ed<   eed<   e	dz  ed<   	 e
j                  ej                     ed<   	 dZedz  ed<   	 ded	dfd
Zd Zd Zed	efd       Zedej                  d	ed   fd       Zdej                  d	ed   fdZddefdZdej2                  fdZy)Layera"  
    The base class for all protocol layers.

    Layers interface with their child layer(s) by calling .handle_event(event),
    which returns a list (more precisely: a generator) of commands.
    Most layers do not implement .directly, but instead implement ._handle_event, which
    is called by the default implementation of .handle_event.
    The default implementation of .handle_event allows layers to emulate blocking code:
    When ._handle_event yields a command that has its blocking attribute set to True, .handle_event pauses
    the execution of ._handle_event and waits until it is called with the corresponding CommandCompleted event.
    All events encountered in the meantime are buffered and replayed after execution is resumed.

    The result is code that looks like blocking code, but is not blocking:

        def _handle_event(self, event):
            err = yield OpenConnection(server)  # execution continues here after a connection has been established.

    Technically this is very similar to how coroutines are implemented.
     _Layer__last_debug_messagecontextN_paused_paused_event_queuedebugreturnc                 
   || _         | j                   j                  j                  |        d | _        t	        j
                         | _        t        |j                  dd      }|rdt        |j                        z  | _
        y y )Nproxy_debugFz  )r$   layersappendr%   collectionsdequer&   getattroptionslenr'   )selfr$   show_debug_outputs      r   __init__zLayer.__init__S   si    ""4(#.#4#4#6 #GOO]EJGNN 33DJ r   c                     t        | d| j                        }t        |dd      }|j                  dd      }|dk(  rd}nd| }t        |       j                   d| dS )	Nstater   r"   state__handle_eventzstate: ())r/   r8   replacetyper   )r2   statefunr6   s      r   __repr__zLayer.__repr__]   sk    4$*<*<=*b1h+O#EeW%Et*%%&awa00r   c                 z   t        |      t        kD  r|dt         dz   }t        j                  |k(  r:|j	                  dd      d   j                         }t        |      dkD  r|dd dz   }n|t        _        | j                  J t        j                  t        j                  || j                        t              S )zJyield a Log command indicating what message is passing through this layer.Nu   …
   r      )r1   MAX_LOG_STATEMENT_SIZEr!   r#   splitstripr'   r   Logtextwrapindentr   )r2   messages     r   __debugzLayer.__debugg   s    w<00556>G%%0mmD!,Q/557G7|c!!$3-%/)0E&zz%%%||HOOGTZZ@%HHr   c                     	 | j                   j                  j                  |       }dj                  d | j                   j                  d|dz    D              S # t        $ r t        |       cY S w xY w)zKrepr() for this layer and all its parent layers, only useful for debugging.z >> c              3   2   K   | ]  }t        |        y wN)repr).0xs     r   	<genexpr>z"Layer.stack_pos.<locals>.<genexpr>|   s     O1tAwOs   NrA   )r$   r+   indexjoin
ValueErrorrN   )r2   idxs     r   	stack_poszLayer.stack_post   si    	P,,%%++D1C ;;O0C0CIcAg0NOOO  	:	s   %A A0/A0eventc              #   $   K   dE d{    y7 w)zHandle a proxy server eventr   Nr   r2   rW   s     r   r8   zLayer._handle_event~   s      s   c              #   V  K   | j                   rt        |t        j                        xr" |j                  | j                   j                  u }| j
                  | j                  |rdnd d|        |r6t        |t        j                        sJ | j                  |      E d {    y | j                  j                  |       y | j
                  | j                  d|        | j                  |      }d }	 |j                  |      }	 | j
                  0t        |t        j                        s| j                  d|        |j                  du r| |_        t!        ||      | _         | y | 	 t#        |      }x7 # t        $ r Y y w xY w# t        $ r Y y w xY ww)Nz>>z>! z>> T<< )r%   
isinstancer   CommandCompletedr   r'   _Layer__debug_Layer__continuer&   r,   r8   sendStopIterationr   rF   blockingr   next)r2   rW   pause_finishedcommand_generatorra   r   s         r   handle_eventzLayer.handle_event   s    << 5&"9"9: :MMT\\%9%99  zz%llnd$%Gq#PQQ!%)@)@AAA??5111((//6zz%llS=11 $ 2 25 9D ,006 ::)%gx||<"llS	?;;##t+ (,G$#))$DL "M!M"&'8"9) ' 2  ! 0 ) s\   B%F)'F	(AF)?F A,F)=F F)	FF)FF)	F&#F)%F&&F)rf   c              #   \  K   	 |j                  |      }	 | j                  0t        |t        j
                        s| j                  d|        |j                  du r| |_        t        ||      | _	        | y| 	 t        |      }x# t        $ r Y yw xY w# t        $ r Y yw xY ww)z
        Yield commands from a generator.
        If a command is blocking, execution is paused and this function returns without
        processing any further commands.
        NTr\   )ra   rb   r'   r]   r   rF   r_   rc   r   r%   rd   )r2   rf   ra   r   s       r   	__processzLayer.__process   s     	 (,,T2G zz%!'8<<8,,WI774' $( %%  "#45G)   		0 % sL   B,B A,B,B B,	BB,BB,	B)&B,(B))B,c              #     K   | j                   J | j                   j                  }d| _         | j                  ||j                        E d{    | j                   s| j                  r| j                  j                         }| j                  | j                  d|        | j                  |      }| j                  |      E d{    | j                   s| j                  ryyyy7 7 #w)z
        Continue processing events after being paused.
        The tricky part here is that events in the event queue may trigger commands which again pause the execution,
        so we may not be able to process the entire queue.
        Nz!> )	r%   r   _Layer__processreplyr&   popleftr'   r_   r8   )r2   rW   rf   evs       r   
__continuezLayer.__continue   s      ||''' LL22>>"3U[[AAA,,4#;#;))113Bzz%llS:.. $ 2 22 6~~&7888 ,,4#;#;,#;, 	B 9s+   AC1C-A=C1C/C1)C1/C1rM   )r   r   r   r   r#   r	   strr   r   r   r-   r.   r   Eventr'   r4   r>   r_   propertyrV   r   r   r8   rg   rk   r^   r`   r   r   r   r!   r!   ,   s   ( +-(3-,d] %**6<<88 E3:
4 4D 41I P3 P P 6<< 4DT4J  4&,, 43CD3I 4n$+; $L9 7 7 9r   r!   c                        e Zd ZU edz  ed<   	 eej                     ed<   	 eed<   dde	deddf fdZ
d	 Zd
ej                  f fdZd
ej                  fdZd Zd Zd ZdefdZ xZS )	NextLayerNlayerr   _ask_on_startr$   ask_on_startr(   c                     t         |   |       | j                  j                  j	                  |        d | _        g | _        || _        d | _        y rM   )	superr4   r$   r+   removeru   r   rv   _handle)r2   r$   rw   	__class__s      r   r4   zNextLayer.__init__  sE    !""4(
)QUr   c                 2    dt        | j                         S )Nz
NextLayer:)rN   ru   r2   s    r   r>   zNextLayer.__repr__	  s    D,-..r   rW   c              #      K   | j                   | j                  |      E d {    y t        | 	  |      E d {    y 7 7 wrM   )r{   ry   rg   )r2   rW   r|   s     r   rg   zNextLayer.handle_event  s?     <<#||E***w+E222 +2s   !AAAAAAc              #      K   | j                   j                  |       | j                  r3t        |t         j                        r| j                         E d {    y t        |t        j                        rO|j                  | j                  j                  k(  r,t        j                  | j                  j                         y t        |t        j                        r| j                         E d {    y y 7 7 wrM   )r   r,   rv   r]   Start_askmeventsConnectionClosed
connectionr$   clientr   CloseConnectionDataReceivedrY   s     r   r8   zNextLayer._handle_event  s     5! *UFLL"Ayy{""ug667  DLL$7$77 **4<<+>+>??w334yy{"" 5 # #s%   AC>C:BC>3C<4C><C>c              #     K   t        |        | j                  r| j                  r5t        j                  | j                   d| j                  t
               | j                  D ]%  }| j                  j                  |      E d{    ' | j                  j                          | j                  j                  | _        | j                  j                  | _	        | j                  j                  | _
        yy7 sw)z
        Manually trigger a next_layer hook.
        The only use at the moment is to make sure that the top layer is initialized.
        z[nextlayer] N)NextLayerHookru   r'   r   rF   r   r   rg   clearr8   r{   )r2   es     r   r   zNextLayer._ask#  s     
 D!! ::zzlldjj\djj^#LeTT[[ 6::2215556KK !%

 7 7D!%!8!8D::22DL  6s   BD 
C>A4D c                 L    | j                  | j                  j                        S rM   )_datar$   r   r~   s    r   data_clientzNextLayer.data_client=      zz$,,--..r   c                 L    | j                  | j                  j                        S rM   )r   r$   serverr~   s    r   data_serverzNextLayer.data_server@  r   r   r   c                 P    fd| j                   D        }dj                  |      S )Nc              3      K   | ]9  }t        |t        j                        r|j                  k(  r|j                   ; y wrM   )r]   r   r   r   data)rO   r   r   s     r   rQ   z"NextLayer._data.<locals>.<genexpr>D  s8      
!W112q||z7Q FF
s   ?Ar   )r   rS   )r2   r   r   s    ` r   r   zNextLayer._dataC  s&    
[[

 xx~r   )F)r   r   r   r!   r   listr   rq   boolr   r4   r>   rg   r8   r   r   r   r   r   __classcell__)r|   s   @r   rt   rt      s    4<0>V Vt V V/3'-- 3#7== #"34//
 r   rt   c                       e Zd ZU dZeed<   y)r   z
    Network layers are being switched. You may change which layer will be used by setting data.layer.

    (by default, this is done by mitmproxy.addons.NextLayer)
    r   N)r   r   r   r   rt   r   r   r   r   r   r   L  s     Or   r   )#r   r-   rG   abcr   collections.abcr   r   dataclassesr   loggingr   typingr   r	   r
   r   mitmproxy.connectionr   mitmproxy.proxyr   r   mitmproxy.proxy.commandsr   r   mitmproxy.proxy.contextr   r   r   rC   r   r!   r   rt   r   r   r   r   <module>r      s       $ % !      + $ " , . +CLWc1_- 
   N Z  D9 D9P  
Q Qh I  r   