
    @OOfҾ                    Z   d dl m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  G d d      Z	 d	 	 	 ddZ	 	 ddZd Z	 	 	 	 	 	 ddZ	 d	 	 	 	 	 ddZe	 G d d             Z G d dej:                        Zy)     )annotationsN)	Generator)Iterable)Iterator)	dataclass)field)Enum)contentviewsflow)
flowfilter)http)base)decodec                     e Zd Ze G d d             Ze G d de             Ze G d de             Ze G d d             Ze G d	 d
             Z G d de	      Z
edd       Zedd       Zedd       Z G d de	      Ze	 	 	 	 	 	 	 	 	 	 dd       Ze	 	 	 	 dd       Z G d d      Z	 	 d	 	 	 	 	 	 	 ddZddZd dZy)!ProtoParserc                  <    e Zd ZU dZded<   	 dZded<   	 dZded<   y)	ProtoParser.ParserRulean  
        A parser rule lists Field definitions which are applied if the filter rule matches the flow.

        Matching on flow-level also means, a match applies to request AND response messages.
        To restrict a rule to a requests only use 'ParserRuleRequest', instead.
        To restrict a rule to a responses only use 'ParserRuleResponse', instead.
        z'list[ProtoParser.ParserFieldDefinition]field_definitions strnamefilterN)__name__
__module____qualname____doc____annotations__r   r        \/var/www/premiumrankchecker/venv/lib/python3.12/site-packages/mitmproxy/contentviews/grpc.py
ParserRuler      s.    	 CB6c8	r    r"   c                      e Zd ZdZy)ProtoParser.ParserRuleResponsez
        A parser rule lists Field definitions which are applied if the filter rule matches the flow.

        The rule only applies if the processed message is a server response.
        Nr   r   r   r   r   r    r!   ParserRuleResponser$   ,       	r    r&   c                      e Zd ZdZy)ProtoParser.ParserRuleRequestz
        A parser rule lists Field definitions which are applied if the filter rule matches the flow.

        The rule only applies if the processed message is a client request.
        Nr%   r   r    r!   ParserRuleRequestr)   4   r'   r    r*   c                  j    e Zd ZU dZded<   	  ee      Zded<   	 dZded	<   	 dZ	d
ed<   	 dZ
ded<   y)!ProtoParser.ParserFieldDefinitiona  
        Defines how to parse a field (or multiple fields with the same tag) in a protobuf messages.

        This allows to apply an intended decoding (f.e. decode uint64 as double instead) and to assign
        a descriptive name to a field. Field definitions are aggregated into rules, which also holds
        a filter to match selected HTTP messages.

        The most natural way to use this, is to describe known parts of a single protobuf message
        in a set of field descriptors, pack them into a rule and set the filter of the rule in a way,
        that it only applies to proper protobuf messages (f.e. to request traffic against an API endpoint
        matched by an URL flowfilter)
        r   tagdefault_factoryz	list[str]tag_prefixesNzProtoParser.DecodedTypes | Noneintended_decoding
str | Noner   Fzbool | None	as_packed)r   r   r   r   r   r   listr0   r1   r   r3   r   r    r!   ParserFieldDefinitionr,   <   sM    	P i"'"=i=}=A:Aujr!&	;&Yr    r5   c                  *    e Zd ZU dZded<   dZded<   y)ProtoParser.ParserOptionsFboolinclude_wiretypeexclude_message_headersN)r   r   r   r9   r   r:   r   r    r!   ParserOptionsr7   u   s     "'$&
 ).-r    r;   c                  T    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZdZy)ProtoParser.DecodedTypesr                           	   
                        N)r   r   r   int32int64uint32uint64sint32sint64r8   enumfixed32sfixed32floatfixed64sfixed64doublestringbytesmessageunknownr   r    r!   DecodedTypesr=      s^     r    r`   c                    d}d}|t        |       k  r0| |   }||dz  d|z  z  z  }|dz  }|dk  r||fS |t        |       k  r0t        d      )Nr      rD   r>      z&varint exceeds bounds of provided data)len
ValueError)dataresoffsetos       r!   _read_base128lezProtoParser._read_base128le   sp    s4y VAAH!f*--CaKF4x s{"! s4y " ABBr    c                >    dt        j                  d| d d       d   fS )NrA   z<Ir   structunpackrf   s    r!   	_read_u32zProtoParser._read_u32   #    &--d2Ah/222r    c                >    dt        j                  d| d d       d   fS )NrE   z<Qr   rl   ro   s    r!   	_read_u64zProtoParser._read_u64   rq   r    c                  $    e Zd ZdZdZdZdZdZdZy)ProtoParser.WireTypesr   r>   r?   r@   rA   rB   N)	r   r   r   varintbit_64len_delimitedgroup_start	group_endbit_32r   r    r!   	WireTypesru      s     	r    r|   c           	     |   g }d}|t        |       k  rt        j                  | |d        \  }}t        j                  |dz        }|dz	  }	||z  }|t        j                  j                  k(  rt        j                  | |d        \  }}
||z  }|
j                         }|dkD  rt        j                  j                  }|dkD  rt        j                  j                  }nt        j                  j                  }n|t        j                  j                  k(  r<t        j                  | |d        \  }}
||z  }t        j                  j                  }n,|t        j                  j                  k(  rdt        j                  | |d        \  }}||z  }|t        | |d        kD  rt        d      | |||z    }
||z  }t        j                  j                  }n|t        j                  j                   k(  s|t        j                  j"                  k(  rt        d|       |t        j                  j$                  k(  r;t        j'                  | |d        \  }}
||z  }t        j                  j(                  }nt        d      t        j+                  |||||	|
|	      }|j-                  |       |t        |       k  r|S )
Nr   rD   r@   @       z(length delimited field exceeds data sizezdeprecated field: ,invalid WireType for protobuf messsage field)	wire_typepreferred_decodingoptionsrulesr-   
wire_valueparent_field)rd   r   rj   r|   rv   
bit_lengthr`   r_   rR   rQ   rw   rs   rY   rx   re   r^   ry   rz   r{   rp   rV   Fieldappend)	wire_datar   r   r   rg   posrh   keywtr-   valblr   lengthr   s                  r!   read_fieldszProtoParser.read_fields   s    (*C	N"%55ioFKFC&&sQw/B(C6MC [**111)99)CD/Jv^^%7)4)A)A)I)I&7)4)A)A)H)H&)4)A)A)H)H&{,,333)33IcdODv%0%=%=%E%E"{,,:::!,!<!<Yst_!MvC	#$00$%OPPcFl3v%0%=%=%E%E"k++777..888 #5bT!:;;{,,333)33IcdODv%0%=%=%E%E" !!OPP%%#5) & E JJuo C	N"r 
r    c                `   t        | j                  t              s!t        dt	        | j                               | j                  }| j
                  }| j                  }| j                  }| j                  }| j                  t        j                  j                  k7  st        | j                  t              st        d      |t        j                  j                  k(  s|t        j                  j                  k(  s|t        j                  j                   k(  s|t        j                  j"                  k(  st|t        j                  j$                  k(  sW|t        j                  j&                  k(  s:|t        j                  j(                  k(  s|t        j                  j*                  k(  rt        j                  j,                  }na|t        j                  j.                  k(  s:|t        j                  j0                  k(  s|t        j                  j2                  k(  rt        j                  j4                  }n|t        j                  j6                  k(  s:|t        j                  j8                  k(  s|t        j                  j:                  k(  rt        j                  j<                  }n}|t        j                  j>                  k(  s:|t        j                  j                  k(  s|t        j                  j@                  k(  rt        j                  j                  }ntC        d      g }d}|t        j                  j,                  k(  rv|tE        |      k  rt        jG                  ||d        \  }	}
||	z  }|jI                  t        jK                  ||||||
| jL                  d             |tE        |      k  reng|t        j                  j<                  k(  rtE        |      dz  dk7  rt        d      |tE        |      k  rt        jO                  ||d        \  }	}
||	z  }|jI                  t        jK                  ||||||
| jL                  d             |tE        |      k  ren|t        j                  j                  k(  r|tE        |      k  rt        jG                  ||d        \  }	}||	z  }||||z    }
|tE        ||d        kD  rt        d	      |jI                  t        jK                  ||||||
| jL                  d             ||z  }|tE        |      k  rn|t        j                  jP                  k(  s|t        j                  jR                  k(  rt        d
      |t        j                  j4                  k(  rtE        |      dz  dk7  rt        d      |tE        |      k  rqt        jU                  ||d        \  }	}
||	z  }|jI                  t        jK                  ||||||
| jL                  d             |tE        |      k  rent        d      d| _+        |S )Nz1can not unpack field with data other than bytes: z?packed fields have to be embedded in a length delimited messagez;Wire type could not be determined from packed decoding typer   T)r   r   r   r-   r   r   r   is_unpacked_childrenrE   zcan not parse as packed bit64z/packed length delimited field exceeds data sizez$group tags can not be encoded packedrA   zcan not parse as packed bit32r   ),
isinstancer   r]   re   typer-   r   r   r   r   r   r|   rx   r`   rO   rP   rQ   rR   rS   rT   r8   rU   rv   rV   rW   rX   r{   rY   rZ   r[   rw   r\   r^   	TypeErrorrd   rj   r   r   r   rs   ry   rz   rp   is_packed_parent)packed_fieldr   r-   r   r   r1   packed_wire_typerg   r   rh   r   r   s               r!   read_packed_fieldszProtoParser.read_packed_fields  sl    ,1159CDI`I`DaCbc  (22	##-9-A-A.:.@.@6B6U6U ""k&;&;&I&IIl55u=Q  !9!9!?!?? K$<$<$B$BB K$<$<$C$CC K$<$<$C$CC K$<$<$C$CC K$<$<$C$CC K$<$<$A$AA K$<$<$A$AA*44;;!9!9!A!AA K$<$<$E$EE K$<$<$B$BB*44;;!9!9!A!AA K$<$<$E$EE K$<$<$C$CC*44;;!9!9!@!@@ K$<$<$B$BB K$<$<$D$DD*44BB M  (*{44;;;I&)99)CD/Jv

%% '+<#"2#&%1%>%>-1 & 	 I& !6!6!=!==9~!Q& !@AAI&)33IcdODv

%% '+<#"2#&%1%>%>-1 & 	 I& !6!6!D!DDI&!,!<!<Yst_!MvcFl3C	#$00$%VWW

%% '+<#"2#&%1%>%>-1 & 	 v% I&(  5 5 A AA;#8#8#B#BBCDD!6!6!=!==9~!Q& !@AAI&)33IcdODv

%% '+<#"2#&%1%>%>-1 & 	 I&" KLL )-%
r    c                      e Zd ZdZ	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddZd Z	 d	 	 	 	 	 ddZ	 d	 	 	 	 	 ddZddZ	ddZ
dd	Zd
 ZddZdddZddZy)ProtoParser.Fielda
  
        Represents a single field of a protobuf message and handles the varios encodings.

        As mitmproxy sees the data passing by as raw protobuf message, it only knows the
        WireTypes. Each of the WireTypes could represent different Protobuf field types.
        The exact Protobuf field type can not be determined from the wire format, thus different
        options for decoding have to be supported.
        In addition the parsed WireTypes are (intermediary) stored in Python types, which adds
        some additional overhead type conversions.

        WireType            represented Protobuf Types                 Python type (intermediary)

        0: varint           int32, int64, uint32, uint64, enum,        int (*)
                            sint32, sint64 (both ZigZag encoded),      int
                            bool                                       bool
                                                                       float (**)

        1: bit_64           fixed64, sfixed64,                         int (*)
                            double                                     float

        2: len_delimited    string,                                    str
                            message,                                   class 'Message'
                            bytes,                                     bytes (*)
                            packed_repeated_field                      class 'Message' (fields with same tag)

        3: group_start      unused (deprecated)                        -
        4: group_end        unused (deprecated)                        -

        5: bit_32           fixed32, sfixed32,                         int (*)
                            float                                      float

        (*) Note 1:  Conversion between WireType and intermediary python representation
                     is handled by Kaitai protobuf decoder and always uses the python
                     representation marked with (*). Converting to alternative representations
                     is handled inside this class.
        (**) Note 2: Varint is not used to represent floating point values, but some applications
                     store native floats in uint32 protobuf types (or native double in uint64).
                     Thus we allow conversion of varint to floating point values for convenience
                     (A well known APIs "hide" GPS latitude and longitude values in varint types,
                     much easier to spot such things when rendered as float)

        Ref: - https://developers.google.com/protocol-buffers/docs/proto3
             - https://developers.google.com/protocol-buffers/docs/encoding
        c	                   || _         || _        || _        || _        || _        d| _        || _        || _        || _        d| _	        g | _
        | j                  M| j                  j                  d d  | _
        | j                  j                  | j                  j                         d| _        | j                          || j                  rd| _        y y y )Nr   F)r   r   r   r-   r   r   r   r   r   r   parent_tagsr   
try_unpackapply_rules)	selfr   r   r-   r   r   r   r   r   s	            r!   __init__zProtoParser.Field.__init__  s     5>DN@RD#+5DODH6=DLDI7<DJ:FD$ %  ! +-D  ,#'#4#4#@#@#C   ''(9(9(=(=>#DO 'D,E,E"' -F'r    c                   | j                         }d }d }d}	 | j                  D ]  }|j                  D ]  }d}t        |j                        dk(  r|j
                  |k(  rd}n'|j                  D ]  }	|	|j
                  z   |k(  sd} n |sY|rW|j                  |j                  | _        |j                  |j                  | _        t        |j                        | _          y |j                  r|j                  n|}|j                  r|j                  n|}|j                  sd} 	 |r|| _        |r|| _        || _        y # t        $ r}
t        j                  |
       Y d }
~
y d }
~
ww xY w)NFr   T)_gen_tag_strr   r   rd   r0   r-   r   r1   r   r8   r3   r   	Exceptionloggingwarning)r   only_first_hittag_strr   decodingr3   rulefdmatchrtes              r!   r   zProtoParser.Field.apply_rules  sc   '')GDHI&# JJ 5D"44 5 %r/1479J$(E&(oo *#%;'#9,0E$)* !-#%77#602DI#%#7#7#C>@>R>RD$;26r||2D & 35''rwwt (*';'; %'$8$8)1 !)
 $&<<04I955>  $DI.6D+"+ #""#s2   A,E E AE &A E ' E 	E0E++E0c                    | j                   d d  }|j                  | j                         dj                  |D cg c]  }t	        |       c}      S c c}w )N.)r   r   r-   joinr   )r   tagsr-   s      r!   r   zProtoParser.Field._gen_tag_str  sC    ##A&DKK!886#SX6776s   Ac                .   | j                   t        j                  j                  k(  r	 || j	                  ||      fS | j                   t        j                  j                  k(  r	 || j	                  ||      fS | j                   t        j                  j                  k(  r	 || j	                  ||      fS | j                   t        j                  j                   k(  r	 || j	                  ||      fS t        j                  j(                  | j                  fS # t
        $ rw t        | j                        j                         dkD  r(t        j                  j                  | j                  fcY S t        j                  j                  | j                  fcY S w xY w# t
        $ r) t        j                  j                  | j                  fcY S w xY w# t
        $ r) t        j                  j                  | j                  fcY S w xY w# t
        $ r t        j                  j"                  t        j                  j$                  t        j                  j&                  g}|D ]1  }||k(  r|s	 || j	                  |d      fc cY S # t
        $ r Y /w xY w Y w xY w)z
            Tries to decode as intended, applies failover, if not possible

            Returns selected decoding and decoded value
            r   F)r   r   r|   rv   	decode_asr   intr   r   r`   rR   rQ   rw   rY   r{   rV   rx   r^   r\   r]   r_   )r   r1   try_as_packedlen_delimited_strategyfailover_decodings        r!   safe_decode_asz ProtoParser.Field.safe_decode_as"  so    ~~!6!6!=!==	P,dnn)=/   ;#8#8#?#??M,dnn)=/  
 ;#8#8#?#??M,dnn)=/  
 ;#8#8#F#FF!,dnn)=/  , ++33T__DDY ! P4??+6682=*77>>OO*77>>OOP ! M&33;;T__LLM ! M&33;;T__LLM ! ! $0088#0077#0066N*
 .D 	!),0AA-$!#4dnn 157 $   ) ! !	!!ss   D %F !G H AF.&FF/GG/H HA#J(J ;J 	J	JJJJc                   |du rt         j                  |       S | j                  t         j                  j                  k(  rt        | j                  t              sJ |t         j                  j                  k(  r| j                  dz  dk7  S |t         j                  j                  k(  r_| j                  j                         dkD  rt        d      t        j                  dt        j                  d| j                              d   S |t         j                  j                   k(  r_| j                  j                         d	kD  rt        d
      t        j                  dt        j                  d| j                              d   S |t         j                  j"                  k(  r4| j                  j                         dkD  rt        d      | j                  S |t         j                  j$                  k(  s|t         j                  j&                  k(  r4| j                  j                         d	kD  rt        d      | j                  S |t         j                  j(                  k(  rH| j                  j                         dkD  rt        d      | j                  dz	  | j                  dz   z  S |t         j                  j*                  k(  rH| j                  j                         d	kD  rt        d      | j                  dz	  | j                  dz   z  S |t         j                  j,                  k(  s|t         j                  j.                  k(  r| j1                         S | j                  t         j                  j2                  k(  r|t         j                  j4                  k(  r| j                  S |t         j                  j6                  k(  r7t        j                  dt        j                  d| j                              d   S |t         j                  j.                  k(  r| j1                         S | j                  t         j                  j8                  k(  r|t         j                  j:                  k(  r| j                  S |t         j                  j<                  k(  r7t        j                  dt        j                  d| j                              d   S |t         j                  j,                  k(  r| j1                         S | j                  t         j                  j>                  k(  rt        | j                  t@              sJ |t         j                  jB                  k(  r| jE                  d      S |t         j                  j@                  k(  r| j                  d d  S |t         j                  jF                  k(  r7t         jI                  | j                  | | jJ                  | jL                        S t        d      )NT)r   l    r   r   zwire value too large for int32z!i!Ir~   zwire value too large for int64z!q!Qzwire value too large for uint32zwire value too largezwire value too large for sint32r>   zwire value too large for sint64)escape_newline)r   r   r   r   z&intended decoding mismatches wire type)'r   r   r   r|   rv   r   r   r   r`   r8   rO   r   r   rm   rn   packrP   rQ   rR   rU   rS   rT   rX   r[   _wire_value_as_floatrw   rY   rZ   r{   rV   rW   rx   r]   r\   wire_value_as_utf8r^   r   r   r   )r   r1   r3   s      r!   r   zProtoParser.Field.decode_asb  s    D "5545HH~~!6!6!=!==!$//3777$(@(@(E(EE??-??1DD&+*B*B*H*HH113b8'(HII!==v{{4/QRSTUU&+*B*B*H*HH113b8'(HII!==v{{4/QRSTUU&+*B*B*I*II113b8'(IJJ??*%)A)A)H)HH(K,D,D,I,II113b8'(>????*&+*B*B*I*II113b8'(IJJ OOq0!+5   '+*B*B*I*II113b8'(IJJ !OOq0doo6I4JJJ%)A)A)G)GG(K,D,D,K,KK  4466;#8#8#?#??$(@(@(H(HH??*&+*B*B*K*KK!==v{{4/QRSTUU&+*B*B*I*II4466;#8#8#?#??$(@(@(H(HH??*&+*B*B*K*KK!==v{{4/QRSTUU&+*B*B*H*HH4466;#8#8#F#FF!$//5999$(@(@(G(GG  22$2GG&+*B*B*H*HH??1--&+*B*B*J*JJ&22"&//%) $"jj	 3   DEEr    c                    t        d      )NzbFuture work, needed to manipulate and re-encode protobuf message, with respect to given wire types)NotImplementedError)inputvalintended_encodings     r!   encode_fromzProtoParser.Field.encode_from  s    %t r    c                    | j                         }t        |      dk(  rt        j                  d|      d   S t        |      dk(  rt        j                  d|      d   S t	        d      )a  
            Handles double (64bit) and float (32bit).
            Assumes Network Byte Order (big endian).

            Usable for:

               WireType --> Protobuf Type):
               ----------------------------
               varint        --> double/float (not intended by ProtoBuf, but used in the wild)
               bit_32        --> float
               bit_64        --> double
               len_delimited --> 4 bytes: float / 8 bytes: double / other sizes return NaN
            rA   z!fr   rE   z!dz4can not be converted to floatingpoint representation)_value_as_bytesrd   rm   rn   r   )r   vs     r!   r   z&ProtoParser.Field._wire_value_as_float  s`     $$&A1v{}}T1-a00Q1}}T1-a00RSSr    c                   t        | j                  t              r| j                  S t        | j                  t              r| j                  j	                         dkD  rt        d      | j                  j	                         dkD  r t        j                  d| j                        S t        j                  d| j                        S t        d      )Nr~   z-value exceeds 64bit, violating protobuf specsr   r   r   zcan not be converted to bytes)r   r   r]   r   r   re   rm   r   r   s    r!   r   z!ProtoParser.Field._value_as_bytes  s    $//51&DOOS1??--/"4 %%TUU__//1B6!;;tT__== ";;tT__== !!@AAr    c                P    t        | j                        j                  d      d   S Nr   )r   r   splitr   s    r!   _wire_type_strz ProtoParser.Field._wire_type_str  s!    t~~&,,S1"55r    c                <    t        |      j                  d      d   S r   )r   r   )r   r   s     r!   _decoding_strzProtoParser.Field._decoding_str  s    x=&&s+B//r    c                    t        | j                  t              r1| j                  j                  d      }|r|j	                  dd      S |S t        | j                        S )Nzutf-8
z\n)r   r   r]   r   replacer   )r   r   rg   s      r!   r   z$ProtoParser.Field.wire_value_as_utf8  sK    $//51oo,,W53As{{4/JsJt''r    c              #    K   | j                  | j                  | j                        \  }}| j                         | j	                         | j                  |      | j                  d}t        |t              rR|t        j                  j                  k(  r| j                  s	d|d<   | |D ]  }|j                         E d{     y||d<   | y7 w)at  
            Returns a generator which passes the field as a dict.

            In order to return the field value it gets decoded (based on a failover strategy and
            provided ParserRules).
            If the field holds a nested message, the fields contained in the message are appended.
            Ultimately this flattens all fields recursively.
            )r-   wireTyper   r   r   r   N)r   r   r   r   r   r   r   r   r4   r   r`   r^   r   gen_flat_decoded_field_dicts)r   selected_decodingdecoded_valfield_desc_dictfs        r!   r   z.ProtoParser.Field.gen_flat_decoded_field_dicts  s      .2-@-@''.*{ ((* //1 ../@A			O +t,%"//778 11 .0OE*))$ @A ==???@ *5&%% @s   C CCCN)F)r   ru   r   r=   r-   r   r   ProtoParser.Field | Noner   zint | bytesr   r7   r   list[ProtoParser.ParserRule]r   r8   returnNone)T)r1   r=   r   r8   r   z[tuple[ProtoParser.DecodedTypes, bool | float | int | bytes | str | list[ProtoParser.Field]])r1   r=   r3   r8   r   z:bool | int | float | bytes | str | list[ProtoParser.Field])r   r=   )r   rX   )r   r]   )r   r=   )r   r   r   zGenerator[dict, None, None])r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r   zProtoParser.Field  s    +	l */#	(,#	( !9#	( 	#	(
 3#	( $#	( /#	( 0#	( #'#	( #	(L+	#Z	8 #(>	E7>	E  >	E
	>	EB RWP	F%=P	FJNP	FGP	Fd	
	T,	B$	6	0	( 	&r    r   Nc                   || _         |t        j                         }|| _        |g }|| _        	 t        j                  | j                   | j                  d | j                        | _        y # t        $ r}t        d      |d }~ww xY w)N)r   r   r   r   znot a valid protobuf message)	rf   r   r;   r   r   r   root_fieldsr   re   )r   rf   r   parser_optionsr   s        r!   r   zProtoParser.__init__  s      	!(668N%=E
	D8C8O8O))!jj	 9P 9D  	D;<!C	Ds   <A. .	B7BBc              #  b   K   | j                   D ]  }|j                         E d {     y 7 wN)r   r   )r   r   s     r!   r   z(ProtoParser.gen_flat_decoded_field_dicts'  s0     !! 	8A55777	87s   #/-/c              #  :  K   | j                         D ]  }| j                  j                  r	|d   dk(  r"| j                  j                  rdj	                  |d   |d         }ndj	                  |d         }|d   }|d   }t        |d         }||||f  y w)	Nr   r^   z[{}->{}]r   z[{}]r   r-   r   )r   r   r:   r9   formatr   )r   
field_dictcol1col2col3col4s         r!   gen_str_rowszProtoParser.gen_str_rows+  s     ;;= 	)J44z*i7||,,!((J)?JAWX}}Z
%;<f%De$Dz%()DdD((	)s   BB)rf   r]   r   ztuple[int, int])
r   r]   r   r   r   r7   r   r   r   list[ProtoParser.Field])r   r   r   r   )NN)rf   r]   r   z#list[ProtoParser.ParserRule] | Noner   zParserOptions | Noner   r   r   )r   z&Generator[tuple[str, ...], None, None])r   r   r   r   r"   r&   r*   r5   r;   r	   r`   staticmethodrj   rp   rs   r|   r   r   r   r   r   r   r   r    r!   r   r      s     , Z   J   6Z 6Z 6Zp . . .t 4 C C, 3 3 3 3D  AA.A +A ,	A
 
!A AF R'R	 R Rhq& q&l 6:/3	DD 3D -	D
 
D08)r    r   c              #  8  K   g }d}g }| D ]  }t        |t        |            }t        |      |k  r |j                  d       t        |      |k  r t        t        |            D ]   }t        t        ||         ||         ||<   " |j                  |        t        t        |            D ]  }t	        ||   |      ||<    |D ]N  }g }t        t        |            D ]/  }||   j                  ||   dz         }	|j                  d|	f       1 | P yw)a  
    Helper function to render tables with variable column count (move to contentview base, if needed elsewhere)

    Note: The function has to convert generators to a list, as all rows have to be processed twice (to determine
    the column widths first).
    r   r?   textN)maxrd   r   rangeminljust)

table_rowsmax_col_widthrows	col_count
cols_widthrowcol_numilinecol_vals
             r!   format_tabler  @  s5     #%DIJ 	3s8,	*o	)a  *o	)SX 	NG"%c#g,&7G9L"MJw	N 	C 3z?# :JqM=9
1:  !SX 	+G'l((G)<q)@AGKK)*	+ 
s   ADC	Dc              #  F  K   | ra	 t        j                  d| dd       \  }}t        j                  d|z  | dd|z          d   }|r	 t	        ||      }||f | d|z   d } | r`yy# t        $ r}t        d      |d}~ww xY w# t        $ r}t        d      |d}~ww xY ww)	zGenerator iterates over body data and returns a boolean indicating if the messages
    was compressed, along with the raw message data (decompressed) for each gRPC message
    contained in the body dataz!?iNrB   z!%isr   zinvalid gRPC message)encodedencodingz+Failed to decompress gRPC message with gzip)rm   rn   r   re   r   )rf   compression_schememsg_is_compressedr   decoded_messager   s         r!   parse_grpc_messagesr  b  s      	<(.eT"1X(F%v$mmFVOT!a&j=QRSTUO W"(+6H#  00AJL!!   	<34!;	<  W !NOUVVWsR   B!>A' B!B B!%B!'	B0A<<BB!	BBBB!c                    t        |       S r   )r4   )generator_funcs    r!   hack_generator_to_listr    s    r    c              #  j   K   t        t        | ||      j                               E d {    y 7 w)N)rf   r   r   )r  r   r   r^   r   r   s      r!   format_pbufr    s0     
 u	

,.  s   )313c              #     K   d}t        | |      D ]F  \  }}dt        |      z   dz   t        |r|n|      z   dz   }d|fg t        |||      E d {    H y 7 w)Nr   )rf   r  zgRPC message z (compressed )r   r  )r  r   r  )rf   r   r   r  message_count
compressed
pb_messageheadlines           r!   format_grpcr    s      M"5&8# 

J - ! 
$
CD 	 	 !""~U
 	
 	

	
s   AAAAc                  Z    e Zd ZU  eej
                        Zded<    ee      Z	ded<   y)
ViewConfigr.   r7   r   r   parser_rulesN)
r   r   r   r   r   r;   r   r   r4   r  r   r    r!   r  r    s/    05#111N-  27t1LL.Lr    r  c                       e Zd ZdZdZg dZddgZg dZdd fdZ	 	 	 	 	 	 	 	 dd	Z	dddd
	 	 	 	 	 	 	 	 	 ddZ
dddd
	 	 	 	 	 	 	 	 	 ddZ xZS )ViewGrpcProtobufz'Human friendly view of protocol bufferszgRPC/Protocol Buffer)zapplication/x-protobufzapplication/x-protobufferzapplication/grpc-protozapplication/grpczapplication/prpc)gzipidentitydeflatezstdNc                H    t         |           |
t               }|| _        y r   )superr   r  config)r   r!  	__class__s     r!   r   zViewGrpcProtobuf.__init__  s!    >\Fr    c                .   g }|s|S t        |t        j                        }|D ]o  }|rt        |t        j                        r |st        |t        j
                        r=t        j                  |j                  |      s_|j                  |       q |S )a,  
        Checks which of the give rules applies and returns a List only containing those rules

        Each rule defines a flow filter in rule.filter which is usually matched against a flow.
        When it comes to protobuf parsing, in most cases request messages differ from response messages.
        Thus, it has to be possible to apply a rule to a http.Request or a http.Response, only.

        As the name flowfilter suggests, filters are working on a flow-level, not on message-level.
        This means:

        - the filter expression '~q' matches all flows with a request, but no response
        - the filter expression '~s' matches all flows with a response

        In result, for complete flows (with a gRPC message in the request and the response), ParserRules would
        either be applied to request and response at the same time ('~s') or neither would match request, nor
        response (~q).

        To distinguish between rules which should be applied to response messages, request messages or both
        (while being applied to the whole flow), different classes with same behavior are used to wrap rules:

            - ParserRule: applies to requests and responses
            - ParserRuleRequest: applies to requests only
            - ParserRuleResponse: applies to responses only
        r   )
r   r   Requestr   r&   r*   r   r   r   r   )r   r   r^   r   rg   
is_requestr   s          r!   _matching_rulesz ViewGrpcProtobuf._matching_rules  s    < -/J6
 	!Dj{/M/MNJt[5R5R$S$7

4 	! 
r    )content_typer   http_messagec                  | j                  | j                  j                  ||      }|| j                  v rY	 |J |j                  d   }|| j
                  v r|n| j
                  d   }t        || j                  j                  ||      }	d}
n$t        || j                  j                  |      }	d}
	 t        |	      }	|
|	fS # t        $ r | j
                  d   }Y tw xY w# t        $ r}|d }~ww xY w)N)r   r   r^   zgrpc-encodingr   )rf   r   r  r   gRPCr  zProtobuf (flattened))r&  r!  r  %_ViewGrpcProtobuf__content_types_grpcheaders'_ViewGrpcProtobuf__valid_grpc_encodingsr   r  r   r  r  )r   rf   r'  r   r(  unknown_metadataapplicabble_ruleshgrpc_encoding	text_itertitler   s               r!   __call__zViewGrpcProtobuf.__call__  s&    !00++**| 1 
 4444	?#/// ((9 D777 44Q7  $#{{99#0'	I E##{{99'I
 +E	.y9I i9  ? $ ; ;A >?*  	
 G	s)   2C 5C" CC"	C2+C--C2c               l    t        |      r|| j                  v ryt        |      r|| j                  v ryy)Nr>   g      ?r   )r8   r+  #_ViewGrpcProtobuf__content_types_pb)r   rf   r'  r   r(  r.  s         r!   render_priorityz ViewGrpcProtobuf.render_priorityT  s5     :,$*C*CC:,$*A*AAr    r   )r!  zViewConfig | Noner   r   )r   r   r^   http.Message | Noner   flow.Flow | Noner   r   )
rf   r]   r'  r2   r   r9  r(  r8  r   zcontentviews.TViewResult)
rf   r]   r'  r2   r   r9  r(  r8  r   rX   )r   r   r   r   r   r6  r+  r-  r   r&  r4  r7  __classcell__)r"  s   @r!   r  r    s    1!D 	 		+++ %+ 	+
 
&+b $(!%,0< <  !	< 
 <  *<  
"< D $(!%,0 !	
  * 
r    r  )d   )r   zIterable[tuple[str, ...]]r   zIterator[base.TViewLine])r   z)Generator[tuple[bool, bytes], None, None])r^   r]   r   r7   r   r   )r  )rf   r]   r   r7   r   r   )
__future__r   r   rm   collections.abcr   r   r   dataclassesr   r   rU   r	   	mitmproxyr
   r   r   r   mitmproxy.contentviewsr   mitmproxy.net.encodingr   r   r  r  r  r  r  r  Viewr  r   r    r!   <module>rC     s    "   % $ $ !   "     ' )f) f)\ ) D"."p 		-	 (	  	


-
 (
0 M M MYtyy Yr    