
     iP                     x    S r SSK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)
z
Async HTTP/2 server connection implementation for ASGI workers.

Uses the hyper-h2 library for HTTP/2 protocol handling with
asyncio for non-blocking I/O.
    N   )
HTTP2ErrorHTTP2ProtocolErrorHTTP2ConnectionErrorHTTP2NotAvailableHTTP2ErrorCode)HTTP2Stream)HTTP2Requestc                      [         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        Q/var/www/ias/venv/lib/python3.13/site-packages/gunicorn/http2/async_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)!AsyncHTTP2Connection0   zAsync HTTP/2 server-side connection handler for ASGI.

Manages the HTTP/2 connection state and multiplexed streams
using asyncio for non-blocking I/O operations.
i   c                    [        5         Xl        X l        X0l        X@l        0 U l        [        R                  " 5       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        SU l        SU l        SU l        g)a  Initialize an async HTTP/2 server connection.

Args:
    cfg: Gunicorn configuration object
    reader: asyncio StreamReader
    writer: asyncio StreamWriter
    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readerwriterclient_addrstreamsasyncioQueue_request_queue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_conn_closed_initialized_receive_task)selfr&   r'   r(   r)   r   s         r   __init__AsyncHTTP2Connection.__init__:   s     	&  &mmo $'#@#@ &)&F&F#!66$'$B$B! ++# , 
 ''v'6 !!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       I Sh  vN   SU l         g N7f)z|Send initial HTTP/2 settings to client.

Should be called after the SSL handshake completes and
before processing any data.
NT)r:   r8   update_settingsr   SettingCodesMAX_CONCURRENT_STREAMSr1   INITIAL_WINDOW_SIZEr/   MAX_FRAME_SIZEr3   MAX_HEADER_LIST_SIZEr5   initiate_connection_send_pending_datar<   s    r   rF   (AsyncHTTP2Connection.initiate_connectione   s       	$$%%<<d>Y>Y%%994;S;S%%44d6I6I%%::D<U<U	&
 	 	((*%%'''  	(s   C+C<-C:.C<Nc                   #     UbA  [         R                  " U R                  R                  U R                  5      US9I Sh  vN nO.U R                  R                  U R                  5      I Sh  vN n U(       d	  SU l        / $  U R                  R                  U5      n/ nU H*  nU R5                  U5      nUc  M  UR7                  U5        M,     U R9                  5       I Sh  vN   U$  N N! [
        [        4 a  n[        SU 35      eSnAff = f! [        R                   a?  nU R                  [        R                  S9I Sh  vN    [!        [#        U5      5      eSnAf[        R$                   a?  nU R                  [        R&                  S9I Sh  vN    [!        [#        U5      5      eSnAf[        R(                   ah  n[+        USS5      nUb  U R                  US9I Sh  vN    O&U R                  [        R,                  S9I Sh  vN    [!        [#        U5      5      eSnAf[        R.                   a?  nU R                  [        R0                  S9I Sh  vN    [!        [#        U5      5      eSnAf[        R2                   a?  nU R                  [        R,                  S9I Sh  vN    [!        [#        U5      5      eSnAff = f GN7f)a(  Receive data and return completed requests.

Args:
    timeout: Optional timeout in seconds for read operation

Returns:
    list: List of HTTP2Request objects for completed requests

Raises:
    HTTP2ConnectionError: On protocol or connection errors
    asyncio.TimeoutError: If timeout expires
NtimeoutzSocket read error: T
error_coderN   )r+   wait_forr'   readREAD_BUFFER_SIZEOSErrorIOErrorr   r9   r8   receive_datar   FlowControlErrorcloser   FLOW_CONTROL_ERRORr   strFrameTooLargeErrorFRAME_SIZE_ERRORInvalidSettingsValueErrorgetattrPROTOCOL_ERRORTooManyStreamsErrorREFUSED_STREAMProtocolError_handle_eventappendrG   )	r<   rL   dataer   rN   completed_requestseventrequests	            r   rT   !AsyncHTTP2Connection.receive_dataz   s_    		B"$--KK$$T%:%:;# 
 "[[--d.C.CDD DLI	-\\..t4F:  E((/G""))'2  %%'''!!o
 E! 	B&)<QC'@AA	B .. 	-**(I(I*JJJ$SV,,00 	-**(G(G*HHH$SV,,77 		- !L$7J%jjJj777jjN,I,IjJJJ$SV,,11 	-**(E(E*FFF$SV,,++ 	-**(E(E*FFF$SV,,	- 	(s  K>C2 C.C2 K(C2 0C01C2 5KD "K?(K'K(K.C2 0C2 2DDDKK, E&EE&&K= F7F F77K"H10G31&H1HH11K J(I+)JK K9J<:KKK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<   rf   s     r   ra   "AsyncHTTP2Connection._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)z-Handle RequestReceived event (HEADERS frame).F
end_streamN)	stream_idheadersr	   r*   receive_headers)r<   rf   r   r   streams        r   rl   -AsyncHTTP2Connection._handle_request_received   sA    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:  aH   U R                  R                  [        U5      US9  U R                  R                  [        U5      SS9  gg! [        [        R                  4 aC    SU l         U R                  R                  [        R                  S9   g! [         a      gf = ff = f)zHandle DataReceived event.NFr~   r   )r   TrM   )r   rc   r*   getrT   lenr8   increment_flow_control_window
ValueErrorr   rU   r9   close_connectionr   rW   	Exception)r<   rf   r   rc   r   s        r   rn   *AsyncHTTP2Connection._handle_data_received   s    OO	zz!!),>DU3 t9q=::3t9PY:Z::3t9PT:U   ? ?@   $LL11^=^=^1_  ! s+   AB   !C='C++
C95C=8C99C=c                     UR                   nU R                  R                  U5      nUc  gSUl        [	        X0R
                  U R                  5      $ )zHandle StreamEnded event.NT)r   r*   r   request_completer
   r&   r)   r<   rf   r   r   s       r   rp   )AsyncHTTP2Connection._handle_stream_ended  sF    OO	!!),>"&FHHd.>.>??r   c                     UR                   nU R                  R                  U5      nUb  UR                  UR                  5        gg)zHandle StreamReset event.N)r   r*   r   resetrN   r   s       r   rr   )AsyncHTTP2Connection._handle_stream_reset  s<    OO	!!),LL))* r   c                     SU l         g)z"Handle ConnectionTerminated event.TNr9   r{   s     r   rx   2AsyncHTTP2Connection._handle_connection_terminated$  s	    r   c                     UR                   nU R                  R                  U5      nUc  gUR                  UR                  5        [        X0R                  U R                  5      $ )zHandle TrailersReceived event.N)r   r*   r   receive_trailersr   r
   r&   r)   r   s       r   rz   .AsyncHTTP2Connection._handle_trailers_received(  sP    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<   rf   r   s      r   ru   -AsyncHTTP2Connection._handle_priority_updated3  sQ     !!%//2""|| ++// #  r   c                   #    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       I Sh  vN   g N7f)
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:statusFr~   )	r   r*   r   rX   rb   lowerr8   send_headersrG   )r<   r   statusr   r   response_headersnamevalues           r   send_informational'AsyncHTTP2Connection.send_informationalA  s      C<6S==fXFGG!!),>wyk<== 'F45"KD##TZZ\3u:$>? #
 	!!)%!P%%'''s   B8C:C ;Cc                 `  #    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       I Sh  vN   U(       a'  [        U5      S:  a  U R                  XSS9I Sh  vN   g N3 N! [        R                   a$    UR                  5         U R                  U5         gf = f7f)a  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

Returns:
    bool: True if response sent, False if stream was already closed
NFr   r   r~   T)r*   r   rX   rb   r   r   r8   r   rG   	send_datar   StreamClosedErrorrV   cleanup_stream)
r<   r   r   r   bodyr   r   r   r   r   s
             r   send_response"AsyncHTTP2Connection.send_responsea  s     !!),> 'F45"KD##TZZ\3u:$>? # T\3SY!^
	LL%%ij%Y 0H))+++ D	AnnYnFFF , G// 	LLN	*		sN   A<D.?<C3 ;C/<-C3 )C1*C3 .D./C3 1C3 35D+(D.*D++D.c                   #    Sn[        U5       GH  nU R                  R                  U5      nUS:  a  Us  $  [        R                  " U R
                  R                  U R                  5      SS9I Sh  vN nU(       a  U R                  R                  U5      nU H`  n[        U[        R                  5      (       a  UR                  U:X  a      gM7  [        U[        R                  5      (       d  MX  SU l            g   U R                  5       I Sh  vN   GM  SU l          g   U R                  R                  U5      $  N N/! [        R                    a     GMO  ["        R$                   a       gf = f7f)zsWait for flow control window to become positive.

Returns:
    int: Available window size, or -1 if waiting failed
2   r   g?rK   NT)ranger8   local_flow_control_windowr+   rO   r'   rP   rQ   rT   rj   r   rq   r   rw   r9   rG   TimeoutErrorr   r`   )r<   r   max_wait_attempts_	availableincomingr   rf   s           r   _wait_for_flow_control_window2AsyncHTTP2Connection._wait_for_flow_control_window  sE     ()A>>yII1}  !(!1!1KK$$T%:%:;"  !\\66x@F!'%eZ-C-CDD$);')  <'z/N/NOO+/DL#% "( 11333 $(DL3 *> ||55i@@1 4
 '' !// s   7E9;E5E6AEE9E6E>E9 EEEE9E$E9EEE6E9E62E95E66E9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::  aW  U R                  5       I Sh  vN   U R                  U5      I Sh  vN 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       I Sh  vN   U(       a  M  UR                  X#S9  g N N N!! [        R                  [        R                  4 a$    UR                  5         U R                  U5         gf = f7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   r~   T)r*   r   r8   r   minr3   r   rG   r   r   r   r   rU   rV   r   )
r<   r   rc   r   r   data_to_sendr   
chunk_sizechunkis_finals
             r   r   AsyncHTTP2Connection.send_data  s`     !!),>	 LLBB9M	 ,?,?\ARS
?11333&*&H&H&S SI A~$!$Y0C0CSEV!WJ$[j1+K8%@#l*;q*@&&yH&M--///# ,& T9 4 S 0 00.2Q2QR 	LLN	*	ss   "E?AD4 ?D. D4 D0
D4 #E?$A,D4 D2D4 D4 -E?.D4 0D4 2D4 4AE<9E?;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       I Sh  vN   g N! [        R                   a$    UR                  5         U R                  U5         gf = f7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
NF:zPseudo-header 'z' not allowed in trailersTr~   )r*   r   response_headers_sentr   
startswithr   rb   rX   r8   r   send_trailersrG   r   r   rV   r   )r<   r   trailersr   trailer_headersr   r   lnames           r   r   "AsyncHTTP2Connection.send_trailers  s       !!),>++ #KDJJLE$$ ?4&8Q!RSS""E3u:#67	 $
	LL%%iT%R  1))+++ ,// 	LLN	*		s<   BD>C CC DC 5DDD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      I Sh  vN   g N7f)z#Send an error response on a stream.r   zcontent-length)zcontent-typeztext/plain; charset=utf-8N)encoderX   r   rb   r   )r<   r   status_codemessager   r   s         r   
send_errorAsyncHTTP2Connection.send_error  sP     #*w~~$c#d)n56NNHI  GGGs   AA( A&!A(c                    #    U R                   R                  U5      nUb  UR                  U5        U R                  R	                  XS9  U R                  5       I Sh  vN   g N7f)zReset a stream with RST_STREAM.NrM   )r*   r   r   r8   reset_streamrG   )r<   r   rN   r   s       r   r   !AsyncHTTP2Connection.reset_stream  sR     !!),LL$!!)!C%%'''s   AA&A$A&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       I Sh  vN    U R                  R                  5         U R                  R                  5       I Sh  vN   g NB! [         a     NLf = f N! [         a     gf = f7f)z,Close the connection gracefully with GOAWAY.NTr   rM   )r9   r*   maxkeysr8   r   rG   r   r(   rV   wait_closed)r<   rN   last_stream_ids      r   rV   AsyncHTTP2Connection.close  s     <<!9=S!2!2!451N	LL))Z)@))+++	KK++))+++ , 		
 , 		sl   AC),C CC 7C ?C C C)C 
CC)CC)C 
C&#C)%C&&C)c                 *  #    U R                   R                  5       nU(       a?   U R                  R                  U5        U R                  R	                  5       I Sh  vN   gg N! [
        [        4 a  nSU l        [        SU 35      eSnAff = f7f)z,Send any pending data from h2 to the socket.NTzSocket write error: )	r8   r   r(   writedrainrR   rS   r9   r   )r<   rc   rd   s      r   rG   'AsyncHTTP2Connection._send_pending_data0  s     ||((*G!!$'kk'')))  *W% G#*-A!+EFFGs:   "B8A& A$A& "B$A& &B6BBBc                     U R                   $ )zCheck if connection is closed.r   rH   s    r   	is_closedAsyncHTTP2Connection.is_closed;  s     ||r   c                 <    U R                   R                  US5        g)z-Remove a stream after processing is complete.N)r*   pop)r<   r   s     r   r   #AsyncHTTP2Connection.cleanup_stream@  s    D)r   c                 N    S[        U R                  5       SU R                   S3$ )Nz<AsyncHTTP2Connection streams=z closed=>)r   r*   r9   rH   s    r   __repr__AsyncHTTP2Connection.__repr__D  s0    4<<() *ll^1&	
r   )r9   r:   r;   r-   r&   r)   r8   r/   r1   r3   r5   r'   r*   r(   )N)F)   )r   N)__name__
__module____qualname____firstlineno____doc__rQ   r=   rF   rT   ra   rl   rn   rp   rr   rx   rz   ru   r   r   r   r   r   r   r   rV   rG   propertyr   r   r   __static_attributes__r   r   r   r!   r!   0   s     )"V!*F"P$L
::	@+	@(@&P&AP)V*XH(,	G  *
r   r!   )r   r+   errorsr   r   r   r   r   r   r	   rg   r
   r   r   r   r   r   r   r!   __all__r   r   r   <module>r      sX        ! 

""Y
 Y
x "
"r   