
     iq                        S r SSKrSSKrSSKrSSKrSSKJr  SSKJrJ	r	J
r
JrJrJr  SSKJr  SSKJr  SSKJr   " S S	5      rS
 rS r0 rSrSqSq\" S5       V s0 s H  o U S S3R9                  S5      _M     sn rSr " S S5      rS r S r! " S S5      r" " S S5      r# " S S\RH                  5      r%gs  sn f )z
ASGI protocol handler for gunicorn.

Implements asyncio.Protocol to handle HTTP/1.x and HTTP/2 connections
and dispatch to ASGI applications.
    N)AsyncUnreader)PythonProtocolCallbackRequest
ParseErrorLimitRequestLineLimitRequestHeadersInvalidChunkExtension)AsyncUWSGIRequest)
NoMoreData)UWSGIParseExceptionc                   "    \ rS rSrSrSrS rSrg)_RequestTime   zLightweight request time container compatible with logging atoms.

Uses time.monotonic() elapsed seconds instead of datetime.now() syscalls.
Provides .seconds and .microseconds attributes for glogging.py compatibility.
)secondsmicrosecondsc                 b    [        U5      U l        [        XR                  -
  S-  5      U l        g )Ni@B )intr   r   )selfelapseds     H/var/www/ias/venv/lib/python3.13/site-packages/gunicorn/asgi/protocol.py__init___RequestTime.__init__$   s&    7|<<!79 DE    )r   r   N)__name__
__module____qualname____firstlineno____doc__	__slots__r   __static_attributes__ r   r   r   r      s     ,IFr   r   c                 0    U (       a  [        U SS 5      $ S$ )zNormalize socket address to ASGI-compatible (host, port) tuple.

ASGI spec requires server/client to be (host, port) tuples.
IPv6 sockets return 4-tuples (host, port, flowinfo, scope_id),
so we extract just the first two elements.
N   )tuple)sockaddrs    r   _normalize_sockaddrr&   )   s     #+5"144r   c                     [        U [        5      (       d  gSU;   a  g [        R                  " U S   5      nU H
  nX4;   d  M
    g   g! [         a     gf = f)zzCheck if peer address is in the trusted proxy list.

Cached at connection start to avoid repeated IP parsing per request.
F*Tr   )
isinstancer$   	ipaddress
ip_address
ValueError)	peer_addr
allow_listnetworksipnetworks        r   _check_trusted_proxyr2   3   se    
 i''
j!!)A,/ =    s   A	 	
AAs   Server: gunicorn/asgi
r   g        i @  x
latin-1i   c                   @    \ rS rSrSrSrS rS rS rS r	S r
S	 rS
rg)FlowControlU   zManage transport-level write flow control.

Blocks send() when transport buffer exceeds high water mark,
preventing memory issues with large streaming responses.
)
_transportread_pausedwrite_paused_is_writable_eventc                     Xl         SU l        SU l        [        R                  " 5       U l        U R
                  R                  5         g NF)r9   r:   r;   asyncioEventr<   set)r   	transports     r   r   FlowControl.__init__]   s7    # !")--/##%r   c                 T   #    U R                   R                  5       I Sh  vN   g N7f)z!Wait until transport is writable.N)r<   waitr   s    r   drainFlowControl.draind   s     %%**,,,s   (&(c                 j    U R                   (       d"  SU l         U R                  R                  5         g g NT)r:   r9   pause_readingrF   s    r   rK   FlowControl.pause_readingh   s(    #DOO))+  r   c                 j    U R                   (       a"  SU l         U R                  R                  5         g g r>   )r:   r9   resume_readingrF   s    r   rN   FlowControl.resume_readingm   s(    $DOO**, r   c                 j    U R                   (       d"  SU l         U R                  R                  5         g g rJ   )r;   r<   clearrF   s    r   pause_writingFlowControl.pause_writingr   s*       $D##))+ !r   c                 j    U R                   (       a"  SU l         U R                  R                  5         g g r>   )r;   r<   rA   rF   s    r   resume_writingFlowControl.resume_writingw   s*     %D##'') r   )r<   r9   r:   r;   N)r   r   r   r   r   r   r   rG   rK   rN   rR   rU   r    r!   r   r   r7   r7   U   s-    
 TI&-,
-
,
*r   r7   c                      [         R                   " 5       n U [        -
  S:  a!  SSKJn  SU" SS9 S3R	                  S5      qU q[
        $ )	z1Get cached Date header, updating once per second.      ?r   )
formatdatezDate: T)usegmtr4   r5   )time_cached_date_timeemail.utilsrY   encode_cached_date_header)nowrY   s     r   _get_cached_date_headerra   }   sL     ))+C
#%* &z'>&?tDKKIVr   c           	          X4nU[         ;  a-  SU S    SU S    SU SU S3	nUR                  S5      [         U'   [         U   $ )zGet cached status line bytes.HTTP/r   .    r4   r5   )_CACHED_STATUS_LINESr^   )versionstatusreasonkeylines        r   _get_cached_status_linerm      sZ    
C
&&wqzl!GAJ<q&F$(KK	$:S!$$r   c                       \ rS rSrSrS rSrg)ASGIResponseInfo   z;Simple container for ASGI response info for access logging.c                    Xl         X0l        / U l        U Hm  u  pE[        U[        5      (       a  UR                  S5      n[        U[        5      (       a  UR                  S5      nU R                  R                  XE45        Mo     g )Nr5   )ri   sentheadersr)   bytesdecodeappend)r   ri   rs   rr   namevalues         r   r   ASGIResponseInfo.__init__   si    	"KD$&&{{9-%''Y/LL. #r   )rs   rr   ri   N)r   r   r   r   r   r   r    r!   r   r   ro   ro      s
    E
/r   ro   c                   R    \ rS rSrSrSrS rS rS rS r	S r
S	 rS
 rS rS rSrg)BodyReceiver   zBody receiver for callback-based parsers.

Body chunks are fed directly via the feed() method from parser callbacks.
Uses Future-based waiting for efficient async receive().
)_chunks	_complete_body_finished_closed_waiterrequestprotocolc                 b    Xl         X l        / U l        SU l        SU l        SU l        S U l        g r>   )r   r   r}   r~   r   r   r   )r   r   r   s      r   r   BodyReceiver.__init__   s0     #r   c                 j    U(       a,  U R                   R                  U5        U R                  5         gg)z7Feed a body chunk directly (called by parser callback).N)r}   rv   _wake_waiterr   chunks     r   feedBodyReceiver.feed   s(    LL& r   c                 2    SU l         U R                  5         g)z1Mark body as complete (called when message ends).TN)r~   r   rF   s    r   set_completeBodyReceiver.set_complete   s    r   c                 2    SU l         U R                  5         g)z%Signal that connection has been lost.TN)r   r   rF   s    r   signal_disconnectBodyReceiver.signal_disconnect   s    r   c                     U R                   b<  U R                   R                  5       (       d  U R                   R                  S5        ggg)z#Wake up any pending receive() call.N)r   done
set_resultrF   s    r   r   BodyReceiver._wake_waiter   s9    <<#DLL,=,=,?,?LL##D) -@#r   c                 D  #    U R                   (       d  U R                  (       a  SS0$ U R                  (       a  U R                  5       $ U R                  (       a  SU l        SSSS.$ U R
                  R                  S:X  a/  U R
                  R                  (       d  SU l        SU l        SSSS.$ U R                  R                   (       a  SU l         SS0$  U R                  5       I S	h  vN   U R                  5       $  N! [        R                   a    SS0s $ f = f7f)
z:ASGI receive callable - returns body chunks or disconnect.typehttp.disconnectThttp.requestr   Fr   body	more_bodyr   N)r   r   r}   
_pop_chunkr~   r   content_lengthchunkedr   _wait_for_data_build_receive_resultr?   CancelledErrorrF   s    r   receiveBodyReceiver.receive   s      <<4..-.. <<??$$ >>"&D*CeLL <<&&!+DLL4H4H!DN"&D*CeLL ==  DL-..	/%%'''--// (%% 	/-..	/s<   CD D +D ,D ?D  D DD DD c                     U R                   R                  S5      n[        U R                   5      =(       d    U R                  (       + nU(       d  SU l        SXS.$ )z/Pop a chunk and return the appropriate message.r   Tr   r   )r}   popboolr~   r   )r   r   mores      r   r   BodyReceiver._pop_chunk   sF      #DLL!7%7"&D&IIr   c                     U R                   (       a  SS0$ U R                  (       a  U R                  5       $ SU l        SSSS.$ )z,Build receive result after waiting for data.r   r   Tr   r   Fr   )r   r}   r   r   rF   s    r   r   "BodyReceiver._build_receive_result   s@    <<-..<<??$$ #&%HHr   c                 v  #    U R                   (       d"  U R                  (       d  U R                  (       a  g[        R                  " 5       nUR                  5       U l         [        R                  " U R                  SS9I Sh  vN   SU l        g N! [        R                   a     N f = f! SU l        f = f7f)z*Wait for body data to arrive via callback.N      >@timeout)	r}   r~   r   r?   get_event_loopcreate_futurer   wait_forTimeoutError)r   loops     r   r   BodyReceiver._wait_for_data   s     <<4>>T\\ %%'))+	 ""4<<>>>  DL	 ?## 		  DLsH   AB9""B BB 	B9B B*'B- )B**B- -	B66B9)r   r}   r   r~   r   r   r   N)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r   r   r{   r{      s>    (I 

*
/BJI r   r{   c                      \ rS rSrSrSrSrSrSrS r	S r
\S 5       rSrS	 rS
 rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS 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% r*S& r+S' r,S( r-S) r.S* r/S+ r0S,r1g).ASGIProtocoli  zHTTP/1.1 protocol handler for ASGI applications.

Handles connection lifecycle, request parsing, and ASGI app invocation.
Uses callback-based parsing (H1CProtocol/PythonProtocol) for efficient
incremental parsing in data_received().
NFc                 d   Xl         UR                  U l        UR                  U l        UR                  U l        S U l        S U l        S U l        S U l        SU l	        SU l
        S U l        S U l        SU l        SU l        S U l        S U l        S U l        S U l        SU l        S U l        S U l        g )Nr   Fi   )workercfglogasgiapprB   readerwriter_task	req_countr   _body_receiver_response_buffer_reading_paused_max_buffer_size_keepalive_handle_callback_parser_request_ready_current_request_is_ssl_flow_control
_websocket)r   r   s     r   r   ASGIProtocol.__init__   s    ::::;;
 " !%  % ) "& !%" $ " r   c                    Xl         U R                  =R                  S-  sl        UR                  S5      nU(       a{  [	        US5      (       aj  UR                  5       nUS:X  aT  [        R                  " 5       U l        U R                  R                  R                  U R                  X5      5      U l        gUSLU l        Xl        [        U5      U l        UR#                  [$        S9  [        R&                  " 5       U l        U R+                  5         U R                  R                  R                  U R-                  5       5      U l        g)z(Called when a connection is established.re   
ssl_objectselected_alpn_protocolh2N)high)rB   r   nr_connsget_extra_infohasattrr   r?   StreamReaderr   r   create_task_handle_http2_connectionr   r   r   r7   r   set_write_buffer_limitsHIGH_WATER_LIMITr@   r   _setup_callback_parser_handle_connection)r   rB   r   alpns       r   connection_madeASGIProtocol.connection_madeF  s   "! --l;
'*.FGG446Dt|%224![[--9911)H
  "- )3))/?)@ &mmo##%[[%%11$2I2I2KL
r   c                    U R                   cG   SSKnSSKJn  SU l         X l        [	        US5      U l        [        USS5      U l        U R                   $ U R                   $ ! [         a    SU l         SU l         U R                   $ f = f)z:Check if H1CProtocol is available (cached at class level).Nr   )H1CProtocolTr   r	   F)	_h1c_availablegunicorn_h1cr   _h1c_protocol_classr   _h1c_has_limitsgetattr_h1c_invalid_chunk_extensionImportError)clsr   r   s      r   _check_h1c_protocol_available*ASGIProtocol._check_h1c_protocol_availabled  s     %,#4%)"*5'&-l<N&O#3: "9440 !!!s!!!  ,%*"&+#!!!,s   :A! !BB)permit_obsolete_foldingstrip_header_spacesc                    [        U R                  SS5      n/ nU R                   H2  n[        U R                  US5      (       d  M!  UR                  U5        M4     US:X  a  [        nOUS:X  au  U R                  5       (       d  [        S5      e[        R                  (       d  [        S5      eU(       a  [        SS	R                  U5      -  5      e[        R                  nOHU R                  5       (       a-  [        R                  (       a  U(       d  [        R                  nO[        nU R                  R                  nUS
:X  a  U[        :w  a  SnU" U R                  U R                  U R                  UU R                  R                  U R                  R                   U R                  R"                  U R                  R$                  S9U l        g)a  Create callback parser based on http_parser setting.

Parser selection:
- auto: Use H1CProtocol if available (>= 0.4.1) and no incompatible flags, else PythonProtocol
- fast: Require H1CProtocol >= 0.4.1 (error if unavailable or incompatible flags)
- python: Use PythonProtocol only
http_parserautoFpythonfastz,gunicorn_h1c required for http_parser='fast'zigunicorn_h1c >= 0.4.1 required for http_parser='fast'. Please upgrade: pip install --upgrade gunicorn_h1czqhttp_parser='fast' is incompatible with compatibility flags: %s. Use http_parser='python' or disable these flags.z, r   i   )on_headers_completeon_bodyon_message_completelimit_request_linelimit_request_fieldslimit_request_field_size!permit_unconventional_http_method"permit_unconventional_http_versionN)r   r   _FAST_PARSER_INCOMPATIBLE_FLAGSrv   r   r   RuntimeErrorr   r   joinr   r   _on_headers_complete_on_body_on_message_completer   r   r   r   r   )r   parser_settingincompatibleflagparser_classr   s         r   r   #ASGIProtocol._setup_callback_parser~  s    !=&A 88Dtxxu--##D) 9 X%)Lv%5577"#QRR//"I  "Gii-. 
 (;;L2244 00+??- "XX88"|~'E!, !- $ 9 9MM $ 9 91!%!>!>%)XX%F%F.2hh.X.X/3xx/Z/Z	!
r   c                    [         R                  " U R                  U R                  S9U l        [        U R                  U 5      U l        U R                  (       a  U R                  R                  5         U R                  R                  S:H  $ )z'Callback: request headers are complete.)is_ssls   HEAD)
r   from_parserr   r   r   r{   r   r   rA   methodrF   s    r   r   !ASGIProtocol._on_headers_complete  ss     !0 ; ;!!$,,!

 +4+@+@$G ##% $$++w66r   c                 ^    U R                   (       a  U R                   R                  U5        gg)z#Callback: received body data chunk.N)r   r   r   s     r   r   ASGIProtocol._on_body  s$    $$U+ r   c                 \    U R                   (       a  U R                   R                  5         gg)z$Callback: request is fully received.N)r   r   rF   s    r   r   !ASGIProtocol._on_message_complete  s"    ,,. r   c                 6   U R                   (       a  U R                   R                  U5        gU R                  (       a  U R                  R                  U5        O-U R                  (       a   U R                  R	                  U5        U R                   (       d'  U R#                  5       (       a  U R%                  5         ggg! [
         a5  nU R                  S[        U5      5        U R                  5          SnAgSnAf[         a5  nU R                  S[        U5      5        U R                  5          SnAgSnAf[         a5  nU R                  S[        U5      5        U R                  5          SnAgSnAf[         a5  nU R                  S[        U5      5        U R                  5          SnAgSnAf[         aY  n[        R                  nUb@  [        X#5      (       a0  U R                  S[        U5      5        U R                  5          SnAge SnAff = f)z/Called when data is received on the connection.N  i    )r   	feed_datar   r   r   r   _send_error_responsestr_close_transportr   r	   r   	Exceptionr   r   r)   r   _is_buffer_full_pause_reading)r   dataeh1c_excs       r   data_receivedASGIProtocol.data_received  s   ??OO%%d+;;KK!!$'""%%**408 ##(<(<(>(>! )?#7 $ ))#s1v6%%'& ))#s1v6%%'( ))#s1v6%%' ))#s1v6%%' &CC&:a+A+A--c3q6:))+sO   -C 
H+C;;H+D88H+E55H+F22H?AHHHc                     U R                   (       aG  [        U R                   S5      (       a,  [        U R                   R                  5      U R                  :  $ g)z/Check if internal buffer is full (HTTP/2 only)._bufferF)r   r   lenr  r   rF   s    r   r  ASGIProtocol._is_buffer_full  s<    ;;74;;	::t{{**+d.C.CCCr   c                     U R                   (       d5  U R                  (       a#  SU l          U R                  R                  5         ggg! [        [        4 a     gf = f)z1Pause reading from transport due to backpressure.TN)r   rB   rK   AttributeErrorr   rF   s    r   r  ASGIProtocol._pause_reading  sO    ###'D ,,. )7# #L1    A AAc                     U R                   (       a5  U R                  (       a#  SU l          U R                  R                  5         ggg! [        [        4 a     gf = f)zResume reading from transport.FN)r   rB   rN   r#  r   rF   s    r   _resume_readingASGIProtocol._resume_reading  sO    DNN#(D --/ %3 #L1 r%  c                     U R                   (       a  U R                   R                  5         U R                  R                  nUS:  a5  U R                  R
                  R                  XR                  5      U l         gg)z6Arm keepalive timeout timer after response completion.r   N)r   cancelr   	keepaliver   r   
call_later_keepalive_timeout)r   keepalive_timeouts     r   _arm_keepalive_timer!ASGIProtocol._arm_keepalive_timer  s`    !!""))+ HH..q %)[[%5%5%@%@!#:#:&D" !r   c                 j    U R                   (       a"  U R                   R                  5         SU l         gg)z0Cancel keepalive timer when new request arrives.N)r   r*  rF   s    r   _cancel_keepalive_timer$ASGIProtocol._cancel_keepalive_timer   s*    !!""))+%)D" "r   c                 $    U R                  5         g)z&Called when keepalive timeout expires.N)r  rF   s    r   r-  ASGIProtocol._keepalive_timeout&  s    r   c                    U R                   (       a  gSU l         U R                  =R                  S-  sl        U R                  5         U R                  (       a  U R                  R                  5         U R                  (       a  U R                  R                  5         U R                  b  U R                  R                  5         U R                  (       a  U R                  R                  5       (       di  [        U R                  SS5      nUS:  a1  U R                  R                  R                  UU R                  5        gU R                  R!                  5         ggg)a\  Called when the connection is lost or closed.

Instead of immediately cancelling the task, we signal a disconnect
event and send an http.disconnect message to the receive queue.
This allows the ASGI app to clean up resources (like database
connections) gracefully before the task is cancelled.

See: https://github.com/benoitc/gunicorn/issues/3484
NTre   asgi_disconnect_grace_period   r   )r   r   r   r2  r   feed_eofr   r   r   r   r   r   r   r   r,  _cancel_task_if_pendingr*  )r   excgrace_periods      r   connection_lostASGIProtocol.connection_lost*  s     <<! 	$$&;;KK  " ??OO$$& *113 ::djjoo//"488-KQOLa  ++ 00 

!!# 0:r   c                     U R                   (       a;  U R                   R                  5       (       d  U R                   R                  5         ggg)z9Cancel the task if it's still pending after grace period.N)r   r   r*  rF   s    r   r:  $ASGIProtocol._cancel_task_if_pendingU  s0    ::djjoo//JJ 0:r   c                 \    U R                   (       a  U R                   R                  5         gg)z>Called by transport when write buffer exceeds high water mark.N)r   rR   rF   s    r   rR   ASGIProtocol.pause_writingZ  s"    ,,. r   c                 \    U R                   (       a  U R                   R                  5         gg)zBCalled by transport when write buffer drains below low water mark.N)r   rU   rF   s    r   rU   ASGIProtocol.resume_writing_  s"    --/ r   c                 F    U R                   R                  U5        g! [         ag  nUR                  [        R                  [        R
                  [        R                  4;  a   U R                  R                  S5         SnAg SnAgSnAf[        [        4 a     gf = f)aH  Write data to transport, handling connection errors gracefully.

Catches exceptions that occur when the client has disconnected:
- OSError with errno EPIPE, ECONNRESET, ENOTCONN
- RuntimeError when transport is closing/closed
- AttributeError when transport is None

These are silently ignored since the client is already gone.
zSocket error writing response.N)rB   writeOSErrorerrnoEPIPE
ECONNRESETENOTCONNr   	exceptionr   r#  )r   r  r  s      r   _safe_writeASGIProtocol._safe_writed  sw    	NN  & 	Ewwu{{E,<,<ennMM""#CDD Nn- 		s    
B AB

B B c                   #     U R                   R                  S5      nU R                   R                  S5      n[        U R                  SS5      nUS:X  a+  U R	                  X5      I Sh  vN    U R                  5         gU R                  (       Gd   U =R                  S-  sl        U R                  5         U R                  R                  5       (       d#   U R                  R                  5       I Sh  vN   U R                  (       d  U R                  c  GOU R                  nU R                  U5      (       a  U R!                  XBU5      I Sh  vN   GO[U R#                  XBU5      I Sh  vN nU R$                  =R&                  S-  sl        U R$                  R&                  U R$                  R(                  :  a.  U R*                  R-                  S5        S	U R$                  l        S	nU(       a  U R$                  R.                  (       d  OU R                  R0                  (       d  OU R3                  5         U R4                  (       a  U R4                  R7                  5         SU l        SU l        U R                  R;                  5         U R=                  5         U R                  (       d  GM   U R                  5         g GNZ GN! [        R                   a     M.  f = f GN GN{! [        R                   a     NN[>         a&  nU R*                  RA                  S
U5         SnANxSnAff = f! U R                  5         f = f7f)a  Main request handling loop using callback-based parser.

Uses synchronous parsing in data_received(), avoiding the async
overhead of pull-based parsing. The parser fires callbacks when
headers and body data are available, and this loop waits on
events rather than actively parsing.
peernamesocknamer   httpuwsgiNre   ,Autorestarting worker after current request.FzError handling connection: %s)!rB   r   r   r   _handle_connection_uwsgir  r   r   r2  r   is_setrE   r?   r   r   _is_websocket_upgrade_handle_websocket_handle_http_requestr   nrmax_requestsr   infoaliver+  r'  r   resetr   rQ   r/  r  rL  )r   rP  rQ  protocol_typer   r+  r  s          r   r   ASGIProtocol._handle_connectionw  s    I	$~~44Z@H~~44Z@H $DHHj&AM'33HGGGB !!# lll!#,,. **1133"1166888 <<4#8#8#@// --g6600HMMM #'";";x# 	
 !# ;;>>T[[%=%==HHMM"PQ(-DKK% %I (9(9 xx)) $$& (())//1 )-%&*###))+ ))+q lll~ !!#E H 9"11  NF %% 	 	CHH>BB	C !!#s   M	A'K, +K,K, 1M	AK, K 6K7K ;K, L4 7K, K&K, L4 K, .K)/B!K, L4 K, ,L4 -BK, 4M	K, K K#K,  L4 "K##K, )K, ,L1 L4 	L1L,'L4 ,L11L4 4MM	c                   #    [        U R                  5      nU R                  (       Gd}  U =R                  S-  sl         [        R
                  " U R                  UUU R                  5      I Sh  vN nU R                  U5      (       a  U R                  XBU5      I Sh  vN   gU R                  XBU5      I Sh  vN nU R                  =R                  S-  sl        U R                  R                  U R                  R                   :  a.  U R                  R#                  S5        SU R                  l        SnU(       a  U R                  R$                  (       d  gU R                  R&                  (       d  gUR)                  5       I Sh  vN   U R                  (       d  GM|  gg GN8! [         a     g[         a&  nU R                  R                  SU5         SnAgSnAff = f GNI GN1 Na7f)z0Handle uWSGI protocol connections (legacy path).re   NzuWSGI parse error: %srT  F)r   r   r   r   r
   parser   r   r   r   debugrW  rX  rY  r   rZ  r[  r\  r]  r+  
drain_body)r   rP  rQ  unreaderr   r  r+  s          r   rU  %ASGIProtocol._handle_connection_uwsgi  sz     -,,,NNaN 1 7 7HHNN	!  ))'22,,WIII #778 I
 KKNNaN {{~~!9!99LM$)!!	DKK$5$588%%$$&&&S ,,,  & 6: J& 's   =G1 0F+ 0F(1F+ 5+G1 G)!G1;G,<CG1G/G1&G1(F+ +
G&5G17	G& G!G1!G&&G1,G1/G1c                     UR                   S:w  a  gSnSnUR                   H5  u  pEUS:X  a  UR                  5       nM  US:X  d  M%  UR                  5       nM7     US:H  =(       a    U=(       a    SU;   $ )zCheck if request is a WebSocket upgrade.

Per RFC 6455 Section 4.1, the opening handshake requires:
- HTTP method MUST be GET
- Upgrade header MUST be "websocket" (case-insensitive)
- Connection header MUST contain "Upgrade"
GETFNUPGRADE
CONNECTION	websocketupgrade)r	  rs   lower)r   r   rl  
connectionrw   rx   s         r   rW  "ASGIProtocol._is_websocket_upgrade  so     >>U"
"??KDy ++-%"[[]
	 +
 +%P*Pj9PPr   c                    #    SSK Jn  SU l        U R                  XU5      nU" U R                  XPR
                  U R                  5      nX`l        UR                  5       I Sh  vN   g N7f)z!Handle WebSocket upgrade request.r   )WebSocketProtocolN)	gunicorn.asgi.websocketrq  r   _build_websocket_scoperB   r   r   r   run)r   r   rQ  rP  rq  scopews_protocols          r   rX  ASGIProtocol._handle_websocket  sX     = !%++GxH'NNE88TXX

 &oos   A!A+#A)$A+c           	      r	  ^ ^^^^^^^^#    T R                  TX#5      nSmSmSmSmST l        Sm/ mSmT R                  nUUUUUUUU U4	S jnT R                  R                  n [
        R                  " 5       nT R                  R                  T R                  T5        T R                  XER                  U5      I Sh  vN   Tb  TeT(       d  T R                  SS5        SmST l         [!        [
        R                  " 5       U-
  5      n	U(       a=  T R#                  TX#5      n
[%        TTT5      nT R                  R'                  UTX5        OSn
SnT R                  R)                  T R                  TX5        TR/                  5       (       a  gT R                  R0                  =(       a    T R                  R2                  $  GN! [        R                   a    T R                  R                  S5         ST l         [!        [
        R                  " 5       W-
  5      n	U(       a=  T R#                  TX#5      n
[%        TTT5      nT R                  R'                  UTX5        OSn
SnT R                  R)                  T R                  TX5        g! [*         a    T R                  R-                  S5         gf = f[*         a    T R                  R-                  S	5        T(       d  T R                  SS5        Sm ST l         [!        [
        R                  " 5       W-
  5      n	U(       a=  T R#                  TX#5      n
[%        TTT5      nT R                  R'                  UTX5        OSn
SnT R                  R)                  T R                  TX5        g! [*         a    T R                  R-                  S5         gf = ff = f! [*         a    T R                  R-                  S5         GNpf = f! ST l         [!        [
        R                  " 5       W-
  5      n	U(       a=  T R#                  TX#5      n
[%        TTT5      nT R                  R'                  UTX5        OSn
SnT R                  R)                  T R                  TX5        f ! [*         a    T R                  R-                  S5         f f = f= f7f)
zHandle a single HTTP request.FN  r   c                 &  >	#    TR                   (       a  g U S   nUS:X  a6  U R                  S5      nU R                  S/ 5      nTR                  X#T5        g US:X  az  T(       a  [        S5      mg SmU S   mU R                  S/ 5      m
[	        S T
 5       5      nU(       d!  TR
                  S	:  a  Sm[        T
5      S
/-   m
TR                  TT
T5        g US:X  Ga0  T(       d  [        S5      mg T	(       a  [        S5      mg U R                  SS5      nU R                  SS5      nU(       aQ  TR                  UTS9  T[        U5      -  mTR                  (       a"  TR                  R                  5       I S h  vN   U(       d  T(       aI  TR                  (       a&  TR                  TR                  S-   5        S Tl        OETR                  S5        O3TR                  (       a"  TR                  TR                  5        S Tl        Sm	g g g  N7f)Nr   http.response.informationalri   rs   http.response.startResponse already startedTc              3     #    U  H~  u  p[        U[        5      (       a  UR                  5       OUR                  5       S :H  =(       d8    [        U[        5      (       a  UR                  5       OUR                  5       S:H  v   M     g7f)s   content-lengthzcontent-lengthN)r)   r  rm  ).0rw   _s      r   	<genexpr>BASGIProtocol._handle_http_request.<locals>.send.<locals>.<genexpr>M  sj      ) $4 &0c%:%:TZZ\

Qbb e(24(=(=

4::<Tdde#3s   BBre   re   )s   transfer-encodings   chunkedhttp.response.bodyResponse not startedResponse already completer   r   r   F)r   s   0

)r   get_send_informationalr   anyrh   list_send_response_start
_send_bodyr   r   rG   r   rM  )messagemsg_typeinfo_statusinfo_headershas_content_lengthr   r   exc_to_raiser   response_completeresponse_headersresponse_sentresponse_startedresponse_statusr   use_chunkeds          r   send/ASGIProtocol._handle_http_request.<locals>.send2  s     ||vH88%kk(3&{{9b9((GL00##/0J#KL#' ")("3#*;;y"#=  &) ) $4) &" *goo.G"&K'+,<'=Ac@d'd$))/;KWU11'#/0F#GL$#/0K#LL{{63/#KKU;	OOD+O>!SY.M))"0066888 "00 ,,T-B-B\-QR48D1 ,,\:..(()>)>?04-(,% !% 2  9s   E8H;H<BHInternal Server Errorz'Request cancelled (client disconnected)Exception in post_request hookError in ASGI application)_build_http_scoper   r   r   access_log_enabledr[   	monotonicr   pre_requestr   r   r   r  r?   r   rc  r   _build_environro   accesspost_requestr  rL  should_closer]  r+  )r   r   rQ  rP  ru  body_receiverr  r  request_startrequest_timeenvironrespr  r  r  r  r  r  r  s   ``          @@@@@@@r   rY  !ASGIProtocol._handle_http_request  s    &&wC ! !%  ++F	- F	-R "XX88(	E NN,MHH  g6((5"7"7>>>'"" $))#/FG"% #'DE+DNN,<},LM%"11'8NG+O=M}]DHHOOD'7I"GD%%dkk7GJ
 !!{{  7TXX%7%77U ? %% 	HHNNDE #'DE+DNN,<},LM%"11'8NG+O=M}]DHHOOD'7I"GD%%dkk7GJ E""#CDE+  	HH:;#))#/FG"% #'DE+DNN,<},LM%"11'8NG+O=M}]DHHOOD'7I"GD%%dkk7GJ E""#CDE+	*  E""#CDE #'DE+DNN,<},LM%"11'8NG+O=M}]DHHOOD'7I"GD%%dkk7GJ E""#CDEs   AR7$AG >G?$G #R7+BO ;A	R7G /O 6O/ 7R7?BJ R7%J85R77J88R7;?O :O/ ;R7BN R7%N<9R7;N<<R7?O  O/ %O,(R7+O,,R7/R48BR	R4	%R1.R40R11R44R7c                 j   [        USS5      n[        U[        5      (       a  [        U5      nOV/ nUR                   HD  u  pgUR	                  UR                  5       R                  S5      UR                  S5      45        MF     [        U5      n[        U5      n	SSSS.UR                  S    S	UR                  S
    3UR                  UR                  UR                  UR                  (       a  UR                  OSUR                  (       a  UR                  R                  S5      OSU R                  R                  =(       d    SUUU	S.n
[!        U R"                  S5      (       a  U R"                  R$                  U
S'   [!        US5      (       a  SUR&                  UR(                  S.0U
S'   U
$ )z*Build ASGI HTTP scope from parsed request.headers_bytesNr5   rR  3.02.4rh   spec_versionr   rd   re   r    r   r   http_versionr	  schemepathraw_pathquery_string	root_pathrs   serverclientstatepriority_weighthttp.response.priorityweight
depends_on
extensions)r   r)   r  rs   rv   rm  r^   r&   rh   r	  r  r  r  queryr   r  r   r   r  r  priority_depends_on)r   r   rQ  rP  r  rs   rw   rx   r  r  ru  s              r   r  ASGIProtocol._build_http_scope  sv     $?mT**=)GG&

 3 3I >Y@WXY  / %X.$X.  %u=&q12!GOOA4F3GHnnnnLL,3,<,<((#?F}}GMM00;RU++1r
  4;;((![[..E'N 7-..(%55")"="=+#E, r   c           	      .   UR                   UR                  UR                  UR                  =(       d    SSUR                  S    SUR                  S    3U(       a  US   OSS.nUR
                   H  u  pVSUR                  SS	5      -   nXdU'   M      U$ )
z8Build minimal WSGI-like environ dict for access logging.r  rc   r   rd   re   -REQUEST_METHODRAW_URI	PATH_INFOQUERY_STRINGSERVER_PROTOCOLREMOTE_ADDRHTTP_r  )r	  urir  r  rh   rs   replacer   r   rQ  rP  r  rw   rx   rk   s           r   r  ASGIProtocol._build_environ  s     &nn{{ #MM/R!&wq'9&:!GOOA<N;OP*28A;
 #??KDDLLc22C CL + r   c                 P   / nUR                    HD  u  pVUR                  UR                  5       R                  S5      UR                  S5      45        MF     / nUR                    H;  u  pVUS:X  d  M  UR	                  S5       Vs/ s H  oR                  5       PM     nn  O   [        U5      n	[        U5      n
SSSS.UR                  S    S	UR                  S
    3UR                  S:X  a  SOSUR                  UR                  (       a  UR                  OSUR                  (       a  UR                  R                  S5      OSU R                  R                  =(       d    SUU	U
US.n[        U R                  S5      (       a  U R                  R                   US'   U$ s  snf )z/Build ASGI WebSocket scope from parsed request.r5   zSEC-WEBSOCKET-PROTOCOL,rk  r  r  r  r   rd   re   httpswsswsr   r  )r   r   r  r  r  r  r  r  rs   r  r  subprotocolsr  )rs   rv   rm  r^   splitstripr&   rh   r  r  r  r  r   r  r   r   r  )r   r   rQ  rP  rs   rw   rx   r  sr  r  ru  s               r   rs  #ASGIProtocol._build_websocket_scope  sj    "??KDNNDJJL//	:ELL<STU + "??KD//38;;s3CD3Ca	3CD +
 %X.$X.   %u=&q12!GOOA4F3GH&~~8edLL,3,<,<((#?F}}GMM00;RU++1r(
  4;;((![[..E'N3  Es   F#c           	         UR                   S:  a  gU R                  U5      nSUR                   S    SUR                   S    SU SU S3	nU H[  u  pg[        U[        5      (       a  UR	                  S	5      n[        U[        5      (       a  UR	                  S	5      nXV S
U S3-  nM]     US-  nU R                  UR                  S	5      5        g)a7  Send an informational response (1xx) such as 103 Early Hints.

Args:
    status: HTTP status code (100-199)
    headers: List of (name, value) header tuples
    request: The parsed request object

Note: Informational responses are only sent for HTTP/1.1 or later.
HTTP/1.0 clients do not support 1xx responses.
r  Nrc   r   rd   re   rf   r4   r5   z: )rh   _get_reason_phraser)   rt   ru   rM  r^   )r   ri   rs   r   rj   responserw   rx   s           r   r   ASGIProtocol._send_informational  s     ??V#((07??1-.a0B/C1VHAfXUYZ"KD$&&{{9-%''Y/&5'..H # 	F34r   c                 "   U R                  U5      n[        UR                  X5      nU/nSnSnU H  u  p[        U	[        5      (       a"  U	R                  5       nUR                  U	5        O?U	R                  5       R                  S5      nUR                  U	R                  S5      5        UR                  S5        [        U
[        5      (       a  UR                  U
5        O UR                  U
R                  S5      5        UR                  S5        US:X  a  SnM  US:X  d  M  SnM     U(       d  UR                  [        5        U(       d  UR                  [        5       5        UR                  S5        SR                  U5      U l        g	)
zSend HTTP response status and headers.

Uses cached status lines and headers for common cases to avoid
repeated string formatting and encoding.
Fr5   s   :    
s   dateTs   serverr   N)r  rm   rh   r)   rt   rm  rv   r^   _CACHED_SERVER_HEADERra   r   r   )r   ri   rs   r   rj   status_linepartshas_date
has_serverrw   rx   
name_lowers               r   r  !ASGIProtocol._send_response_start.  s7    ((0-goovN 
"KD$&&!ZZ\
T"!ZZ\00;
T[[34LL%''U#U\\)45LL! W$y(!
+ #0 LL./LL023W !$r   c                    U(       a  U(       aD  [        U5      n[        R                  U5      =(       d    US S3R                  S5      nXA-   S-   nOSnU R                  (       a&  U R                  U R                  U-   5        SU l        gU(       a  U R                  U5        ggU R                  (       a&  U R                  U R                  U-   5        SU l        gU(       a  U R                  U5        gg)ziSend response body chunk.

Combines buffered headers with first body chunk for efficient write batching.
r3   r4   r5   r  r   N)r   _CHUNK_PREFIXESr  r^   r   rM  )r   r   r   sizeprefix
chunk_datas         r   r  ASGIProtocol._send_body`  s    
  4y(,,T2Wao6L6LY6W#]W4
 
 $$  !6!6!CD(,%  ,  $$  !6!6!=>(,%  & r   c                     UR                  S5      nSU SU S[        U5       S3nU R                  UR                  S5      5        U R                  U5        g)zSend an error response.zutf-8z	HTTP/1.1 rf   z,
Content-Type: text/plain
Content-Length: z
Connection: close

r5   N)r^   r   rM  )r   ri   r  r   r  s        r   r  !ASGIProtocol._send_error_response}  sa    ~~g&xq	 *"4yk * 	 	34r   c                     0 SS_SS_SS_SS_S	S
_SS_SS_SS_SS_SS_SS_SS_SS_SS_SS_SS _S!S"_0 S#S$_S%S&_S'S(_S)S*_S+S,_S-S._S/S0_S1S2_S3S4_S5S6_S7S8_S9S:_S;S<_S=S>_S?S@_SASB_EnUR                  USC5      $ )Dz'Get HTTP reason phrase for status code.d   Continuee   zSwitching Protocolsg   zEarly Hints   OK   Created   Accepted   z
No Content   zPartial Contenti-  zMoved Permanentlyi.  Foundi/  z	See Otheri0  zNot Modifiedi3  zTemporary Redirecti4  zPermanent Redirectr  zBad Requesti  Unauthorizedi  	Forbiddeni  z	Not Foundi  zMethod Not Allowedi  zRequest Timeouti  Conflicti  Gonei  zLength Requiredi  zPayload Too Larger  zURI Too Longi  zUnsupported Media Typei  zUnprocessable Entityi  zToo Many Requestsry  r  i  zNot Implementedi  zBad Gatewayi  zService Unavailablei  zGateway TimeoutUnknown)r  )r   ri   reasonss      r   r  ASGIProtocol._get_reason_phrase  s   "
"
&"
 "
 	"

 "
 "
 "
 ""
 $"
 "
 "
 "
 %"
 %"
 "
  !"
" #"
$ %"
& %'"
( ")"
* +"
, -"
. "/"
0 $1"
2 3"
4 )5"
6 '7"
8 $9"
: (;"
< "="
> ?"
@ &A"
B "C"
F {{69--r   c                 "   U R                   (       an  U R                  (       d\   U R                   R                  5       (       a  U R                   R                  5         U R                   R	                  5         SU l        ggg! [
         a     Nf = f)zClose the transport safely.

Calls write_eof() first if supported to signal end of writing,
which helps ensure buffered data is flushed before closing.
TN)rB   r   can_write_eof	write_eofcloser  rF   s    r   r  ASGIProtocol._close_transport  sm     >>$,,>>//11NN,,.$$&  DL #/>  s   AB 
BBc           	        #     SSK Jn  UR                  S5      nUR                  S5      nU R                  n[        R
                  " U5      n[        R                  " XX`R                  R                  5      nU" U R                  XhU5      n	U	R                  5       I Sh  vN   Xl        U	R                  (       Gd/  U R                  R                  (       Ga   U	R                  SS9I Sh  vN n
U
 HC  n U R'                  XXT5      I Sh  vN   U	R3                  UR,                  R.                  5        ME     U R                  =R4                  [7        U
5      -  sl        U R                  R4                  U R                  R8                  :  a-  U R"                  R;                  S5        SU R                  l        O/U	R                  (       d  U R                  R                  (       a  GM  [?        U S5      (       a#   U R                  RA                  5       I Sh  vN   U RC                  5         g GN GNH! [        R                   a     GM  [          a'  nU R"                  R%                  SU5         SnAM  SnAff = f GNv! [          au  nU R"                  R)                  S	5         U	R+                  UR,                  R.                  S
[1        U5      5      I Sh  vN     SnAGN! [          a      SnAGNf = fSnAff = f! U	R3                  UR,                  R.                  5        f = f! [        R<                   a     GN\[          a'  nU R"                  R)                  SU5         SnAGNSnAff = f GN`! [          a     GNkf = f! [?        U S5      (       a5   U R                  RA                  5       I Sh  vN    O! [          a     Of = fU RC                  5         f = f7f)zHandle an HTTP/2 connection.r   )AsyncHTTP2ConnectionrP  rQ  NrX   r   zHTTP/2 receive error: %szError handling HTTP/2 requestry  rT  FzHTTP/2 connection error: %s_h2_conn)"gunicorn.http2.async_connectionr  r   r   r?   StreamReaderProtocolStreamWriterr   r   r   initiate_connectionr  	is_closedr]  receive_datar   r  r   rc  _handle_http2_requestrL  
send_errorstream	stream_idr  cleanup_streamrZ  r   r[  r\  r   r   r  r  )r   rB   r   r  rP  rQ  r   r   r   h2_connrequestsr  reqs                r   r   %ASGIProtocol._handle_http2_connection  s)    C	$L //
;H //
;H [[F33F;H))V[[-=-=F
 +&(G --///#M '''DKK,=,=,=%,%9%9#%9%FFH $CE"88(    ..szz/C/CD $" #h-/ ;;>>T[[%=%==HHMM"PQ(-DKK%A ''DKK,=,=,=N tZ((----/// !!#c 0  G++   HHNN#=qA % !**+JK!")"4"4 #

 4 4c3q6#    ) ! !!  ..szz/C/CD %% 	 	AHH<a@@	A
 0   tZ((----///  !!#s  O*BL1  H1!8L1 H7 ,H4-H7 1L1 7JJJB+L1 <N =,L1 ,O*>M> M;M>  O*1L1 4H7 7I?L1 	I?I:4L1 8N :I??L1 J
LK?+3K*K!K*$L*
K<4K?5L;K<<K??LL'L..L1 1M8N 	M8M3-N 3M88N ;M> >
NO*NO*O'"O?O OO'
OO'OO''O*c                     / nU Hr  u  p4[        U[        5      (       a  UR                  S5      n[        U[        5      (       a  UR                  S5      nUR                  UR	                  5       U45        Mt     U$ )z?Convert ASGI headers to HTTP/2 format (lowercase string names).r5   )r)   rt   ru   rv   rm  )r   rs   resultrw   rx   s        r   _convert_h2_headers ASGIProtocol._convert_h2_headers  sg    "KD$&&{{9-%''Y/MM4::</0 # r   c           
         ^ ^^^^^^^^^^^#    UR                   R                  mTR                  R                  T5      mT R	                  XU5      nSmSmSmSmSm/ mSmSmUU4S jnUUUUUUUUU U4
S jnT R
                  R                  n[        R                  " 5       n	 T R                  R                  T R                  U5        T R                  XVU5      I Sh  vN   Tb  TeT(       d  TR                  TSS5      I Sh  vN   SmOT(       d  T R                  T5      n
S[        T5      4/nUR!                  U
5        TR                  R                  T5      mT(       aC  TR"                  R%                  TUS	S
9  TR%                  US	S
9  TR'                  5       I Sh  vN    [-        [        R                  " 5       U	-
  5      nU(       a<  T R/                  XU5      n[1        TTT5      nT R
                  R3                  XX5        OSnSnT R                  R5                  T R                  XU5        g GN\ GN8 N! [(         aC    T R
                  R+                  S5        T(       d  TR                  TSS5      I Sh  vN    Sm Nf = f! [(         a    T R
                  R+                  S5         gf = f!  [-        [        R                  " 5       U	-
  5      nU(       a<  T R/                  XU5      n[1        TTT5      nT R
                  R3                  XX5        OSnSnT R                  R5                  T R                  XU5        f ! [(         a    T R
                  R+                  S5         f f = f= f7f)zHandle a single HTTP/2 request with streaming support.

Streams both request and response body chunks immediately,
avoiding buffering entire uploads and enabling SSE, streaming
downloads, and other real-time use cases.
FNry  r   c                    >#    Tb  TR                   R                  S:X  a  SS0$ T(       d:  TR                  (       a)  TR                  (       d  SmTR	                  5       n SU SS.$  [
        R                  " TR                  5       SS	9I S h  vN nUc  SmSS
SS.$ TR                  (       a  SmSUTR                  (       + S.$  N7! [
        R                   a    SS0s $ f = f7f)NCLOSEDr   r   Tr   Fr   r   r   r   )
r  rw   request_complete_body_chunksget_request_bodyr?   r   read_body_chunkr   _body_complete)r   r   body_receivedr  s     r   r   3ASGIProtocol._handle_http2_request.<locals>.receive)  s     ~!2!2h!> 122 !V%<%<VEXEX $..0* !& 3%..**,   } $*!&  $$ $ '!'!6!66 % '' 3 1223s<   A#C%'&C CC 3C%C C"C%!C""C%c                   >
#    U S   nUS:X  aO  U R                  S5      nU R                  S/ 5      nTR                  U5      nTR                  TX$5      I S h  vN   g US:X  a-  T(       a  [        S5      mg SmU S   mU R                  S/ 5      mg US:X  GaM  T(       d  [        S	5      mg T(       a  [        S
5      mg U R                  SS5      nU R                  SS5      nT(       d  TR                  T5      nS[	        T5      4/nUR                  U5        TR                  R                  T5      nUc  [        S5      mg TR                  R                  TUSS9  UR                  USS9  TR                  5       I S h  vN   SmU(       a+  TR                  TXV(       + S9I S h  vN   T[        U5      -  mU(       d#  U(       d  TR                  TSSS9I S h  vN   Smg g US:X  aQ  T(       d  [        S5      mg U R                  S/ 5      n	TR                  U	5      n
TR                  TU
5      I S h  vN   g g  GN N N Ng N7f)Nr   r{  ri   rs   r|  r}  Tr  r  r  r   r   r   F:statuszStream closed
end_streamhttp.response.trailersz)Cannot send trailers before body complete)r  r!  send_informationalr   r  extendstreamsr  send_headers_send_pending_data	send_datar   send_trailers)r  r  r  r  rs   r   r   response_hdrsr  trailer_headerstrailersr  r  headers_sentr  r  r  r  r  r   r  s              r   r  0ASGIProtocol._handle_http2_request.<locals>.sendT  s[     vH88%kk(3&{{9b922<@00KQQQ00##/0J#KL#' ")("3#*;;y"#=  11'#/0F#GL$#/0K#LL{{63/#KKU;	 $"667GHG&/_1E%F$GM!((1 %__00;F~'3O'DOO00MV[0\''%'H!44666#'L !++It+VVV!SY.M %//	34/PPP(,%	 ! 55(#/0[#\L")++i"<33OD++Ix@@@ 6e RH 7
 W Q As\   AIH=D(II %I'I(4IIAI6I7I IIIIr  r.  Tr/  r  r  )r  r  r4  r  _build_http2_scoper   r  r[   r  r   r  r   r   r  r!  r  r3  r  r5  r6  r  rL  r   _build_http2_environro   r  r  )r   r   r  rQ  rP  ru  r   r  r  r  rs   r9  r  r  r  r+  r  r<  r  r  r  r  r  r  r  s   ` `            @@@@@@@@@@r   r  "ASGIProtocol._handle_http2_request  s     NN,,	$$Y/''8D ! )	VC	A C	AL "XX88(,	EHH  g6((54000'"" $((C9PQQQ"% "223CD"+S-A!B C$$W- ,,Y7OO00MVZ0[''$'G!44666E+DNN,<},LM%"778TG+')9=D HHOOD7I"GD%%dkk7TJQ 1 R 7 	&HH:;((C9PQQQ"%		&&  E""#CDEE+DNN,<},LM%"778TG+')9=D HHOOD7I"GD%%dkk7TJ E""#CDEs   BM>$;I H; &I H>I J> BI %I&I +BJ :M>;I >I I AJJJJ> JJ> %J;8M>:J;;M>>M; BMM;%M85M;7M88M;;M>c                 (   / nUR                    HD  u  pVUR                  UR                  5       R                  S5      UR                  S5      45        MF     [	        U5      n[	        U5      nSSSS.SUR
                  UR                  UR                  [        USS5      =(       d.    UR                  (       a  UR                  R                  S5      OS	UR                  (       a  UR                  R                  S5      OS	U R                  R                  =(       d    S
UUUS.n	[        U R                  S5      (       a  U R                  R                  U	S'   0 n
[        US5      (       a  UR                  UR                   S.U
S'   0 U
S'   XS'   U	$ )z*Build ASGI HTTP scope from HTTP/2 request.r5   rR  r  r  r  2r  Nr   r  r  r  r  r  r  r1  r  )rs   rv   rm  r^   r&   r	  r  r  r   r  r   r  r   r   r  r  r  )r   r   rQ  rP  rs   rw   rx   r  r  ru  r  s              r   r>  ASGIProtocol._build_http2_scope  sa   "??KDNN

##I.Y'  + %X.$X.  %u=nnnnLLT:wahamamw||?R?RS\?]sv?F}}GMM00;RU++1r
 4;;((![[..E'N 
7-..!11%994J/0
 02
+,(lr   c                     UR                   UR                  UR                  UR                  =(       d    SSU(       a  US   OSS.nUR                   H  u  pVSUR                  SS5      -   nXdU'   M      U$ )z.Build minimal environ dict for access logging.r  zHTTP/2r   r  r  r  r  )r	  r  r  r  rs   r  r  s           r   r?  !ASGIProtocol._build_http2_environ  so     &nn{{ #MM/R'*28A;
 #??KDDLLc22C CL + r   )r   r   r   r   r   r  r   r   r   r   r   r   r   r   r   r   r   r   r   rB   r   r   )F)2r   r   r   r   r   r   r   r   r   r   r   classmethodr   r   r   r   r   r   r  r  r  r'  r/  r2  r-  r=  r:  rR   rU   rM  r   rU  rW  rX  rY  r  r  rs  r  r  r  r  r  r  r   r!  r  r>  r?  r    r!   r   r   r   r     s	    NO#' $LM< " "('#
8
t7",
/
)"V* )$V 
/
0
&Q$f-'^Q* "L8\+Z$$L5800d':%.N  E$N	vEp)Vr   r   )&r   r?   rH  r*   r[   gunicorn.asgi.unreaderr   gunicorn.asgi.parserr   r   r   r   r   r	   gunicorn.asgi.uwsgir
   gunicorn.http.errorsr   gunicorn.uwsgi.errorsr   r   r&   r2   rg   r  r_   r\   ranger^   r  r   r7   ra   rm   ro   r{   Protocolr   )is   0r   <module>rO     s   
     0  2 + 5F F5(  4     ?DElKl1Tl)))44lK  %* %*P	%/ / m  m `s7## sG Ls   B;