
    'Xh                    h    d Z ddlmZ ddlmZmZ ddlmZmZm	Z	m
Z
 ddlmZmZmZ dZ G d d	      Zy
)zy
h2/frame_buffer
~~~~~~~~~~~~~~~

A data structure that provides a way to iterate over a byte buffer in terms of
frames.
    )annotations)InvalidDataErrorInvalidFrameError)ContinuationFrameFrameHeadersFramePushPromiseFrame   )FrameDataMissingErrorFrameTooLargeErrorProtocolError@   c                  B    e Zd ZdZd	d
dZddZddZddZddZddZ	y)FrameBufferza
    A buffer data structure for HTTP/2 data that allows iteraton in terms of
    H2 frames.
    c                x    d| _         d| _        |rdnd| _        t        | j                        | _        g | _        y )N    r   s   PRI * HTTP/2.0

SM

)datamax_frame_size	_preamblelen_preamble_len_headers_buffer)selfservers     9/RAG/venv/lib/python3.12/site-packages/h2/frame_buffer.py__init__zFrameBuffer.__init__    s6    	@F<C 0Z\r   c                (   | j                   rqt        |      }t        | j                   |      }| j                  d| |d| k7  rd}t	        |      ||d }| xj                   |z  c_         | j                  |d | _        | xj
                  |z  c_        y)zs
        Add more data to the frame buffer.

        :param data: A bytestring containing the byte buffer.
        NzInvalid HTTP/2 preamble.)r   r   minr   r   r   )r   r   data_lenof_which_preamblemsgs        r   add_datazFrameBuffer.add_data'   s     4yH #D$6$6 A~~001T:L;L5MM0#C(()*+D"33!^^,=,>?DN		T	r   c                \    || j                   kD  rd| d| j                    }t        |      y)zB
        Confirm that the frame is an appropriate length.
        z Received overlong frame: length z, max N)r   r   )r   lengthr!   s      r   _validate_frame_lengthz"FrameBuffer._validate_frame_length;   s;     D'''4VHF4CVCVBWXC$S)) (r   c                   | j                   r| j                   d   j                  }|duxr! t        |t              xr |j                  |k(  }|sd}t	        |      t        |t              sJ | j                   j                  |       t        | j                         t        kD  rd}t	        |      d|j                  v rZ| j                   d   }|j                  j                  d       dj                  d | j                   D              |_        g | _         |S d}|S t        |t        t        f      r+d|j                  vr| j                   j                  |       d}|S )z
        Updates the internal header buffer. Returns a frame that should replace
        the current one. May throw exceptions if this frame is invalid.
        r   Nz"Invalid frame during header block.z&Too many continuation frames received.END_HEADERSr   c              3  4   K   | ]  }|j                     y wN)r   ).0xs     r   	<genexpr>z4FrameBuffer._update_header_buffer.<locals>.<genexpr>f   s     !G2FQ!&&2Fs   )r   	stream_id
isinstancer   r   appendr   CONTINUATION_BACKLOGflagsaddjoinr   r   r	   )r   fr-   valid_framer!   s        r   _update_header_bufferz!FrameBuffer._update_header_bufferC   sU    ,,Q/99I )1/0)y( 
 :#C((a!2333   ''*4''(+??>#C(( '((+M*!G$2F2F!GG')$    \+;<=QWW,   ''*Ar   c                    | S r)    )r   s    r   __iter__zFrameBuffer.__iter__t   s    r   c                   t        | j                        dk  rt        	 t        j                  t        | j                  d d             \  }}t        | j                        |dz   k  rt        | j                  |       	 |j                  t        | j                  dd|z                 | j                  d|z   d  | _        | j                  |      }||S | j                         S # t        t        f$ r}d|}t        |      |d }~ww xY w# t        $ r}d}t        |      |d }~wt        $ r}d}t        |      |d }~ww xY w)N	   z$Received frame with invalid header: z&Received frame with non-compliant datazFrame data missing or invalid)r   r   StopIterationr   parse_frame_header
memoryviewr   r   r   r%   
parse_bodyr   r6   __next__)r   r4   r$   errr!   	new_frames         r   r@   zFrameBuffer.__next__w   sE    tyy>A	.00DIIbqM1JKIAv tyy>FQJ& 	##F+	6LLDIIa&$9:; IIahi(	 ..q1	 &1yFt}}FE !"34 	.8@C$#-	.   	.:C$#-  	61C',#5	6s;   .C' *D 'D6DD	ED&&E2E  EN)F)r   boolreturnNone)r   bytesrD   rE   )r$   intrD   rE   )r4   Frame | NonerD   rH   )rD   r   )rD   r   )
__name__
__module____qualname____doc__r   r"   r%   r6   r9   r@   r8   r   r   r   r      s(    
](*.b*Gr   r   N)rL   
__future__r   hyperframe.exceptionsr   r   hyperframe.framer   r   r   r	   
exceptionsr   r   r   r0   r   r8   r   r   <module>rQ      s4    # E U U P P  GG GGr   