
    AҐi1W                     |    d Z ddlmZ ddlmZmZmZmZmZ ddl	m
Z
 ddlmZ dadadadadad Z G d	 d
      Zd
gZy)zc
HTTP/2 server connection implementation.

Uses the hyper-h2 library for HTTP/2 protocol handling.
    )BytesIO   )
HTTP2ErrorHTTP2ProtocolErrorHTTP2ConnectionErrorHTTP2NotAvailableHTTP2ErrorCode)HTTP2Stream)HTTP2RequestNc                  ~    t         y	 ddlma  ddlma ddlma ddl	m
a ddlma y# t        $ r t!               w xY w)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        R/var/www/descvideos/venv/lib/python3.12/site-packages/gunicorn/http2/connection.py
_import_h2r       s8     "#&&.* "!!"s   ( <c                       e Zd ZdZdZd Zd ZddZd Zd Z	d	 Z
d
 Zd Zd Zd Zd Zd ZddZd ZddZd ZddZddZddZd Zed        Zd Zd Zy)HTTP2ServerConnectionzHTTP/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                    t                || _        || _        || _        i | _        g | _        |j                  | _        |j                  | _	        |j                  | _        |j                  | _        t        j                  dd      }t         j#                  |      | _        t'               | _        d| _        d| _        y)a.  Initialize 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__zHTTP2ServerConnection.__init__:   s     		&  "$ $'#@#@ &)&F&F#!66$'$B$B! ++# , 
 ''v'6 $I !r   c           
         | j                   ry| j                  j                  t        j                  j
                  | j                  t        j                  j                  | j                  t        j                  j                  | j                  t        j                  j                  | j                  i       | j                  j                          | j                          d| _         y)zSend initial HTTP/2 settings to client.

        Should be called after the SSL handshake completes and
        before processing any data.
        NT)r8   r5   update_settingsr   SettingCodesMAX_CONCURRENT_STREAMSr.   INITIAL_WINDOW_SIZEr,   MAX_FRAME_SIZEr0   MAX_HEADER_LIST_SIZEr2   initiate_connection_send_pending_datar9   s    r   rB   z)HTTP2ServerConnection.initiate_connectione   s      	$$%%<<d>Y>Y%%994;S;S%%44d6I6I%%::D<U<U	&
 	 	((*! r   Nc                    |&	 | j                   j                  | j                        }|s	d| _        g S 	 | j                  j                  |      }g }|D ]'  }| j1                  |      }||j3                  |       ) | j5                          |S # t        t        f$ r}t        d|       d}~ww xY w# t        j                  $ r9}| j                  t        j                         t        t        |            d}~wt        j                   $ r9}| j                  t        j"                         t        t        |            d}~wt        j$                  $ r[}t'        |dd      }|| j                  |       n | j                  t        j(                         t        t        |            d}~wt        j*                  $ r9}| j                  t        j,                         t        t        |            d}~wt        j.                  $ r9}| j                  t        j(                         t        t        |            d}~ww xY w)aA  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_coderG   )r'   recvREAD_BUFFER_SIZEOSErrorIOErrorr   r7   r5   receive_datar   FlowControlErrorcloser	   FLOW_CONTROL_ERRORr   strFrameTooLargeErrorFRAME_SIZE_ERRORInvalidSettingsValueErrorgetattrPROTOCOL_ERRORTooManyStreamsErrorREFUSED_STREAMProtocolError_handle_eventappendrC   )r9   dataer   rG   completed_requestseventrequests           r   rL   z"HTTP2ServerConnection.receive_dataz   s    <Fyy~~d&;&;< DLI	-\\..t4F:   	3E((/G""))'2	3 	!!!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 B5 B2B--B25I4C<<I4EIAF22I4G<<I4IIc                    t        |t        j                        r| j                  |      S t        |t        j                        r| j                  |      S t        |t        j                        r| j                  |      S t        |t        j                        r| j                  |       yt        |t        j                        r	 yt        |t        j                        r| j                  |       yt        |t        j                        r	 yt        |t        j                        r| j                  |       yt        |t        j                         r| j#                  |      S y)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r9   r^   s     r   rY   z#HTTP2ServerConnection._handle_event   s.    eZ7780077z667--e44z556,,U33z556%%e,"  z778  z99:))%0  z>>?  z>>?..u5
  z::;11%88r   c                     |j                   }|j                  }t        ||       }|| j                  |<   |j	                  |d       y)z{Handle RequestReceived event (HEADERS frame).

        Args:
            event: RequestReceived event with headers
        F
end_streamN)	stream_idheadersr
   r)   receive_headers)r9   r^   rv   rw   streams        r   rc   z.HTTP2ServerConnection._handle_request_received   sG     OO	-- Y-"(Y 	w59r   c                    |j                   }|j                  }| j                  j                  |      }|y|j	                  |d       t        |      dkD  r^	 | j                  j                  t        |      |       | j                  j                  t        |      d       | j                          yy# t        t        j                  f$ r# | j                  t        j                         Y yw xY w)zHandle DataReceived event.

        Args:
            event: DataReceived event with body data

        Returns:
            None (request completion handled by StreamEnded)
        NFrt   r   )rv   rF   )rv   r[   r)   getrL   lenr5   increment_flow_control_windowrC   
ValueErrorr   rM   rN   r	   rO   )r9   r^   rv   r[   ry   s        r   re   z+HTTP2ServerConnection._handle_data_received   s     OO	zz!!),>DU3 t9q=	I::3t9PY:Z::3t9PT:U'')
 	  ? ?@ I

n&G&G
H	Is   AB7 79C32C3c                     |j                   }| j                  j                  |      }|yd|_        t	        || j
                  | j                        S )zHandle StreamEnded event.

        Args:
            event: StreamEnded event

        Returns:
            HTTP2Request for the completed request
        NT)rv   r)   r{   request_completer   r&   r(   r9   r^   rv   ry   s       r   rg   z*HTTP2ServerConnection._handle_stream_ended  sN     OO	!!),> #' FDHHd.>.>??r   c                     |j                   }| j                  j                  |      }||j                  |j                         yy)ziHandle StreamReset event (RST_STREAM frame).

        Args:
            event: StreamReset event
        N)rv   r)   r{   resetrG   r   s       r   ri   z*HTTP2ServerConnection._handle_stream_reset*  s>     OO	!!),LL))* r   c                     d| _         y)zwHandle ConnectionTerminated event (GOAWAY frame).

        Args:
            event: ConnectionTerminated event
        TNr7   rr   s     r   ro   z3HTTP2ServerConnection._handle_connection_terminated7  s     r   c                     |j                   }| j                  j                  |      }|y|j                  |j                         t        || j                  | j                        S )zHandle TrailersReceived event.

        Args:
            event: TrailersReceived event with trailer headers

        Returns:
            HTTP2Request if this completes the request
        N)rv   r)   r{   receive_trailersrw   r   r&   r(   r   s       r   rq   z/HTTP2ServerConnection._handle_trailers_received@  sV     OO	!!),>. FDHHd.>.>??r   c                     | j                   j                  |j                        }|3|j                  |j                  |j
                  |j                         yy)zHandle PriorityUpdated event (PRIORITY frame).

        Args:
            event: PriorityUpdated event with priority info
        N)weight
depends_on	exclusive)r)   r{   rv   update_priorityr   r   r   )r9   r^   ry   s      r   rl   z.HTTP2ServerConnection._handle_priority_updatedT  sQ     !!%//2""|| ++// #  r   c                 l   |dk  s|dk\  rt        d|       | j                  j                  |      }|t        d| d      dt        |      fg}|D ]/  \  }}|j	                  |j                         t        |      f       1 | j                  j                  ||d	       | j                          y)
a  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:statusFrt   )	r   r)   r{   rP   rZ   lowerr5   send_headersrC   )r9   rv   statusrw   ry   response_headersnamevalues           r   send_informationalz(HTTP2ServerConnection.send_informationalb  s     C<6S==fXFGG!!),>wyk<== 'F45" 	@KD%##TZZ\3u:$>?	@
 	!!)-=%!P!r   c                 ,   | j                   j                  |      }|ydt        |      fg}|D ]/  \  }}|j                  |j	                         t        |      f       1 |du xs t        |      dk(  }		 | j                  j                  |||	       |j                  ||	       | j                          |r"t        |      dkD  r| j                  ||d       y# t        j                  $ r$ |j                          | j                  |       Y yw xY w)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

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

        Returns:
            bool: True if response sent, False if stream was already closed
        NFr   r   rt   T)r)   r{   rP   rZ   r   r|   r5   r   rC   	send_datar   StreamClosedErrorrN   cleanup_stream)
r9   rv   r   rw   bodyry   r   r   r   ru   s
             r   send_responsez#HTTP2ServerConnection.send_response  s    !!),> 'F45" 	@KD%##TZZ\3u:$>?	@ T\3SY!^
	LL%%i1Aj%Y 0ZH##% D	Ay$4@// 	LLN	*		s   6A%C 4DDc                    ddl }d}	 |j                         }|j                  | j                  |j                         d}	 t        |      D ]  }| j                  j                  |      }|dkD  r|} n|j                  d      }|s<	 | j                  j                  | j                        }	|	s	d| _         n	 | j                  j%                  |	      }
|
D ]U  }t'        |t(        j*                        r|j,                  |k(  s-d} n8t'        |t(        j.                        sLd| _        d} n | j1                           n | j                  j                  |      }|j3                          |S # t
        t        f$ r Y yw xY w# t        t        t        j                   f$ r Y  Hw xY w# t        j                   $ r Y  bw xY w# |j3                          w xY w)zWait 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~   ranger5   local_flow_control_windowselectrH   rI   rJ   rK   r   rX   r7   rL   ra   r   rh   rv   rn   rC   rN   )r9   rv   r   max_wait_attemptsselresult_	availablereadyincomingr   r^   s               r   _wait_for_flow_control_windowz3HTTP2ServerConnection._wait_for_flow_control_window  s    		++-CLLI$8$89
 %	,- "K LLBB9M	q=&F

3
/#'99>>$2G2G#H $'+!%!:!:8!D "( !%eZ-C-CD$);)+ %'z/N/NO+/DL%'F!! //1 ?"KD ??	JIIKY :& 		  $Wn.J.JK  *77 & IIKsr   6E0 AG 	%F.G :F*.G G #;G 0FFF'#G &F''G *G=G  GG Gc                    | j                   j                  |      }|y|}	 |r| j                  j                  |      }t	        || j
                  t        |            }|dk  rG| j                          | j                  |      }|dk  ryt	        || j
                  t        |            }|d| }||d }|xr t        |      dk(  }	| j                  j                  |||	       | j                          |r|j                  ||       y# t        j                  t        j                  f$ r$ |j                          | j                  |       Y yw xY w)a  Send 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   rt   T)r)   r{   r5   r   minr0   r|   rC   r   r   r   r   rM   rN   r   )
r9   rv   r[   ru   ry   data_to_sendr   
chunk_sizechunkis_finals
             r   r   zHTTP2ServerConnection.send_data  sH    !!),>	 LLBB9M	 D,?,?\ARS
?++- $ B B9 MI A~$!$Y0C0CSEV!WJ$[j1+JK8%@#l*;q*@&&y%H&M'')# & Tj900.2Q2QR 	LLN	*		s    A(D A,D 8D AEEc                    | j                   j                  |      }|y|j                  syg }|D ]Q  \  }}|j                         }|j	                  d      rt        d| d      |j                  |t        |      f       S 	 | j                  j                  ||d       |j                  |       | j                          y# t        j                  $ r$ |j                          | j                  |       Y yw xY w)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 trailersTrt   )r)   r{   response_headers_sentr   
startswithr   rZ   rP   r5   r   send_trailersrC   r   r   rN   r   )r9   rv   trailersry   trailer_headersr   r   lnames           r   r   z#HTTP2ServerConnection.send_trailers  s      !!),>++ # 	8KD%JJLE$ ?4&8Q!RSS""E3u:#67		8
	LL%%iT%R  1##%// 	LLN	*		s   ?C 4C<;C<c                     |r|j                         nd}dt        t        |            fg}|r|j                  d       | j	                  ||||       y)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)encoderP   r|   rZ   r   )r9   rv   status_codemessager   rw   s         r   
send_errorz HTTP2ServerConnection.send_error@  sM     $+w~~$c#d)n56NNHI9k7DAr   c                     | j                   j                  |      }||j                  |       | j                  j	                  ||       | j                          y)zReset a stream with RST_STREAM.

        Args:
            stream_id: The stream ID to reset
            error_code: HTTP/2 error code (default: CANCEL)
        NrF   )r)   r{   r   r5   reset_streamrC   )r9   rv   rG   ry   s       r   r   z"HTTP2ServerConnection.reset_streamO  sM     !!),LL$!!)
!C!r   c                 
   | j                   ryd| _         |1| j                  r#t        | j                  j                               nd}	 | j                  j                  |       | j                          y# t        $ r Y yw xY w)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   rF   )r7   r)   maxkeysr5   close_connectionrC   	Exception)r9   rG   last_stream_ids      r   rN   zHTTP2ServerConnection.close]  sr     <<!9=S!2!2!451N	LL))Z)@##% 		s   	,A6 6	BBc                     | j                   j                         }|r	 | j                  j                  |       yy# t        t
        f$ r}d| _        t        d|       d}~ww xY w)z,Send any pending data from h2 to the socket.TzSocket write error: N)r5   r   r'   sendallrJ   rK   r7   r   )r9   r[   r\   s      r   rC   z(HTTP2ServerConnection._send_pending_datas  sg    ||((*G		!!$'  W% G#*-A!+EFFGs   ; A$
AA$c                     | j                   S )zCheck if connection is closed.r   rD   s    r   	is_closedzHTTP2ServerConnection.is_closed}  s     ||r   c                 <    | j                   j                  |d       y)zvRemove a stream after processing is complete.

        Args:
            stream_id: The stream ID to clean up
        N)r)   pop)r9   rv   s     r   r   z$HTTP2ServerConnection.cleanup_stream  s     	D)r   c                 N    dt        | j                         d| j                   dS )Nz<HTTP2ServerConnection streams=z closed=>)r|   r)   r7   rD   s    r   __repr__zHTTP2ServerConnection.__repr__  s0    4<<() *ll^1&	
r   )N)F)   )r   N)__name__
__module____qualname____doc__rI   r:   rB   rL   rY   rc   re   rg   ri   ro   rq   rl   r   r   r   r   r   r   r   rN   rC   propertyr   r   r   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	   ry   r
   r_   r   r   r   r   r   r   r    r"   __all__r   r   r   <module>r      sX        ! 

""`	
 `	
F #
#r   