
     i1W                     |    S r SSKJr  SSKJrJrJrJrJr  SSK	J
r
  SSKJr  SqSqSqSqSqS r " S	 S
5      rS
/rg)zc
HTTP/2 server connection implementation.

Uses the hyper-h2 library for HTTP/2 protocol handling.
    )BytesIO   )
HTTP2ErrorHTTP2ProtocolErrorHTTP2ConnectionErrorHTTP2NotAvailableHTTP2ErrorCode)HTTP2Stream)HTTP2RequestNc                      [         b  g SSKJq   SSKJq  SSKJq  SSK	J
q  SSKJq  g! [         a    [!        5       ef = f)z$Lazily import h2 library components.Nr   )_h2h2.connection
connection	h2.configconfig
_h2_config	h2.eventsevents
_h2_eventsh2.exceptions
exceptions_h2_exceptionsh2.settingssettings_h2_settingsImportErrorr        K/var/www/ias/venv/lib/python3.13/site-packages/gunicorn/http2/connection.py
_import_h2r       s8     "#&&.* "!!"s   ) >c                       \ rS rSrSrSrS rS rSS jrS r	S	 r
S
 rS rS rS rS rS rS rSS jrS rSS jrS rSS jrSS jrS S jrS r\S 5       rS rS rSrg)!HTTP2ServerConnection/   zHTTP/2 server-side connection handler.

Manages the HTTP/2 connection state and multiplexed streams.
This class wraps the h2 library and provides a higher-level
interface for gunicorn workers.
i   c                 r   [        5         Xl        X l        X0l        0 U l        / U l        UR                  U l        UR                  U l	        UR                  U l        UR                  U l        [        R                  SSS9n[         R#                  US9U l        ['        5       U l        SU l        SU l        g)zInitialize an HTTP/2 server connection.

Args:
    cfg: Gunicorn configuration object
    sock: SSL socket with completed handshake
    client_addr: Client address tuple (host, port)

Raises:
    HTTP2NotAvailable: If h2 library is not installed
Fzutf-8)client_sideheader_encoding)r   N)r    cfgsockclient_addrstreams_pending_requestshttp2_initial_window_sizeinitial_window_sizehttp2_max_concurrent_streamsmax_concurrent_streamshttp2_max_frame_sizemax_frame_sizehttp2_max_header_list_sizemax_header_list_sizer   H2Configurationr   H2Connectionh2_connr   _read_buffer_closed_initialized)selfr'   r(   r)   r   s        r   __init__HTTP2ServerConnection.__init__:   s     		&  "$ $'#@#@ &)&F&F#!66$'$B$B! ++# , 
 ''v'6 $I !r   c           
         U R                   (       a  gU R                  R                  [        R                  R
                  U R                  [        R                  R                  U R                  [        R                  R                  U R                  [        R                  R                  U R                  05        U R                  R                  5         U R                  5         SU l         g)z|Send initial HTTP/2 settings to client.

Should be called after the SSL handshake completes and
before processing any data.
NT)r9   r6   update_settingsr   SettingCodesMAX_CONCURRENT_STREAMSr/   INITIAL_WINDOW_SIZEr-   MAX_FRAME_SIZEr1   MAX_HEADER_LIST_SIZEr3   initiate_connection_send_pending_datar:   s    r   rD   )HTTP2ServerConnection.initiate_connectione   s      	$$%%<<d>Y>Y%%994;S;S%%44d6I6I%%::D<U<U	&
 	 	((*! r   Nc                    Uc&   U R                   R                  U R                  5      nU(       d	  SU l        / $  U R                  R                  U5      n/ nU H*  nU R1                  U5      nUc  M  UR3                  U5        M,     U R5                  5         U$ ! [        [        4 a  n[        SU 35      eSnAff = f! [        R                   a6  nU R                  [        R                  S9  [        [        U5      5      eSnAf[        R                    a6  nU R                  [        R"                  S9  [        [        U5      5      eSnAf[        R$                   aV  n['        USS5      nUb  U R                  US9  OU R                  [        R(                  S9  [        [        U5      5      eSnAf[        R*                   a6  nU R                  [        R,                  S9  [        [        U5      5      eSnAf[        R.                   a6  nU R                  [        R(                  S9  [        [        U5      5      eSnAff = f)a	  Process received data and return completed requests.

Args:
    data: Optional bytes to process. If None, reads from socket.

Returns:
    list: List of HTTP2Request objects for completed requests

Raises:
    HTTP2ConnectionError: On protocol or connection errors
NzSocket read error: T
error_coderJ   )r(   recvREAD_BUFFER_SIZEOSErrorIOErrorr   r8   r6   receive_datar   FlowControlErrorcloser	   FLOW_CONTROL_ERRORr   strFrameTooLargeErrorFRAME_SIZE_ERRORInvalidSettingsValueErrorgetattrPROTOCOL_ERRORTooManyStreamsErrorREFUSED_STREAMProtocolError_handle_eventappendrE   )r:   dataer   rJ   completed_requestseventrequests           r   rO   "HTTP2ServerConnection.receive_dataz   s    <Fyy~~d&;&;< DLI	-\\..t4F:  E((/G""))'2  	!!!c W% F*-@+DEEF .. 	-JJ."C"CJD$SV,,00 	-JJ."A"AJB$SV,,77 		- !L$7J%

j
1

n&C&C
D$SV,,11 	-JJ."?"?J@$SV,,++ 	-JJ."?"?J@$SV,,	-s_   %B C  B=*B88B= I
1DI
1EI
$AF55I
1G==I
1II
c                 .   [        U[        R                  5      (       a  U R                  U5      $ [        U[        R                  5      (       a  U R                  U5      $ [        U[        R                  5      (       a  U R                  U5      $ [        U[        R                  5      (       a  U R                  U5        g[        U[        R                  5      (       a   g[        U[        R                  5      (       a  U R                  U5        g[        U[        R                  5      (       a   g[        U[        R                  5      (       a  U R                  U5        g[        U[        R                   5      (       a  U R#                  U5      $ g)zHandle a single h2 event.

Args:
    event: h2 event object

Returns:
    HTTP2Request if a request is complete, None otherwise
N)
isinstancer   RequestReceived_handle_request_receivedDataReceived_handle_data_receivedStreamEnded_handle_stream_endedStreamReset_handle_stream_resetWindowUpdatedPriorityUpdated_handle_priority_updatedSettingsAcknowledgedConnectionTerminated_handle_connection_terminatedTrailersReceived_handle_trailers_receivedr:   ra   s     r   r\   #HTTP2ServerConnection._handle_event   sI    eZ77880077z6677--e44z5566,,U33z5566%%e,"  z7788  z99::))%0  z>>??  z>>??..u5
  z::;;11%88r   c                     UR                   nUR                  n[        X 5      nX@R                  U'   UR	                  USS9  g)zcHandle RequestReceived event (HEADERS frame).

Args:
    event: RequestReceived event with headers
F
end_streamN)	stream_idheadersr
   r*   receive_headers)r:   ra   r{   r|   streams        r   rg   .HTTP2ServerConnection._handle_request_received   sC     OO	-- Y-"(Y 	w59r   c                    UR                   nUR                  nU R                  R                  U5      nUc  gUR	                  USS9  [        U5      S:  aX   U R                  R                  [        U5      US9  U R                  R                  [        U5      SS9  U R                  5         gg! [        [        R                  4 a     U R                  [        R                  S9   gf = f)zHandle DataReceived event.

Args:
    event: DataReceived event with body data

Returns:
    None (request completion handled by StreamEnded)
NFry   r   )r{   rI   )r{   r^   r*   getrO   lenr6   increment_flow_control_windowrE   
ValueErrorr   rP   rQ   r	   rR   )r:   ra   r{   r^   r~   s        r   ri   +HTTP2ServerConnection._handle_data_received   s     OO	zz!!),>DU3 t9q=	I::3t9PY:Z::3t9PT:U'')
 	  ? ?@ I

n&G&G
H	Is   AB0 07C*)C*c                     UR                   nU R                  R                  U5      nUc  gSUl        [	        X0R
                  U R                  5      $ )zsHandle StreamEnded event.

Args:
    event: StreamEnded event

Returns:
    HTTP2Request for the completed request
NT)r{   r*   r   request_completer   r'   r)   r:   ra   r{   r~   s       r   rk   *HTTP2ServerConnection._handle_stream_ended  sL     OO	!!),> #' FHHd.>.>??r   c                     UR                   nU R                  R                  U5      nUb  UR                  UR                  5        gg)zQHandle StreamReset event (RST_STREAM frame).

Args:
    event: StreamReset event
N)r{   r*   r   resetrJ   r   s       r   rm   *HTTP2ServerConnection._handle_stream_reset*  s>     OO	!!),LL))* r   c                     SU l         g)z_Handle ConnectionTerminated event (GOAWAY frame).

Args:
    event: ConnectionTerminated event
TNr8   rv   s     r   rs   3HTTP2ServerConnection._handle_connection_terminated7  s     r   c                     UR                   nU R                  R                  U5      nUc  gUR                  UR                  5        [        X0R                  U R                  5      $ )zHandle TrailersReceived event.

Args:
    event: TrailersReceived event with trailer headers

Returns:
    HTTP2Request if this completes the request
N)r{   r*   r   receive_trailersr|   r   r'   r)   r   s       r   ru   /HTTP2ServerConnection._handle_trailers_received@  sT     OO	!!),>. FHHd.>.>??r   c                     U R                   R                  UR                  5      nUb0  UR                  UR                  UR
                  UR                  S9  gg)zjHandle PriorityUpdated event (PRIORITY frame).

Args:
    event: PriorityUpdated event with priority info
N)weight
depends_on	exclusive)r*   r   r{   update_priorityr   r   r   )r:   ra   r~   s      r   rp   .HTTP2ServerConnection._handle_priority_updatedT  sQ     !!%//2""|| ++// #  r   c                 l   US:  d  US:  a  [        SU 35      eU R                  R                  U5      nUc  [        SU S35      eS[        U5      4/nU H/  u  pgUR	                  UR                  5       [        U5      45        M1     U R                  R                  XSS	9  U R                  5         g)
av  Send an informational response (1xx) on a stream.

This is used for 103 Early Hints and other 1xx responses.
Informational responses are sent before the final response
and do not end the stream.

Args:
    stream_id: The stream ID
    status: HTTP status code (100-199)
    headers: List of (name, value) header tuples

Raises:
    HTTP2Error: If status is not in 1xx range
d      zInvalid informational status: NzStream z
 not found:statusFry   )	r   r*   r   rS   r]   lowerr6   send_headersrE   )r:   r{   statusr|   r~   response_headersnamevalues           r   send_informational(HTTP2ServerConnection.send_informationalb  s     C<6S==fXFGG!!),>wyk<== 'F45"KD##TZZ\3u:$>? #
 	!!)%!P!r   c                 0   U R                   R                  U5      nUc  gS[        U5      4/nU H/  u  pxUR                  UR	                  5       [        U5      45        M1     USL =(       d    [        U5      S:H  n	 U R                  R                  XU	S9  UR                  XiS9  U R                  5         U(       a  [        U5      S:  a  U R                  XSS9  g! [        R                   a$    UR                  5         U R                  U5         gf = f)aY  Send a response on a stream.

Args:
    stream_id: The stream ID to respond on
    status: HTTP status code (int)
    headers: List of (name, value) header tuples
    body: Optional response body bytes

Raises:
    HTTP2Error: If stream not found or in invalid state

Returns:
    bool: True if response sent, False if stream was already closed
NFr   r   ry   T)r*   r   rS   r]   r   r   r6   r   rE   	send_datar   StreamClosedErrorrQ   cleanup_stream)
r:   r{   r   r|   bodyr~   r   r   r   rz   s
             r   send_response#HTTP2ServerConnection.send_response  s     !!),> 'F45"KD##TZZ\3u:$>? # T\3SY!^
	LL%%ij%Y 0H##% D	Ay4@// 	LLN	*		s   =AC 5DDc                    SSK nSn UR                  5       nUR                  U R                  UR                  5        Sn [        U5       GH  nU R                  R                  U5      nUS:  a  Un  GOUR                  SS9nU(       d  MB   U R                  R                  U R                  5      n	U	(       d	  SU l          O U R                  R%                  U	5      n
U
 Hb  n['        U[(        R*                  5      (       a  UR,                  U:X  a  Sn  OCM8  ['        U[(        R.                  5      (       d  MY  SU l        Sn  O   U R1                  5         GM    O   U R                  R                  U5      nUR3                  5         U$ ! [
        [        4 a     gf = f! [        [        [        R                   4 a       MK  f = f! [        R                    a       Mg  f = f! UR3                  5         f = f)zsWait for flow control window to become positive.

Returns:
    int: Available window size, or -1 if waiting failed
r   N2   g?)timeoutT)	selectorsDefaultSelectorregisterr(   
EVENT_READ	TypeErrorr   ranger6   local_flow_control_windowselectrK   rL   rM   rN   r   r[   r8   rO   re   r   rl   r{   rr   rE   rQ   )r:   r{   r   max_wait_attemptsselresult_	availablereadyincomingr   ra   s               r   _wait_for_flow_control_window3HTTP2ServerConnection._wait_for_flow_control_window  s    		++-CLLI$8$89
 %	,- LLBB9M	q=&F

3
/5#'99>>$2G2G#H $'+!%!:!:8!D "(%eZ-C-CDD$);)+ %  < (z/N/NOO+/DL%'F! "( //1 ? .D ??	JIIKY :& 		  $Wn.J.JK  *77 & IIKsm   6F A	G% %F"4G% G	 AG% ;?G% FF"GG% GG% 	G"G% !G""G% %G7c                    U R                   R                  U5      nUc  gUn U(       a  U R                  R                  U5      n[	        X`R
                  [        U5      5      nUS::  aG  U R                  5         U R                  U5      nUS::  a  g[	        X`R
                  [        U5      5      nUSU nXWS nU=(       a    [        U5      S:H  n	U R                  R                  XU	S9  U R                  5         U(       a  M  UR                  X#S9  g! [        R                  [        R                  4 a$    UR                  5         U R                  U5         gf = f)zSend data on a stream.

Args:
    stream_id: The stream ID
    data: Body data bytes
    end_stream: Whether this ends the stream

Returns:
    bool: True if data sent, False if stream was already closed
NFr   ry   T)r*   r   r6   r   minr1   r   rE   r   r   r   r   rP   rQ   r   )
r:   r{   r^   rz   r~   data_to_sendr   
chunk_sizechunkis_finals
             r   r   HTTP2ServerConnection.send_data  s@    !!),>	 LLBB9M	 ,?,?\ARS
?++- $ B B9 MI A~$!$Y0C0CSEV!WJ$[j1+K8%@#l*;q*@&&yH&M'')# ,& T900.2Q2QR 	LLN	*		s    A.D A0D D AEEc                    U R                   R                  U5      nUc  gUR                  (       d  g/ nU HV  u  pVUR                  5       nUR	                  S5      (       a  [        SU S35      eUR                  U[        U5      45        MX      U R                  R                  XSS9  UR                  U5        U R                  5         g! [        R                   a$    UR                  5         U R                  U5         gf = f)a  Send trailing headers on a stream.

Trailers are headers sent after the response body, commonly used
for gRPC status codes, checksums, and timing information.

Args:
    stream_id: The stream ID
    trailers: List of (name, value) trailer tuples

Raises:
    HTTP2Error: If stream not found, headers not sent, or pseudo-headers used

Returns:
    bool: True if trailers sent, False if stream was already closed
F:zPseudo-header 'z' not allowed in trailersTry   )r*   r   response_headers_sentr   
startswithr   r]   rS   r6   r   send_trailersrE   r   r   rQ   r   )r:   r{   trailersr~   trailer_headersr   r   lnames           r   r   #HTTP2ServerConnection.send_trailers  s      !!),>++ #KDJJLE$$ ?4&8Q!RSS""E3u:#67	 $
	LL%%iT%R  1##%// 	LLN	*		s   ;C 5DDc                     U(       a  UR                  5       OSnS[        [        U5      5      4/nU(       a  UR                  S5        U R	                  XXT5        g)zSend an error response on a stream.

Args:
    stream_id: The stream ID
    status_code: HTTP status code
    message: Optional error message body
r   zcontent-length)zcontent-typeztext/plain; charset=utf-8N)encoderS   r   r]   r   )r:   r{   status_codemessager   r|   s         r   
send_error HTTP2ServerConnection.send_error@  sI     $+w~~$c#d)n56NNHI97Ar   c                     U R                   R                  U5      nUb  UR                  U5        U R                  R	                  XS9  U R                  5         g)zReset a stream with RST_STREAM.

Args:
    stream_id: The stream ID to reset
    error_code: HTTP/2 error code (default: CANCEL)
NrI   )r*   r   r   r6   reset_streamrE   )r:   r{   rJ   r~   s       r   r   "HTTP2ServerConnection.reset_streamO  sK     !!),LL$!!)!C!r   c                    U R                   (       a  gSU l         Uc6  U R                  (       a#  [        U R                  R                  5       5      OSn U R                  R                  US9  U R                  5         g! [         a     gf = f)zClose the connection gracefully with GOAWAY.

Args:
    error_code: HTTP/2 error code (default: NO_ERROR)
    last_stream_id: Last processed stream ID (default: highest)
NTr   rI   )r8   r*   maxkeysr6   close_connectionrE   	Exception)r:   rJ   last_stream_ids      r   rQ   HTTP2ServerConnection.close]  sr     <<!9=S!2!2!451N	LL))Z)@##% 		s   )A> >
B
Bc                     U R                   R                  5       nU(       a   U R                  R                  U5        gg! [        [
        4 a  nSU l        [        SU 35      eSnAff = f)z,Send any pending data from h2 to the socket.TzSocket write error: N)r6   r   r(   sendallrM   rN   r8   r   )r:   r^   r_   s      r   rE   (HTTP2ServerConnection._send_pending_datas  sg    ||((*G		!!$'  W% G#*-A!+EFFGs   A   A*A%%A*c                     U R                   $ )zCheck if connection is closed.r   rF   s    r   	is_closedHTTP2ServerConnection.is_closed}  s     ||r   c                 <    U R                   R                  US5        g)z^Remove a stream after processing is complete.

Args:
    stream_id: The stream ID to clean up
N)r*   pop)r:   r{   s     r   r   $HTTP2ServerConnection.cleanup_stream  s     	D)r   c                 N    S[        U R                  5       SU R                   S3$ )Nz<HTTP2ServerConnection streams=z closed=>)r   r*   r8   rF   s    r   __repr__HTTP2ServerConnection.__repr__  s0    4<<() *ll^1&	
r   )r8   r9   r+   r7   r'   r)   r6   r-   r/   r1   r3   r(   r*   )N)F)   )r   N)__name__
__module____qualname____firstlineno____doc__rL   r;   rD   rO   r\   rg   ri   rk   rm   rs   ru   rp   r   r   r   r   r   r   r   rQ   rE   propertyr   r   r   __static_attributes__r   r   r   r"   r"   /   s     )"V!*@"D$L:" D@*
+@("@*X8t*X*XB",G  *
r   r"   )r   ior   errorsr   r   r   r   r	   r~   r
   rb   r   r   r   r   r   r   r    r"   __all__r   r   r   <module>r      sX        ! 

""`	
 `	
F #
#r   