
     i*                     b    S r SSKJrJr  SSKJr  SSKJr   " S S\5      r " S S	5      r	S	S/r
g
)zd
HTTP/2 stream state management.

Each HTTP/2 stream represents a single request/response exchange.
    )Enumauto)BytesIO   )HTTP2StreamErrorc                   z    \ rS rSrSr\" 5       r\" 5       r\" 5       r\" 5       r	\" 5       r
\" 5       r\" 5       rSrg)StreamState   z8HTTP/2 stream states as defined in RFC 7540 Section 5.1. N)__name__
__module____qualname____firstlineno____doc__r   IDLERESERVED_LOCALRESERVED_REMOTEOPENHALF_CLOSED_LOCALHALF_CLOSED_REMOTECLOSED__static_attributes__r       G/var/www/ias/venv/lib/python3.13/site-packages/gunicorn/http2/stream.pyr	   r	      s8    B6DVNfO6DVFr   r	   c                       \ rS rSrSrS r\S 5       r\S 5       r\S 5       r	\S 5       r
SS jrSS	 jrS
 rSS jrSS jrS rSS jrS rSS jrS rS rS rS rS rS rS rSrg)HTTP2Stream   zRepresents a single HTTP/2 stream.

Manages stream state, headers, and body data for a single
request/response exchange within an HTTP/2 connection.
c                 <   Xl         X l        [        R                  U l        / U l        [        5       U l        SU l        SU l	        SU l
        SU l        UR                  U l        SU l        SU l        SU l        SU l        SU l        / U l        SU l        SU l        g)zInitialize an HTTP/2 stream.

Args:
    stream_id: The unique stream identifier (odd for client-initiated)
    connection: The parent HTTP2ServerConnection
FN   r   )	stream_id
connectionr	   r   staterequest_headersr   request_bodyrequest_completeresponse_startedresponse_headers_sentresponse_completeinitial_window_sizewindow_sizetrailersresponse_trailerspriority_weightpriority_depends_onpriority_exclusive_body_chunks_body_event_body_complete)selfr    r!   s      r   __init__HTTP2Stream.__init__%   s     #$ !%%
  "#I % !&%*"!& &99  "&  "#$ "' #r   c                 &    U R                   S-  S:H  $ )z;Check if this is a client-initiated stream (odd stream ID).   r   r    r3   s    r   is_client_streamHTTP2Stream.is_client_streamO        ~~!Q&&r   c                 &    U R                   S-  S:H  $ )z<Check if this is a server-initiated stream (even stream ID).r7   r   r8   r9   s    r   is_server_streamHTTP2Stream.is_server_streamT   r<   r   c                 \    U R                   [        R                  [        R                  4;   $ )z&Check if this stream can receive data.)r"   r	   r   r   r9   s    r   can_receiveHTTP2Stream.can_receiveY   s,     zz))
 
 	
r   c                 \    U R                   [        R                  [        R                  4;   $ )z#Check if this stream can send data.)r"   r	   r   r   r9   s    r   can_sendHTTP2Stream.can_senda   s,     zz**
 
 	
r   c                    U R                   [        R                  :X  a  [        R                  U l         O[U R                   [        R                  [        R                  4;  a-  [        U R                  SU R                   R                   35      eU R                  R                  U5        U(       a  U R                  5         SU l        gg)zProcess received HEADERS frame.

Args:
    headers: List of (name, value) tuples
    end_stream: True if END_STREAM flag is set

Raises:
    HTTP2StreamError: If headers received in invalid state
z Cannot receive headers in state TN)r"   r	   r   r   r   r   r    namer#   extend_half_close_remoter%   r3   headers
end_streams      r   receive_headersHTTP2Stream.receive_headersi   s     ::)))$))DJZZ 0 0+2O2OPP"24::??2CD 
 	##G,##%$(D! r   c                    U R                   (       d-  [        U R                  SU R                  R                   35      eU(       aF  U R
                  R                  U5        U R                  (       a  U R                  R                  5         U R                  R                  U5        U(       aK  U R                  5         SU l        SU l        U R                  (       a  U R                  R                  5         ggg)zProcess received DATA frame with streaming support.

Args:
    data: Bytes received
    end_stream: True if END_STREAM flag is set

Raises:
    HTTP2StreamError: If data received in invalid state
zCannot receive data in state TN)rA   r   r    r"   rG   r0   appendr1   setr$   writerI   r%   r2   r3   datarL   s      r   receive_dataHTTP2Stream.receive_data   s     "/

/@A  $$T*  $$& 	%##%$(D!"&D  $$&  	 r   c                     U R                   (       d-  [        U R                  SU R                  R                   35      eXl        U R                  5         SU l        g)zUProcess received trailing headers.

Args:
    trailers: List of (name, value) tuples
z!Cannot receive trailers in state TN)rA   r   r    r"   rG   r+   rI   r%   r3   r+   s     r   receive_trailersHTTP2Stream.receive_trailers   sO     "3DJJOO3DE 
 !! $r   c                     U R                   (       d-  [        U R                  SU R                  R                   35      eSU l        SU l        U(       a  U R                  5         SU l        gg)zMark headers as sent.

Args:
    headers: List of (name, value) tuples to send
    end_stream: True if this completes the response

Raises:
    HTTP2StreamError: If headers cannot be sent in current state
zCannot send headers in state TN)	rD   r   r    r"   rG   r&   r'   _half_close_localr(   rJ   s      r   send_headersHTTP2Stream.send_headers   s`     }}"/

/@A 
 !%%)"""$%)D" r   c                     U R                   (       d-  [        U R                  SU R                  R                   35      eU(       a  U R                  5         SU l        gg)zMark data as sent.

Args:
    data: Bytes to send
    end_stream: True if this completes the response

Raises:
    HTTP2StreamError: If data cannot be sent in current state
zCannot send data in state TN)rD   r   r    r"   rG   r\   r(   rS   s      r   	send_dataHTTP2Stream.send_data   sP     }}",TZZ__,=> 
 ""$%)D" r   c                     U R                   (       d-  [        U R                  SU R                  R                   35      eXl        U R                  5         SU l        g)zMark trailers as sent and close the stream.

Args:
    trailers: List of (name, value) trailer tuples

Raises:
    HTTP2StreamError: If trailers cannot be sent in current state
zCannot send trailers in state TN)rD   r   r    r"   rG   r,   r\   r(   rX   s     r   send_trailersHTTP2Stream.send_trailers   sN     }}"00AB  "* !%r   c                 J    [         R                  U l        SU l        SU l        g)z^Reset this stream with RST_STREAM.

Args:
    error_code: HTTP/2 error code (default: CANCEL)
TNr	   r   r"   r(   r%   )r3   
error_codes     r   resetHTTP2Stream.reset   s!     !''
!% $r   c                 J    [         R                  U l        SU l        SU l        g)zClose this stream normally.TNrf   r9   s    r   closeHTTP2Stream.close   s     ''
!% $r   Nc                 f    Ub  [        S[        SU5      5      U l        Ub  X l        Ub  X0l        gg)zUpdate stream priority from PRIORITY frame.

Args:
    weight: Priority weight (1-256), higher = more resources
    depends_on: Stream ID this stream depends on
    exclusive: Whether this is an exclusive dependency
Nr      )maxminr-   r.   r/   )r3   weight
depends_on	exclusives       r   update_priorityHTTP2Stream.update_priority   s=     #&q#c6*:#;D !'1$ &/# !r   c                 ,   U R                   [        R                  :X  a  [        R                  U l         gU R                   [        R                  :X  a  [        R
                  U l         g[        U R                  SU R                   R                   35      e)z(Transition to half-closed (local) state.z!Cannot half-close local in state N)	r"   r	   r   r   r   r   r   r    rG   r9   s    r   r\   HTTP2Stream._half_close_local  sg    ::)))$66DJZZ;999$++DJ"3DJJOO3DE r   c                 ,   U R                   [        R                  :X  a  [        R                  U l         gU R                   [        R                  :X  a  [        R
                  U l         g[        U R                  SU R                   R                   35      e)z)Transition to half-closed (remote) state.z"Cannot half-close remote in state N)	r"   r	   r   r   r   r   r   r    rG   r9   s    r   rI   HTTP2Stream._half_close_remote  sg    ::)))$77DJZZ;888$++DJ"4TZZ__4EF r   c                 6    U R                   R                  5       $ )zJGet the complete request body.

Returns:
    bytes: The request body data
)r$   getvaluer9   s    r   get_request_bodyHTTP2Stream.get_request_body%  s       ))++r   c                   #    SSK nU R                  cQ  UR                  5       U l        U R                  (       d  U R                  (       a  U R                  R                  5          U R                  (       a  U R                  R                  S5      $ U R                  (       a  gU R                  R                  5         U R                  R                  5       I Sh  vN   M|   N7f)z~Read next body chunk asynchronously for streaming.

Returns:
    bytes: Next chunk of body data, or None if body is complete.
r   N)	asyncior1   Eventr0   r2   rQ   popclearwait)r3   r   s     r   read_body_chunkHTTP2Stream.read_body_chunk-  s      	 #&}}D   D$7$7  $$&  ((,,Q// "" ""$""'')))  *s   CC$C"C$c                 l    0 nU R                    H!  u  p#UR                  S5      (       d  M  X1U'   M#     U$ )zExtract HTTP/2 pseudo-headers from request headers.

Returns:
    dict: Mapping of pseudo-header names to values
          (e.g., {':method': 'GET', ':path': '/'})
:r#   
startswith)r3   pseudorG   values       r   get_pseudo_headersHTTP2Stream.get_pseudo_headersJ  s8     //KDs##$t 0 r   c                     U R                    VVs/ s H   u  pUR                  S5      (       a  M  X4PM"     snn$ s  snnf )ztGet regular (non-pseudo) headers from request.

Returns:
    list: List of (name, value) tuples for regular headers
r   r   )r3   rG   r   s      r   get_regular_headersHTTP2Stream.get_regular_headersW  sA      $33
3??3' TM3
 	
 
s   ;;c           	          SU R                    SU R                  R                   SU R                   SU R                   S3	$ )Nz<HTTP2Stream id=z state=z req_complete=z resp_complete=>)r    r"   rG   r%   r(   r9   s    r   __repr__HTTP2Stream.__repr__c  sO    t~~. /ZZ__% & 112 3!334A7	
r   )r0   r2   r1   r!   r.   r/   r-   r$   r%   r#   r(   r'   r&   r,   r"   r    r+   r*   )F)   )NNN)r   r   r   r   r   r4   propertyr:   r>   rA   rD   rM   rU   rY   r]   r`   rc   rh   rk   rt   r\   rI   r|   r   r   r   r   r   r   r   r   r   r      s    ($T ' ' ' ' 
 
 
 
)0'@% *.*(&$%%0

,*:


r   r   N)r   enumr   r   ior   errorsr   r	   r   __all__r   r   r   <module>r      s:      $	$ 	K
 K
\
 -
(r   