Ë
    ÚŠ±j»: ã                   óˆ  — d Z ddlZddlZddlZddlZddlmZ ddlmZm	Z	m
Z
mZmZmZ ddlmZ ddlmZ ddlmZ ddlmZ  G d	„ d
«      Zd„ Zd„ Zi ZdZdada ed«      D � ci c]  } | | d›d�j=                  d«      “Œ c} ZdZ  G d„ d«      Z!d„ Z"d„ Z# G d„ d«      Z$ G d„ d«      Z% G d„ dejL                  «      Z'yc c} w )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)Únegotiation)ÚUWSGIParseExceptionc                   ó   — e Zd ZdZdZd„ Zy)Ú_RequestTimezçLightweight 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                 ód   — t        |«      | _        t        || j                  z
  dz  «      | _        y )Ni@B )Úintr   r   )ÚselfÚelapseds     ú[/var/www/io.vulcan-creative.com/venv/lib/python3.12/site-packages/gunicorn/asgi/protocol.pyÚ__init__z_RequestTime.__init__%   s(   € Ü˜7“|ˆŒÜ ¨4¯<©<Ñ!7¸9Ñ DÓEˆÕó    N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__r   © r   r   r   r      s   „ ñð ,€IóFr   r   c                 ó&   — | rt        | dd «      S dS )z÷Normalize 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                 óš   — t        | t        «      syd|v ry	 t        j                  | d   «      }|D ]  }||v sŒ y y# t        $ r Y yw xY w)z‚Check 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_proxyr/   4   si   € ô
 �i¤Ô'ØØ
ˆjÑØðÜ×!Ñ! )¨A¡,Ó/ˆð ò ˆØ�Š=Ùðð øô ò Ùðús   ˜> ¾	A
Á	A
s   Server: gunicorn/asgi
r   g        i @  Úxú
úlatin-1i   c                   ó8   — e Zd ZdZdZd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
y	)
ÚFlowControlz®Manage 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                 ó”   — || _         d| _        d| _        t        j                  «       | _        | j
                  j                  «        y ©NF)r5   r6   r7   ÚasyncioÚEventr8   Úset)r   Ú	transports     r   r   zFlowControl.__init__^   s9   € Ø#ˆŒØ ˆÔØ!ˆÔÜ")§-¡-£/ˆÔØ×Ñ×#Ñ#Õ%r   c              ƒ   óT   K  — | j                   j                  «       ƒ d{  –—†  y7 Œ­w)z!Wait until transport is writable.N)r8   Úwait©r   s    r   ÚdrainzFlowControl.draine   s   è ø€ à×%Ñ%×*Ñ*Ó,×,Ò,ús   ‚( &¡(c                 ó`   — | j                   s"d| _         | j                  j                  «        y y ©NT)r6   r5   Úpause_readingrA   s    r   rE   zFlowControl.pause_readingi   s(   € Ø×ÒØ#ˆDÔØ�O‰O×)Ñ)Õ+ð  r   c                 ó`   — | j                   r"d| _         | j                  j                  «        y y r:   )r6   r5   Úresume_readingrA   s    r   rG   zFlowControl.resume_readingn   s(   € Ø×ÒØ$ˆDÔØ�O‰O×*Ñ*Õ,ð r   c                 ó`   — | j                   s"d| _         | j                  j                  «        y y rD   )r7   r8   ÚclearrA   s    r   Úpause_writingzFlowControl.pause_writings   s*   € Ø× Ò Ø $ˆDÔØ×#Ñ#×)Ñ)Õ+ð !r   c                 ó`   — | j                   r"d| _         | j                  j                  «        y y r:   )r7   r8   r=   rA   s    r   Úresume_writingzFlowControl.resume_writingx   s*   € Ø×ÒØ %ˆDÔØ×#Ñ#×'Ñ'Õ)ð r   N)r   r   r   r   r   r   rB   rE   rG   rJ   rL   r   r   r   r4   r4   V   s-   „ ñð
 T€Iò&ò-ò,ò
-ò
,ó
*r   r4   c                  ó–   — t        j                   «       } | t        z
  dk\  r$ddlm} d |d¬«      › d�j	                  d«      a| at
        S )	z1Get cached Date header, updating once per second.ç      ð?r   )Ú
formatdatezDate: T)Úusegmtr1   r2   )ÚtimeÚ_cached_date_timeÚemail.utilsrO   ÚencodeÚ_cached_date_header)ÚnowrO   s     r   Ú_get_cached_date_headerrW   ~   sL   € ô �)‰)‹+€CØ
ÔÑ #Ò%å*Ø &¡z¸Ô'>Ð&?¸tÐD×KÑKÈIÓVÐØÐÜÐr   c           	      ó†   — | |f}|t         vr-d| d   › d| d   › d|› d|› d�	}|j                  d«      t         |<   t         |   S )zGet cached status line bytes.úHTTP/r   ú.é   ú r1   r2   )Ú_CACHED_STATUS_LINESrT   )ÚversionÚstatusÚreasonÚkeyÚlines        r   Ú_get_cached_status_linerc   Š   s\   € à�FÐ
€CØ
Ô&Ñ&Ø�w˜q‘z�l ! G¨A¡J <¨q°°¸¸&¸ÀÐFˆØ$(§K¡K°	Ó$:Ô˜SÑ!Ü Ñ$Ð$r   c                   ó   — e Zd ZdZd„ Zy)ÚASGIResponseInfoz;Simple container for ASGI response info for access logging.c                 ó   — || _         || _        g | _        |D ]d  \  }}t        |t        «      r|j                  d«      }t        |t        «      r|j                  d«      }| j                  j                  ||f«       Œf y )Nr2   )r_   ÚsentÚheadersr&   ÚbytesÚdecodeÚappend)r   r_   rh   rg   ÚnameÚvalues         r   r   zASGIResponseInfo.__init__–   sp   € ØˆŒØˆŒ	àˆŒØ"ò 	/‰KˆD�%Ü˜$¤Ô&Ø—{‘{ 9Ó-�Ü˜%¤Ô'ØŸ™ YÓ/�Ø�L‰L×Ñ  u Õ.ñ	/r   N)r   r   r   r   r   r   r   r   re   re   “   s
   „ ÙEó
/r   re   c                   ó`   — e Zd ZdZdZd„ Zd„ Zd„ Zd„ Ze	d„ «       Z
d„ Zd	„ Zd
„ Zd„ Zd„ Zd„ Zy)ÚBodyReceiverzºBody 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Ú_body_wait_expiredÚ_waiterÚrequestÚprotocolc                 ót   — || _         || _        g | _        d| _        d| _        d| _        d| _        d | _        y r:   )rv   rw   rp   rq   rr   rs   rt   ru   )r   rv   rw   s      r   r   zBodyReceiver.__init__­   s>   € ØˆŒØ ˆŒØˆŒØˆŒØ#ˆÔð ˆŒØ"'ˆÔØˆ�r   c                 ó`   — |r,| j                   j                  |«       | j                  «        yy)z7Feed a body chunk directly (called by parser callback).N)rp   rk   Ú_wake_waiter©r   Úchunks     r   ÚfeedzBodyReceiver.feed¼   s(   € áØ�L‰L×Ñ Ô&Ø×ÑÕð r   c                 ó2   — d| _         | j                  «        y)z1Mark body as complete (called when message ends).TN)rq   rz   rA   s    r   Úset_completezBodyReceiver.set_completeÂ   s   € àˆŒØ×ÑÕr   c                 ó2   — d| _         | j                  «        y)z/Signal that the client transport has gone away.TN)rs   rz   rA   s    r   Úsignal_disconnectzBodyReceiver.signal_disconnectÇ   s   € àˆŒØ×ÑÕr   c                 ó6   — | j                   xs | j                  S )z?True when the receiver should yield http.disconnect to the app.)rs   rt   rA   s    r   Ú_disconnectedzBodyReceiver._disconnectedÌ   s   € ð �|‰|Ò6˜t×6Ñ6Ð6r   c                 óŠ   — | j                   �7| j                   j                  «       s| j                   j                  d«       yyy)z#Wake up any pending receive() call.N)ru   ÚdoneÚ
set_resultrA   s    r   rz   zBodyReceiver._wake_waiterÑ   s6   € à�<‰<Ð#¨D¯L©L×,=Ñ,=Ô,?Ø�L‰L×#Ñ# DÕ)ð -@Ð#r   c              ƒ   ó  K  — | j                   rddiS | j                  r| j                  «       ƒ d{  –—†  ddiS | j                  r| j	                  «       S | j
                  rd| _        ddddœS | j                  j                  d	k(  r*| j                  j                  sd| _        d| _        ddddœS | j                  j                  rd| _
        ddiS | j                  «       ƒ d{  –—†  | j                  «       S 7 ŒÉ7 Œ­w)
z:ASGI receive callable - returns body chunks or disconnect.Útypeúhttp.disconnectNTúhttp.requestr   F©rˆ   ÚbodyÚ	more_bodyr   )rƒ   rr   Ú_wait_for_disconnectrp   Ú
_pop_chunkrq   rv   Úcontent_lengthÚchunkedrw   rs   Ú_wait_for_dataÚ_build_receive_resultrA   s    r   ÚreceivezBodyReceiver.receiveÖ   s  è ø€ ð ×ÒØÐ-Ð.Ð.ð ×ÒØ×+Ñ+Ó-×-Ð-ØÐ-Ð.Ð.ð �<Š<Ø—?‘?Ó$Ð$ð �>Š>Ø"&ˆDÔØ*°CÀeÑLÐLð �<‰<×&Ñ&¨!Ò+°D·L±L×4HÒ4HØ!ˆDŒNØ"&ˆDÔØ*°CÀeÑLÐLð �=‰=× Ò ØˆDŒLØÐ-Ð.Ð.ð ×!Ñ!Ó#×#Ð#Ø×)Ñ)Ó+Ð+ð9 .øð6 	$ús"   ‚0D ²C<³B4D Ã'C>Ã(D Ã>D c                 óž   — | j                   j                  d«      }t        | j                   «      xs | j                   }|sd| _        d||dœS )z/Pop a chunk and return the appropriate message.r   TrŠ   r‹   )rp   ÚpopÚboolrq   rr   )r   r|   Úmores      r   r�   zBodyReceiver._pop_chunký   sH   € à—‘× Ñ  Ó#ˆÜ�D—L‘LÓ!Ò7¨¯©Ð%7ˆÙØ"&ˆDÔØ&°ÀDÑIÐIr   c                 ó¢   — | j                   rddiS | j                  r| j                  «       S | j                  rd| _        ddddœS d| _        ddiS )z,Build receive result after waiting for data.rˆ   r‰   TrŠ   r   Fr‹   )rƒ   rp   r�   rq   rr   rt   rA   s    r   r“   z"BodyReceiver._build_receive_result  s]   € à×ÒØÐ-Ð.Ð.à�<Š<Ø—?‘?Ó$Ð$à�>Š>Ø"&ˆDÔØ*°CÀeÑLÐLð
 #'ˆÔØÐ)Ð*Ð*r   c              ƒ   óÈ  K  — | j                   s| j                  s| j                  ryt        j                  «       }|j                  «       | _        t        | j                  dd«      }|�t        |dd«      nd}|r|dk  rd}	 t        j                  | j                  |¬«      ƒ d{  –—†  d| _        y7 Œ# t        j                  $ r
 d| _        Y Œ&w xY w# d| _        w xY w­w)z*Wait for body data to arrive via callback.NÚcfgÚtimeoutr   ç      >@©rœ   T)rp   rq   rƒ   r;   Úget_event_loopÚcreate_futureru   Úgetattrrw   Úwait_forÚTimeoutErrorrt   )r   Úloopr›   rœ   s       r   r’   zBodyReceiver._wait_for_data  sÊ   è ø€ à�<Š<˜4Ÿ>š>¨T×-?Ò-?Øô ×%Ñ%Ó'ˆØ×)Ñ)Ó+ˆŒô
 �d—m‘m U¨DÓ1ˆØ36°?”'˜#˜y¨$Ô/ÈˆÙ˜' Qš,ØˆGð
	 Ü×"Ñ" 4§<¡<¸ÔA×AÐAð  ˆD�Lð BùÜ×#Ñ#ò 	+ð '+ˆDÖ#ð	+ûð  ˆD�LüsH   ‚B C"Â$B6 Â'B4Â(B6 Â,C"Â4B6 Â6CÃC ÃCÃC Ã	CÃC"c              ƒ   ó$  K  — | j                   ry| j                  j                   rd| _         yt        j                  «       }|j	                  «       | _        	 | j
                  ƒ d{  –—†  d| _        d| _         y7 Œ# d| _        d| _         w xY w­w)zÑWait for connection to close after body is finished.

        This is needed for ASGI apps (like Django) that call receive()
        to listen for client disconnect after the request body is consumed.
        NT)rs   rw   r;   rŸ   r    ru   )r   r¤   s     r   rŽ   z!BodyReceiver._wait_for_disconnect4  s   è ø€ ð �<Š<Øð �=‰=× Ò ØˆDŒLØô ×%Ñ%Ó'ˆØ×)Ñ)Ó+ˆŒð	 Ø—,‘,×ÐàˆDŒLØˆD�Lð ùàˆDŒLØˆD�Lüs0   ‚ABÁA= Á'A;Á(A= Á,BÁ;A= Á=BÂBN)r   r   r   r   r   r   r}   r   r�   Úpropertyrƒ   rz   r”   r�   r“   r’   rŽ   r   r   r   ro   ro   £   sW   „ ñðI€Iòò òò
ð
 ñ7ó ð7ò*ò
%,òNJò+ò$ ó: r   ro   c                   ó’  — e Zd ZdZdZdZdZdZdZdZ	d„ Z
d„ Zd9d„Zed„ «       ZdZd	„ Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z d„ Z!d„ Z"d„ Z#d„ Z$d„ Z%d„ Z&d „ Z'd!„ Z(d"„ Z)d#„ Z*d$„ Z+d%„ Z,d&„ Z-d'„ Z.d(„ Z/d)„ Z0d*„ Z1d+„ Z2e3d,„ «       Z4e3d-„ «       Z5ed.„ «       Z6d:d/„Z7d0„ Z8d1„ Z9d2„ Z:d;d3„Z;d4„ Z<d5„ Z=d6„ Z>d7„ Z?d8„ Z@y)<ÚASGIProtocolzùHTTP/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                 óº  — || _         |j                  | _        |j                  | _        |j                  | _        d | _        d | _        d | _        d | _        d| _	        d | _
        d | _        d | _        d | _        d| _        d| _        d| _        d | _        d | _        d| _        d| _        d | _        d | _        d | _        d | _        d| _        d | _        d | _        y )NFr   i   )Úworkerr›   ÚlogÚasgiÚappr>   ÚreaderÚ_h2c_bufferÚ
_h2c_timerÚ_h2c_upgrade_okÚ_h2c_upgrade_settingsÚ_h2c_upgrade_bodyÚwriterÚ_taskÚ	req_countrs   Ú_conn_lost_handledÚ_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   zASGIProtocol.__init__c  sí   € ØˆŒØ—:‘:ˆŒØ—:‘:ˆŒØ—;‘;ˆŒàˆŒØˆŒð  ˆÔØˆŒð  %ˆÔØ%)ˆÔ"Ø!%ˆÔØˆŒØˆŒ
ØˆŒð ˆŒð
 #(ˆÔØ"ˆÔð !%ˆÔð  %ˆÔØ )ˆÔð "&ˆÔð !%ˆÔØ"ˆÔØ $ˆÔØˆŒð "ˆÔð ˆ�r   c                 óL  — || _         | j                  xj                  dz  c_        |j                  d«      }|rut	        |d«      ri|j                  «       }|dk(  rTt        j                  «       | _        | j                  j                  j                  | j                  ||«      «      | _        y|j                  d«      }t        j                  | j                  |«      rd| _        || _        t%        |«      | _        |j)                  t*        ¬«       d	| _        | j                  j                  j/                  t        j0                  | j2                  «      | _        y|du| _        || _        t%        |«      | _        |j)                  t*        ¬«       | j7                  «        y)
z(Called when a connection is established.r[   Ú
ssl_objectÚselected_alpn_protocolÚh2NÚpeernameF)Úhighr   )r>   rª   Únr_connsÚget_extra_infoÚhasattrrÅ   r;   ÚStreamReaderr®   r¤   Úcreate_taskÚ_handle_http2_connectionrµ   r   Úprior_knowledge_allowedr›   rÀ   r´   r4   rÁ   Úset_write_buffer_limitsÚHIGH_WATER_LIMITr¯   Ú
call_laterÚH2C_PREFACE_TIMEOUTÚ_h2c_undecided_timeoutr°   Ú_start_http1)r   r>   rÄ   ÚalpnrÇ   s        r   Úconnection_madezASGIProtocol.connection_made—  sb  € à"ˆŒØ�‰×Ò Ñ!Õð ×-Ñ-¨lÓ;ˆ
Ùœ' *Ð.FÔGØ×4Ñ4Ó6ˆDØ�tŠ|ä%×2Ñ2Ó4�”Ø!Ÿ[™[×-Ñ-×9Ñ9Ø×1Ñ1°)¸ZÓHó�”
ð à×+Ñ+¨JÓ7ˆÜ×.Ñ.¨t¯x©x¸ÔBð !ˆDŒLØ#ˆDŒKÜ!,¨YÓ!7ˆDÔØ×-Ñ-Ô3CÐ-ÔDØ"ˆDÔØ"Ÿk™k×.Ñ.×9Ñ9Ü×/Ñ/°×1LÑ1LóˆDŒOð ð "¨Ð-ˆŒØˆŒô )¨Ó3ˆÔØ×)Ñ)Ô/?Ð)Ô@Ø×ÑÕr   c                 óž  — t        j                  «       | _        | j                  «        | j                  j                  d«      }t        j                  | j                  |«      xr t        | j                  d«      | _        | j                  j                  j                  | j                  «       «      | _        |r| j#                  |«       yy)zÖCommit to HTTP/1.x and replay anything already read.

        Called straight from connection_made(), and again when h2c sniffing
        gives up on a connection that turned out to speak HTTP/1 after all.
        rÇ   Ú	remainingN)r;   r<   r¾   Ú_setup_callback_parserr>   rÊ   r   Úupgrade_allowedr›   rË   r½   r±   rª   r¤   rÍ   Ú_handle_connectionrµ   Ú_feed_callback_parser)r   ÚbufferedrÇ   s      r   rÕ   zASGIProtocol._start_http1À  s¢   € ô &Ÿm™m›oˆÔØ×#Ñ#Ô%Ø—>‘>×0Ñ0°Ó<ˆô ×'Ñ'¨¯©°(Ó;ò <Ü˜×-Ñ-¨{Ó;ð 	Ôð —[‘[×%Ñ%×1Ñ1°$×2IÑ2IÓ2KÓLˆŒ
ÙØ×&Ñ& xÕ0ð r   c                 óZ  — | j                   €l	 ddl}ddlm} d| _         || _        t	        |d«      | _        t        |dd«      | _        t        |dd«      | _        t        |dd«      | _	        | j                   S | j                   S # t        $ r d| _         d| _        Y | j                   S w xY w)	z:Check if H1CProtocol is available (cached at class level).Nr   )ÚH1CProtocolTr   r   r	   F)Ú_h1c_availableÚgunicorn_h1crà   Ú_h1c_protocol_classrË   Ú_h1c_has_limitsr¡   Ú_h1c_limit_request_lineÚ_h1c_limit_request_headersÚ_h1c_invalid_chunk_extensionÚImportError)Úclsrâ   rà   s      r   Ú_check_h1c_protocol_availablez*ASGIProtocol._check_h1c_protocol_availableÕ  sÄ   € ð ×ÑÐ%ð,Û#Ý4Ø%)�Ô"Ø*5�Ô'ä&-¨lÐ<NÓ&O�Ô#ä.5Ø Ð"4°dó/�Ô+ô 29Ø Ð"7¸ó2�Ô.ô 4;Ø Ð"9¸4ó4�Ô0ð ×!Ñ!Ð!ˆs×!Ñ!Ð!øô ò ,Ø%*�Ô"Ø&+�Õ#Ø×!Ñ!Ð!ð,ús   ŽAB ÂB*Â)B*)Úpermit_obsolete_foldingÚstrip_header_spacesc           	      óÜ  — t        | j                  dd«      }g }| j                  D ]+  }t        | j                  |d«      sŒ|j                  |«       Œ- t        | j                  dd«      dk7  r|j                  d«       |dk(  rt        }n¤|dk(  rf| j                  «       st        d«      ‚t        j                  st        d	«      ‚|rt        d
dj                  |«      z  «      ‚t        j                  }n9| j                  «       r#t        j                  r|st        j                  }nt        }| j                  j                  }|dk(  r|t        k7  rd}| j                  | j                  | j                  || j                  j                  | j                  j                   | j                  j"                  | j                  j$                  dœ}|t        u rŠt        | j                  dd«      }|dk7  ri| j&                  j)                  d«      }t+        |«      }	t-        |	| j                  j.                  | j                  j1                  «       «      }
|
r|nd|d<   nd|d<    |di |¤Ž| _        y)aC  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Úproxy_protocolÚoffÚ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_versionrÇ   Nr   )r¡   r›   Ú_FAST_PARSER_INCOMPATIBLE_FLAGSrk   r   rê   ÚRuntimeErrorr¨   rä   Újoinrã   r÷   Ú_on_headers_completeÚ_on_bodyÚ_on_message_completerø   rù   rú   rû   r>   rÊ   r#   r/   Úproxy_allow_ipsÚproxy_allow_networksr½   )r   Úparser_settingÚincompatibleÚflagÚparser_classr÷   Úparser_kwargsÚ	cfg_proxyrÇ   Ú
normalizedÚtrusteds              r   rÚ   z#ASGIProtocol._setup_callback_parserö  s:  € ô ! §¡¨=¸&ÓAˆð ˆØ×8Ñ8ò 	*ˆDÜ�t—x‘x  uÕ-Ø×#Ñ# DÕ)ð	*ô
 �4—8‘8Ð-¨uÓ5¸Ò>Ø×ÑÐ 0Ô1à˜XÒ%Ü)‰LØ˜vÒ%Ø×5Ñ5Ô7Ü"Ð#QÓRÐRÜ×/Ò/Ü"ðIóð ñ Ü"ðGà—i‘i Ó-ñ.óð ô
 (×;Ñ;‰Là×2Ñ2Ô4Ü ×0Ò0¹Ü+×?Ñ?‘ä-�ð "ŸX™X×8Ñ8ÐØ Ò" |´~Ò'EØ!,Ðð
 $(×#<Ñ#<Ø—}‘}Ø#'×#<Ñ#<Ø"4Ø$(§H¡H×$AÑ$AØ(,¯©×(IÑ(IØ15·±×1[Ñ1[Ø26·(±(×2]Ñ2]ñ	
ˆð œ>Ñ)ô   §¡Ð*:¸EÓBˆIØ˜EÒ!ØŸ>™>×8Ñ8¸ÓD�Ü0°Ó:�
Ü.ØØ—H‘H×,Ñ,Ø—H‘H×1Ñ1Ó3ó�ñ
 @G±)ÈE�Ð.Ò/à27�Ð.Ñ/Ù ,Ñ =¨}Ñ =ˆÕr   c                 ó®  — t        j                  | j                  | j                  ¬«      | _        t        | j                  | «      | _        | j                  r@t        j                  | j                  «      | _
        | j                  �t        «       | _        y| j                  r| j                  j                  «        | j                  j                  dk(  S )z'Callback: request headers are complete.)Úis_sslFs   HEAD)r   Úfrom_parserr½   rÀ   r¿   ro   r¸   r±   r   Úupgrade_settingsr²   Ú	bytearrayr³   r¾   r=   ÚmethodrA   s    r   rÿ   z!ASGIProtocol._on_headers_completeH  s³   € ô !0× ;Ñ ;Ø×!Ñ!¨$¯,©,ô!
ˆÔô
 +¨4×+@Ñ+@À$ÓGˆÔà×ÒÜ)4×)EÑ)EØ×%Ñ%ó*'ˆDÔ&à×)Ñ)Ð5ô *3«�Ô&Øð ×ÒØ×Ñ×#Ñ#Ô%ð ×$Ñ$×+Ñ+¨wÑ6Ð6r   c                 ó˜   — | j                   �| xj                   |z  c_         y| j                  r| j                  j                  |«       yy)z#Callback: received body data chunk.N)r³   r¸   r}   r{   s     r   r   zASGIProtocol._on_bodyc  sF   € à×!Ñ!Ð-ð ×"Ò" eÑ+Õ"ØØ×ÒØ×Ñ×$Ñ$ UÕ+ð r   c                 óR   — | j                   r| j                   j                  «        yy)z$Callback: request is fully received.N)r¸   r   rA   s    r   r  z!ASGIProtocol._on_message_completen  s"   € à×ÒØ×Ñ×,Ñ,Õ.ð r   c                 óÀ  — t         j                  }|�8t        ||«      r,| j                  dt	        |«      «       | j                  «        yt         j                  }|�8t        ||«      r,| j                  dt	        |«      «       | j                  «        yt         j                  }|�8t        ||«      r,| j                  dt	        |«      «       | j                  «        yy)z�Handle gunicorn_h1c exceptions with appropriate HTTP status codes.

        Returns True if the exception was handled, False otherwise.
        éž  Té¯  é�  F)r¨   rå   r&   Ú_send_error_responseÚstrÚ_close_transportræ   rç   )r   ÚexcÚh1c_limit_lineÚh1c_limit_headersÚh1c_chunk_exts        r   Ú_handle_h1c_exceptionz"ASGIProtocol._handle_h1c_exceptions  sÀ   € ô &×=Ñ=ˆØÐ%¬*°S¸.Ô*IØ×%Ñ% c¬3¨s«8Ô4Ø×!Ñ!Ô#ØÜ(×CÑCÐØÐ(¬Z¸Ð=NÔ-OØ×%Ñ% c¬3¨s«8Ô4Ø×!Ñ!Ô#ØÜ$×AÑAˆØÐ$¬°C¸Ô)GØ×%Ñ% c¬3¨s«8Ô4Ø×!Ñ!Ô#ØØr   c                 óx  — | j                   r| j                   j                  |«       y| j                  �| j                  |«       y| j                  r| j                  j                  |«       n| j
                  r| j                  |«      sy| j                  s"| j                  «       r| j                  «        yyy)z/Called when data is received on the connection.N)
rÂ   Ú	feed_datar¯   Ú	_h2c_feedr®   r½   rÝ   rº   Ú_is_buffer_fullÚ_pause_reading)r   Údatas     r   Údata_receivedzASGIProtocol.data_receivedŠ  s–   € à�?Š?à�O‰O×%Ñ% dÔ+ØØ×ÑÐ'Ø�N‰N˜4Ô ØØ�;Š;à�K‰K×!Ñ! $Õ'Ø×"Ò"à×-Ñ-¨dÔ3Øð ×#Ò#¨×(<Ñ(<Ô(>Ø×ÑÕ!ð )?Ð#r   c                 óÈ  — | xj                   |z  c_         t        j                  | j                   «      }|t        j                  u ry| j                   dc}| _         | j	                  «        |t        j
                  u r| j                  |«       yt        j                  | j                  «      r#| j                  dd«       | j                  «        y| j                  |«       y)z7Accumulate bytes until the connection preface resolves.Nr  ú!Invalid HTTP/2 connection preface)r¯   r   Úpreface_matchÚPARTIALÚ_h2c_cancel_timerÚMATCHÚ
_h2c_startÚmismatch_is_errorr›   r  r  rÕ   )r   r%  ÚstaterÞ   s       r   r"  zASGIProtocol._h2c_feedŸ  s¼   € à×Ò˜DÑ ÕÜ×)Ñ)¨$×*:Ñ*:Ó;ˆØ”K×'Ñ'Ñ'ØØ%)×%5Ñ%5°tÐ"ˆ�$Ô"Ø×ÑÔ Ø”K×%Ñ%Ñ%Ø�O‰O˜HÔ%ØÜ×(Ñ(¨¯©Ô2ð ×%Ñ% cÐ+NÔOØ×!Ñ!Ô#Øð 	×Ñ˜(Õ#r   c                 óô   — t        j                  «       | _        | j                  j                  j                  | j                  | j                  d«      «      | _        | j                  j                  |«       y)z;Commit to HTTP/2 and replay the bytes read while undecided.N)
r;   rÌ   r®   rª   r¤   rÍ   rÎ   r>   rµ   r!  ©r   rÞ   s     r   r-  zASGIProtocol._h2c_start´  sV   € ä×*Ñ*Ó,ˆŒØ—[‘[×%Ñ%×1Ñ1à×)Ñ)¨$¯.©.¸$Ó?ó
ˆŒ
ð 	�‰×Ñ˜hÕ'r   c                 óú   — d| _         | j                  €y| j                  dc}| _        t        j                  | j                  «      s| j                  |«       y| j                  dd«       | j                  «        y)a:  Nothing conclusive arrived in time.

        With prior knowledge alone the peer is expected to speak HTTP/2, so
        stalling mid-preface is refused rather than downgraded. Where an
        upgrade is also on offer, a quiet client is just a quiet client and
        the ordinary HTTP/1 timeouts apply.
        Nr  r(  )r°   r¯   r   r.  r›   rÕ   r  r  r1  s     r   rÔ   z#ASGIProtocol._h2c_undecided_timeout½  so   € ð ˆŒØ×ÑÐ#ØØ%)×%5Ñ%5°tÐ"ˆ�$Ô"Ü×,Ñ,¨T¯X©XÔ6Ø×Ñ˜hÔ'ØØ×!Ñ! #Ð'JÔKØ×ÑÕr   c                 ó`   — | j                   �"| j                   j                  «        d | _         y y ©N)r°   ÚcancelrA   s    r   r+  zASGIProtocol._h2c_cancel_timerÏ  s(   € Ø�?‰?Ð&Ø�O‰O×"Ñ"Ô$Ø"ˆD�Oð 'r   c                 ó8  — 	 | j                   j                  |«       | j                  �| j                  «       S y# t        $ r5}| j                  dt        |«      «       | j                  «        Y d}~yd}~wt        $ r5}| j                  dt        |«      «       | j                  «        Y d}~yd}~wt        t        f$ r5}| j                  dt        |«      «       | j                  «        Y d}~yd}~wt        $ r}| j                  |«      rY d}~y‚ d}~ww xY w)z�Feed data to callback parser, handling parse errors.

        Returns True if parsing should continue, False if connection was closed.
        NTr  Fr  r  )r½   r}   r²   Ú_h2c_arm_upgrader   r  r  r  r   r	   r   Ú	Exceptionr  ©r   r%  Úes      r   rÝ   z"ASGIProtocol._feed_callback_parserÔ  sæ   € ð
	Ø×!Ñ!×&Ñ& tÔ,Ø×)Ñ)Ð5Ø×,Ñ,Ó.Ð.ØøÜò 	Ø×%Ñ% c¬3¨q«6Ô2Ø×!Ñ!Ô#ÜûÜ"ò 	Ø×%Ñ% c¬3¨q«6Ô2Ø×!Ñ!Ô#ÜûÜ%¤zÐ2ò 	Ø×%Ñ% c¬3¨q«6Ô2Ø×!Ñ!Ô#ÜûÜò 	à×)Ñ)¨!Ô,ÜØûð		ús?   ‚6: º	DÁ+A3Á3DÁ?+B/Â/DÃ+C1Ã1DÃ=DÄDÄDc                 ó²  — | j                   }|j                  sy|j                  rKd| _        d| _        | j                  dd«       | j                  «        | j                  j                  «        y|j                  «       }d| _         t        j                  «       | _        |r| j                  j                  |«       | j                  j                  «        y)aÙ  Hand the connection over to HTTP/2 once the request is complete.

        Runs synchronously, inside data_received(), because that is what stops
        the connection preface and the frames behind it from reaching the
        HTTP/1 parser. Installing the reader here also gives later
        data_received() calls somewhere to land while the connection loop is
        still waking up.

        Returns True to keep feeding HTTP/1, as _feed_callback_parser does.
        TNr  zUpgrade request tail too largeF)r½   Úis_completeÚremaining_truncatedr²   r³   r  r  r¾   r=   rÙ   r;   rÌ   r®   r!  )r   ÚparserÚpendings      r   r7  zASGIProtocol._h2c_arm_upgradeð  sº   € ð ×&Ñ&ˆØ×!Ò!ØØ×%Ò%ð *.ˆDÔ&Ø%)ˆDÔ"Ø×%Ñ% cÐ+KÔLØ×!Ñ!Ô#ð ×Ñ×#Ñ#Ô%ØØ×"Ñ"Ó$ˆØ $ˆÔÜ×*Ñ*Ó,ˆŒÙØ�K‰K×!Ñ! 'Ô*Ø×Ñ×ÑÔ!Ør   c                 ó    — | j                   rBt        | j                   d«      r,t        | j                   j                  «      | j                  kD  S y)z/Check if internal buffer is full (HTTP/2 only).Ú_bufferF)r®   rË   ÚlenrA  r»   rA   s    r   r#  zASGIProtocol._is_buffer_full  s9   € à�;Š;œ7 4§;¡;°	Ô:Ü�t—{‘{×*Ñ*Ó+¨d×.CÑ.CÑCÐCØr   c                 ó¦   — | j                   s0| j                  r#d| _         	 | j                  j                  «        yyy# t        t        f$ r Y yw xY w)z1Pause reading from transport due to backpressure.TN)rº   r>   rE   ÚAttributeErrorrý   rA   s    r   r$  zASGIProtocol._pause_reading  sO   € à×#Ò#¨¯ªØ#'ˆDÔ ðØ—‘×,Ñ,Õ.ð )7Ð#øô #¤LÐ1ò Ùðúó   ¡> ¾AÁAc                 ó¦   — | j                   r0| j                  r#d| _         	 | j                  j                  «        yyy# t        t        f$ r Y yw xY w)zResume reading from transport.FN)rº   r>   rG   rD  rý   rA   s    r   Ú_resume_readingzASGIProtocol._resume_reading!  sO   € à×Ò D§N¢NØ#(ˆDÔ ðØ—‘×-Ñ-Õ/ð %3Ðøô #¤LÐ1ò ÙðúrE  c                 óò   — | j                   r| j                   j                  «        | j                  j                  }|dkD  r6| j                  j
                  j                  || j                  «      | _         yy)z6Arm keepalive timeout timer after response completion.r   N)r¼   r5  r›   Ú	keepaliverª   r¤   rÒ   Ú_keepalive_timeout)r   Úkeepalive_timeouts     r   Ú_arm_keepalive_timerz!ASGIProtocol._arm_keepalive_timer*  sb   € à×!Ò!Ø×"Ñ"×)Ñ)Ô+Ø ŸH™H×.Ñ.ÐØ˜qÒ Ø%)§[¡[×%5Ñ%5×%@Ñ%@Ø! 4×#:Ñ#:ó&ˆDÕ"ð !r   c                 ó`   — | j                   r"| j                   j                  «        d| _         yy)z0Cancel keepalive timer when new request arrives.N)r¼   r5  rA   s    r   Ú_cancel_keepalive_timerz$ASGIProtocol._cancel_keepalive_timer4  s*   € à×!Ò!Ø×"Ñ"×)Ñ)Ô+Ø%)ˆDÕ"ð "r   c                 ó$   — | j                  «        y)z&Called when keepalive timeout expires.N)r  rA   s    r   rJ  zASGIProtocol._keepalive_timeout:  s   € à×ÑÕr   c                 óÈ  — | j                   ryd| _         d| _        d| _        | j                  «        | j                  xj
                  dz  c_        | j                  «        | j                  r| j                  j                  «        | j                  r| j                  j                  «        | j                  �| j                  j                  «        | j                  rƒ| j                  j                  «       sht        | j                  dd«      }|dkD  r1| j                  j                   j#                  || j$                  «       y| j                  j'                  «        yyy)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
        NTr[   Úasgi_disconnect_grace_periodé   r   )r·   rs   r¯   r+  rª   rÉ   rN  r®   Úfeed_eofrÂ   r¸   r�   rµ   r…   r¡   r›   r¤   rÒ   Ú_cancel_task_if_pendingr5  )r   r  Úgrace_periods      r   Úconnection_lostzASGIProtocol.connection_lost>  s  € ð ×"Ò"Øà"&ˆÔØˆŒàˆÔØ×ÑÔ Ø�‰×Ò Ñ!Õð 	×$Ñ$Ô&à�;Š;Ø�K‰K× Ñ Ô"ð �?Š?Ø�O‰O×$Ñ$Ô&ð ×ÑÐ*Ø×Ñ×1Ñ1Ô3ð �:Š:˜dŸj™jŸo™oÔ/Ü" 4§8¡8Ð-KÈQÓOˆLØ˜aÒØ—‘× Ñ ×+Ñ+Ø Ø×0Ñ0õð —
‘
×!Ñ!Õ#ð 0ˆ:r   c                 óˆ   — | j                   r6| j                   j                  «       s| j                   j                  «        yyy)z9Cancel the task if it's still pending after grace period.N)rµ   r…   r5  rA   s    r   rT  z$ASGIProtocol._cancel_task_if_pendingp  s-   € à�:Š:˜dŸj™jŸo™oÔ/Ø�J‰J×ÑÕð 0ˆ:r   c                 óR   — | j                   r| j                   j                  «        yy)z>Called by transport when write buffer exceeds high water mark.N)rÁ   rJ   rA   s    r   rJ   zASGIProtocol.pause_writingu  s"   € à×ÒØ×Ñ×,Ñ,Õ.ð r   c                 óR   — | j                   r| j                   j                  «        yy)zBCalled by transport when write buffer drains below low water mark.N)rÁ   rL   rA   s    r   rL   zASGIProtocol.resume_writingz  s"   € à×ÒØ×Ñ×-Ñ-Õ/ð r   c                 ó>  — 	 | j                   j                  |«       y# t        $ re}|j                  t        j                  t        j
                  t        j                  fvr | j                  j                  d«       Y d}~yY d}~yd}~wt        t        f$ r Y yw xY w)ax  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)r>   ÚwriteÚOSErrorÚerrnoÚEPIPEÚ
ECONNRESETÚENOTCONNr«   Ú	exceptionrý   rD  r9  s      r   Ú_safe_writezASGIProtocol._safe_write  sw   € ð	Ø�N‰N× Ñ  Õ&øÜò 	EØ�w‰wœuŸ{™{¬E×,<Ñ,<¼e¿n¹nÐMÑMØ—‘×"Ñ"Ð#C×DÑDô NûäœnÐ-ò 	áð	ús   ‚ ž	B§ABÂBÂBc              ƒ   óÞ  K  — 	 | j                   j                  d«      }| j                   j                  d«      }t        | j                  dd«      }|dk(  r,| j	                  ||«      ƒ d{  –—†  	 | j                  «        y| j                  �sJ| xj                  dz  c_        | j                  «        | j                  j                  «       s#	 | j                  j                  «       ƒ d{  –—†  | j                  s| j                  €�nÎ| j                  }| j                  |«      }| j                   �| j#                  |«      ƒ d{  –—†  �nŠ| j%                  |«      r| j'                  |||«      ƒ d{  –—†  �n\| j)                  |||«      ƒ d{  –—† }| j*                  xj,                  dz  c_        | j*                  j,                  | j*                  j.                  k\  r.| j0                  j3                  d«       d	| j*                  _        d	}|r| j*                  j4                  sn®| j                  j6                  sn—| j8                  }|�|j:                  sn|| j=                  «        | j>                  r| j>                  jA                  «        d| _        d| _        | j                  jC                  «        | jE                  «        | j                  s�ŒJ| j                  «        y7 �Œ7 �Œ# t        j                  $ r Y Œ,w xY w7 �ŒÁ7 �Œ–7 �Œ|# t        j                  $ r Y ŒNtF        $ r&}| j0                  jI                  d
|«       Y d}~Œwd}~ww xY w# | j                  «        w xY w­w)aB  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.
        rÇ   Úsocknamerw   ÚhttpÚuwsgiNr[   ú,Autorestarting worker after current request.FzError handling connection: %s)%r>   rÊ   r¡   r›   Ú_handle_connection_uwsgir  rs   r¶   rN  r¾   Úis_setr@   r;   ÚCancelledErrorr¿   Ú_effective_peernamer²   Ú_handle_h2c_upgradeÚ_is_websocket_upgradeÚ_handle_websocketÚ_handle_http_requestrª   ÚnrÚmax_requestsr«   ÚinfoÚaliverI  r¸   rq   rG  r½   ÚresetrI   rL  r8  ra  )	r   rÇ   rd  Úprotocol_typerv   Úeffective_peerrI  Úreceiverr:  s	            r   rÜ   zASGIProtocol._handle_connection’  sü  è ø€ ð[	$Ø—~‘~×4Ñ4°ZÓ@ˆHØ—~‘~×4Ñ4°ZÓ@ˆHô $ D§H¡H¨j¸&ÓAˆMØ Ò'Ø×3Ñ3°H¸hÓG×GÐGØðf ×!Ñ!Õ#ðc —l“lØ—’ !Ñ#•Ø×,Ñ,Ô.ð ×*Ñ*×1Ñ1Ô3ðØ"×1Ñ1×6Ñ6Ó8×8Ð8ð —<’< 4×#8Ñ#8Ð#@Ùà×/Ñ/�ð "&×!9Ñ!9¸(Ó!C�ð ×-Ñ-Ð9Ø×2Ñ2°7Ó;×;Ð;Ùð ×-Ñ-¨gÔ6Ø×0Ñ0°¸(ÀNÓS×SÐSÙð #'×";Ñ";Ø˜X ~ó#÷ �	ð
 —‘—’ !Ñ#•ð —;‘;—>‘> T§[¡[×%=Ñ%=Ò=Ø—H‘H—M‘MÐ"PÔQØ(-�D—K‘KÔ%Ø %�Iá ¨¯©×(9Ò(9Øð —x‘x×)Ò)Øð  ×.Ñ.�ØÐ'°×0BÒ0BØð ×$Ñ$Ô&ð ×(Ò(Ø×)Ñ)×/Ñ/Ô1ð )-�Ô%Ø&*�Ô#Ø×#Ñ#×)Ñ)Ô+ð ×)Ñ)Ô+ðU —l”lðb ×!Ñ!Õ#ði Hùð 9úÜ"×1Ñ1ò Ùðúð <ùð
 TùðúôZ ×%Ñ%ò 	ÙÜò 	CØ�H‰H×ÑÐ>À×BÑBûð	Cûð ×!Ñ!Õ#üsÎ   ‚M-„A'L Á+K*Á,L Á1M-ÂAL ÃK0 Ã,K-Ã-K0 Ã1AL ÅL	Å	-L Å6LÅ7L ÆLÆEL ËM-Ë*L Ë-K0 Ë0LÌL ÌLÌL ÌL ÌL ÌMÌ%M Ì'MÌ/MÍM ÍMÍM ÍM*Í*M-c              ƒ   ó¤  K  — t        | j                  «      }| j                  �sc| xj                  dz  c_        	 t	        j
                  | j                  ||| j                  «      ƒ d{  –—† }| j                  |«      r| j                  |||«      ƒ d{  –—†  y| j                  |||«      ƒ d{  –—† }| j                  xj                  dz  c_        | j                  j                  | j                  j                   k\  r.| j                  j#                  d«       d| j                  _        d}|r| j                  j$                  sy| j                  j&                  sy|j)                  «       ƒ d{  –—†  | j                  s�Œbyy7 �Œ# t        $ r Y yt        $ r&}| j                  j                  d|«       Y d}~yd}~ww xY w7 �Œ27 �Œ7 ŒY­w)z0Handle uWSGI protocol connections (legacy path).r[   NzuWSGI parse error: %srg  F)r   r®   rs   r¶   r
   Úparser›   r   r   r«   Údebugrm  rn  ro  rª   rp  rq  rr  rs  rI  Ú
drain_body)r   rÇ   rd  Úunreaderrv   r:  rI  s          r   rh  z%ASGIProtocol._handle_connection_uwsgi÷  sz  è ø€ ä  §¡Ó-ˆà—,“,Ø�NŠN˜aÑ�NðÜ 1× 7Ñ 7Ø—H‘HØØØ—N‘Nó	!÷ �ð ×)Ñ)¨'Ô2Ø×,Ñ,¨W°hÀÓI×IÐIØð #×7Ñ7Ø˜ 8ó÷ ˆIð
 �K‰K�NŠN˜aÑ�Nð �{‰{�~‰~ §¡×!9Ñ!9Ò9Ø—‘—‘ÐLÔMØ$)�—‘Ô!Ø!�	á D§K¡K×$5Ò$5Øà—8‘8×%Ò%Øà×$Ñ$Ó&×&Ð&ðS —,–,ðúô ò ÙÜ&ò Ø—‘—‘Ð6¸Ô:Üûðúð Jùðùð& 'úsƒ   ‚8G»/F Á*F	Á+F Á/'GÂGÂGÂ2GÂ3CGÅ4GÅ5GÆGÆ	F Æ	GÆGÆGÆG Æ;GÇ GÇGÇGÇGc              ƒ   ó  K  — | j                   }t        | j                  xs d«      }d| _         d| _        | j                  j	                  t
        j                  «       | j                  | j                  d|||f¬«      ƒ d{  –—†  y7 Œ­w)zÐServe an Upgrade: h2c request over HTTP/2.

        The 101 goes out here rather than in _h2c_arm_upgrade so that nothing
        can write between it and the SETTINGS frame the HTTP/2 handler sends.
        r   N)Úupgrade)r²   ri   r³   r>   r[  r   ÚUPGRADE_101rÎ   )r   rv   ÚsettingsrŒ   s       r   rl  z ASGIProtocol._handle_h2c_upgrade&  s   è ø€ ð ×-Ñ-ˆÜ�T×+Ñ+Ò2¨sÓ3ˆØ%)ˆÔ"Ø!%ˆÔØ�‰×Ñœ[×4Ñ4Ô5Ø×+Ñ+Ø�N‰N˜D¨8°W¸dÐ*Cð ,ó 
÷ 	
ò 	
ús   ‚BBÂB	ÂBc                 óÈ   — |j                   dk7  ryd}d}|j                  D ]1  \  }}|dk(  r|j                  «       }Œ|dk(  sŒ"|j                  «       }Œ3 |dk(  xr |xr d|v S )a	  Check 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Ú	websocketr~  )r  rh   Úlower)r   rv   r~  Ú
connectionrl   rm   s         r   rm  z"ASGIProtocol._is_websocket_upgrade5  sv   € ð �>‰>˜UÒ"ØàˆØˆ
Ø"Ÿ?™?ò 	+‰KˆD�%Ø�yÒ ØŸ+™+›-‘Ø˜Ó%Ø"Ÿ[™[›]‘
ð		+ð
 ˜+Ñ%ÒP¨*ÒP¸ÀjÐ9PÐPr   c              ƒ   óà   K  — ddl m} d| _        | j                  |||«      } || j                  || j
                  | j                  «      }|| _        |j                  «       ƒ d{  –—†  y7 Œ­w)z!Handle WebSocket upgrade request.r   )ÚWebSocketProtocolN)	Úgunicorn.asgi.websocketr‰  r½   Ú_build_websocket_scoper>   r­   r«   rÂ   Úrun)r   rv   rd  rÇ   r‰  ÚscopeÚws_protocols          r   rn  zASGIProtocol._handle_websocketJ  s_   è ø€ å=ð !%ˆÔà×+Ñ+¨G°X¸xÓHˆÙ'Ø�N‰N˜E 4§8¡8¨T¯X©Xó
ˆð
 &ˆŒà�o‰oÓ×Òús   ‚A$A.Á&A,Á'A.c              ƒ   ó8	  ‡ ‡‡‡‡‡‡‡‡‡‡K  — ‰ j                  ‰||«      }dŠdŠdŠdŠdŠdŠd‰ _        dŠg ŠdŠ‰ j                  }ˆˆˆˆˆˆˆˆˆˆ ˆfd„}‰ j                  j                  }	 t        j                  «       }‰ j                  j                  ‰ j                  ‰«       ‰ j                  ||j                  |«      ƒ d{  –—†  ‰�‰‚‰s‰ j                  dd«       dŠ	 t!        t        j                  «       |z
  «      }	|r?‰ j#                  ‰||«      }
t%        ‰‰‰«      }‰ j                  j'                  |‰|
|	«       nd}
d}‰ j                  j)                  ‰ j                  ‰|
|«       ‰j/                  «       ry‰ j                  j0                  xr ‰ j                  j2                  S 7 Œë# t        j                  $ rÖ ‰ j                  j                  d«       Y 	 t!        t        j                  «       z
  «      }	|r?‰ j#                  ‰||«      }
t%        ‰‰‰«      }‰ j                  j'                  |‰|
|	«       nd}
d}‰ j                  j)                  ‰ j                  ‰|
|«       y# t*        $ r ‰ j                  j-                  d«       Y yw xY wt*        $ �r
 ‰r‰ j                  j                  d	«       n1‰ j                  j-                  d
«       ‰s‰ j                  dd«       dŠY 	 t!        t        j                  «       z
  «      }	|r?‰ j#                  ‰||«      }
t%        ‰‰‰«      }‰ j                  j'                  |‰|
|	«       nd}
d}‰ j                  j)                  ‰ j                  ‰|
|«       y# t*        $ r ‰ j                  j-                  d«       Y yw xY ww xY w# t*        $ r ‰ j                  j-                  d«       Y �Œfw xY w# 	 t!        t        j                  «       z
  «      }	|r?‰ j#                  ‰||«      }
t%        ‰‰‰«      }‰ j                  j'                  |‰|
|	«       nd}
d}‰ j                  j)                  ‰ j                  ‰|
|«       w # t*        $ r ‰ j                  j-                  d«       Y w w xY wxY w­w)zHandle a single HTTP request.FNéô  r   c              “   óH  •K  — ‰j                   ry | d   }|dk(  r7| j                  d«      }| j                  dg «      }‰j                  ||‰«       y |dk(  �r‰rt        d«      Šy dŠ| d   Š| j                  dg «      Šd}d}‰D ]E  \  }}t	        |t
        «      r|j                  «       n|j                  «       }|d	v rd}Œ=|d
v sŒBd}dŠŒG ‰j                  ‰j                  ‰«      Š‰r-|s|r)‰j                  ‰‰«      Š‰j                  ‰«      rd}d}dŠ| xr | xr ‰j                  dk\  xr ‰ }	|	rdŠt        ‰«      dgz   Š‰j                  ‰‰‰«       y |dk(  �r<‰st        d«      Šy ‰rt        d«      Šy | j                  dd«      }
| j                  dd«      }‰r/|
r+‰s)‰j                  j                  d‰j                  ‰«       dŠd}
|
rO‰j!                  |
‰¬«       ‰t#        |
«      z  Š‰j$                  r"‰j$                  j'                  «       ƒ d {  –—†  |sw‰rD‰j(                  r&‰j+                  ‰j(                  dz   «       d ‰_        n@‰j+                  d«       n.‰j(                  r"‰j+                  ‰j(                  «       d ‰_        dŠy y y 7 Œ­w)Nrˆ   úhttp.response.informationalr_   rh   úhttp.response.startúResponse already startedTF)ó   content-lengthúcontent-length)ó   transfer-encodingútransfer-encoding©r[   r[   )r—  s   chunkedúhttp.response.bodyúResponse not startedúResponse already completerŒ   r   r�   ú\ASGI app sent body bytes on a no-body response (method=%s status=%s); dropping per RFC 9110.)r‘   s   0

)rs   ÚgetÚ_send_informationalrý   r&   r  r†  Ú_response_omits_bodyr  Ú_strip_body_framing_headersÚ _response_forbids_content_lengthr^   ÚlistÚ_send_response_startr«   ÚwarningÚ
_send_bodyrB  rÁ   rB   r¹   rb  )ÚmessageÚmsg_typeÚinfo_statusÚinfo_headersÚhas_content_lengthÚhas_transfer_encodingrl   Ú_Ú
name_lowerÚneeds_chunkedrŒ   r�   Úexc_to_raiseÚ
omits_bodyÚomits_body_warnedrv   Úresponse_completeÚresponse_headersÚresponse_sentÚresponse_startedÚresponse_statusr   Úuse_chunkeds               €€€€€€€€€€€r   Úsendz/ASGIProtocol._handle_http_request.<locals>.sendp  sò  øè ø€ ð �|Š|Øà˜v‘ˆHàÐ8Ò8à%Ÿk™k¨(Ó3�Ø&Ÿ{™{¨9°bÓ9�Ø×(Ñ(¨°lÀGÔLØàÐ0Ó0Ù#Ü#/Ð0JÓ#K�LØØ#'Ð Ø")¨(Ñ"3�Ø#*§;¡;¨y¸"Ó#=Ð ð &+Ð"Ø(-Ð%Ø/ò +‘G�D˜!Ü1;¸DÄ#Ô1F §¡¤ÈDÏJÉJËL�JØ!Ð%JÑJØ-1Ñ*Ø#Ð'RÒRØ04Ð-Ø&*™ð+ð "×6Ñ6°w·~±~ÀÓW�
ÙÑ#5Ñ9NØ'+×'GÑ'GØ(¨/ó(Ð$ð ×<Ñ<¸_ÔMØ-2Ð*Ø,1Ð)Ø"'�Kð +Ð*ò 'Ø1Ð1ò'àŸ™¨6Ñ1ò'ð '˜ð	 ñ !Ø"&�KÜ'+Ð,<Ó'=ÐAcÐ@dÑ'dÐ$à×)Ñ)¨/Ð;KÈWÕUàÐ1Ó1Ù'Ü#/Ð0FÓ#G�LØÙ$Ü#/Ð0KÓ#L�LØà—{‘{ 6¨3Ó/�Ø#ŸK™K¨°UÓ;�	ñ ÙÑ$5ØŸ™×(Ñ(ðLà#ŸN™N¨Oôð
 -1Ð)Ø�DáØ—O‘O D°+�OÔ>Ø!¤S¨£YÑ.�Mà×)Ò)Ø"×0Ñ0×6Ñ6Ó8×8Ð8á Ù"à×0Ò0Ø ×,Ñ,¨T×-BÑ-BÀ\Ñ-QÔRØ48˜DÕ1à ×,Ñ,¨\Õ:Ø×.Ò.à×(Ñ(¨×)>Ñ)>Ô?Ø04˜Ô-Ø(,Ñ%ð !ðE 2ð@ 9ús   ƒCJ"ÃEJ"È J È!B J"úInternal Server Errorz'Request cancelled (client disconnected)úException in post_request hookz7Exception after response complete (client disconnected)úError in ASGI application)Ú_build_http_scoper¹   r¸   r«   Úaccess_log_enabledrQ   Ú	monotonicr›   Úpre_requestrª   r­   r”   r  r;   rj  rz  r   Ú_build_environre   ÚaccessÚpost_requestr8  ra  Úshould_closers  rI  )r   rv   rd  rÇ   r�  Úbody_receiverr¹  r¾  Úrequest_startÚrequest_timeÚenvironÚrespr°  r±  r²  r³  r´  rµ  r¶  r·  r¸  s   ``          @@@@@@@@@r   ro  z!ASGIProtocol._handle_http_request[  s*  ÿúè ø€ à×&Ñ& w°¸(ÓCˆØ ÐØ!ÐØˆØˆØˆ
Ø!Ðð !%ˆÔð ˆØÐØˆð ×+Ñ+ˆ÷r	-ö r	-ðj "ŸX™X×8Ñ8Ðð/	EÜ ŸN™NÓ,ˆMØ�H‰H× Ñ  §¡¨gÔ6à—(‘(˜5 -×"7Ñ"7¸Ó>×>Ð>àÐ'Ø"Ð"ñ $Ø×)Ñ)¨#Ð/FÔGØ"%�ð.EÜ+¬D¯N©NÓ,<¸}Ñ,LÓM�á%Ø"×1Ñ1°'¸8ÀXÓN�GÜ+¨OÐ=MÈ}Ó]�DØ—H‘H—O‘O D¨'°7¸LÕIà"�GØ�DØ—‘×%Ñ% d§k¡k°7¸GÀTÔJð
 ×ÑÔ!Øà�{‰{× Ñ Ò7 T§X¡X×%7Ñ%7Ð7ðc ?ùô ×%Ñ%ò 	à�H‰H�N‰NÐDÔEØð$EÜ+¬D¯N©NÓ,<¸}Ñ,LÓM�á%Ø"×1Ñ1°'¸8ÀXÓN�GÜ+¨OÐ=MÈ}Ó]�DØ—H‘H—O‘O D¨'°7¸LÕIà"�GØ�DØ—‘×%Ñ% d§k¡k°7¸GÀTÕJøÜò EØ—‘×"Ñ"Ð#CÖDðEúô9 ó 
	ñ !Ø—‘—‘ÐXÕYà—‘×"Ñ"Ð#>Ô?Ù'Ø×-Ñ-¨cÐ3JÔKØ&)�OØðEÜ+¬D¯N©NÓ,<¸}Ñ,LÓM�á%Ø"×1Ñ1°'¸8ÀXÓN�GÜ+¨OÐ=MÈ}Ó]�DØ—H‘H—O‘O D¨'°7¸LÕIà"�GØ�DØ—‘×%Ñ% d§k¡k°7¸GÀTÕJøÜò EØ—‘×"Ñ"Ð#CÖDðEúð9
	ûô8 ò EØ—‘×"Ñ"Ð#C×DðEûðEÜ+¬D¯N©NÓ,<¸}Ñ,LÓM�á%Ø"×1Ñ1°'¸8ÀXÓN�GÜ+¨OÐ=MÈ}Ó]�DØ—H‘H—O‘O D¨'°7¸LÕIà"�GØ�DØ—‘×%Ñ% d§k¡k°7¸GÀTÕJøÜò EØ—‘×"Ñ"Ð#CÖDðEÿsä   �ARÁ,AF4 ÃF2ÃF4 Ã&BN2 Å3?RÆ2F4 Æ4.N/Ç"O Ç$BI2 É1RÉ2$JÊRÊJÊRÊAN/Ë4O Ë6BN ÎRÎ$N+Î(RÎ*N+Î+RÎ.N/Î/O Î2$OÏRÏOÏRÏRÏBQ-Ñ,RÑ-$RÒRÒRÒRÒRc                 ó,  — t        |dd«      }t        |t        «      rt        |«      }nUg }|j                  D ]D  \  }}|j	                  |j                  «       j                  d«      |j                  d«      f«       ŒF t        |«      }t        |«      }	ddddœ|j                  d   › d	|j                  d
   › �|j                  |j                  |j                  |j                  r|j                  nd|j                  r|j                  j                  d«      nd| j                  j                  xs d|||	dœ}
t!        | j"                  d«      r| j"                  j$                  |
d<   t!        |d«      rd|j&                  |j(                  dœi|
d<   |
S )z*Build ASGI HTTP scope from parsed request.Úheaders_bytesNr2   re  ú3.0ú2.4©r^   Úspec_versionr   rZ   r[   r   Ú ©rˆ   r¬   Úhttp_versionr  ÚschemeÚpathÚraw_pathÚquery_stringÚ	root_pathrh   ÚserverÚclientr/  Úpriority_weightúhttp.response.priority©ÚweightÚ
depends_onÚ
extensions)r¡   r&   r£  rh   rk   r†  rT   r#   r^   r  rÓ  rÔ  rÕ  Úqueryr›   r×  rË   rª   r/  rÚ  Úpriority_depends_on)r   rv   rd  rÇ   rË  rh   rl   rm   rØ  rÙ  r�  s              r   r½  zASGIProtocol._build_http_scope  sv  € ô   ¨¸$Ó?ˆÜ�m¤TÔ*Ü˜=Ó)‰GàˆGØ&Ÿ™ò Z‘��eØ—‘ §
¡
£× 3Ñ 3°IÓ >ÀÇÁÈYÓ@WÐXÕYðZô % XÓ.ˆÜ$ XÓ.ˆð Ø %°uÑ=Ø&Ÿ™¨qÑ1Ð2°!°G·O±OÀAÑ4FÐ3GÐHØ—n‘nØ—n‘nØ—L‘LØ,3×,<Ò,<˜×(Ò(À#Ø?F¿}º}˜GŸM™M×0Ñ0°Ô;ÐRUØŸ™×+Ñ+Ò1¨rØØØñ
ˆô  �4—;‘; Ô(Ø!Ÿ[™[×.Ñ.ˆE�'‰Nô �7Ð-Ô.à(Ø%×5Ñ5Ø")×"=Ñ"=ñ+ð#ˆE�,Ñð ˆr   c           	      ó  — |j                   |j                  |j                  |j                  xs dd|j                  d   › d|j                  d   › �|r|d   nddœ}|j
                  D ]  \  }}d|j                  dd	«      z   }|||<   Œ! |S )
z8Build minimal WSGI-like environ dict for access logging.rÐ  rY   r   rZ   r[   ú-©ÚREQUEST_METHODÚRAW_URIÚ	PATH_INFOÚQUERY_STRINGÚSERVER_PROTOCOLÚREMOTE_ADDRÚHTTP_r­  )r  ÚurirÔ  rà  r^   rh   Úreplace©r   rv   rd  rÇ   rÈ  rl   rm   ra   s           r   rÁ  zASGIProtocol._build_environK  s™   € ð &Ÿn™nØ—{‘{Ø Ÿ™Ø#ŸM™MÒ/¨RØ!& w§¡°qÑ'9Ð&:¸!¸G¿O¹OÈAÑ<NÐ;OÐPÙ*2˜8 Aš;¸ñ
ˆð #Ÿ?™?ò 	!‰KˆD�%Ø˜DŸL™L¨¨cÓ2Ñ2ˆCØ ˆG�CŠLð	!ð ˆr   c                 ó  — g }|j                   D ]D  \  }}|j                  |j                  «       j                  d«      |j                  d«      f«       ŒF g }|j                   D ]8  \  }}|dk(  sŒ|j	                  d«      D �cg c]  }|j                  «       ‘Œ }} n t        |«      }	t        |«      }
ddddœ|j                  d   › d	|j                  d
   › �|j                  dk(  rdnd|j                  |j                  r|j                  nd|j                  r|j                  j                  d«      nd| j                  j                  xs d||	|
|dœ}t        | j                  d«      r| j                  j                   |d<   |S c c}w )z/Build ASGI WebSocket scope from parsed request.r2   zSEC-WEBSOCKET-PROTOCOLú,r…  rÌ  rÍ  rÎ  r   rZ   r[   ÚhttpsÚwssÚwsr   rÐ  )rˆ   r¬   rÒ  rÓ  rÔ  rÕ  rÖ  r×  rh   rØ  rÙ  Úsubprotocolsr/  )rh   rk   r†  rT   ÚsplitÚstripr#   r^   rÓ  rÔ  rÕ  rà  r›   r×  rË   rª   r/  )r   rv   rd  rÇ   rh   rl   rm   rô  ÚsrØ  rÙ  r�  s               r   r‹  z#ASGIProtocol._build_websocket_scope]  sv  € ð ˆØ"Ÿ?™?ò 	V‰KˆD�%Ø�N‰N˜DŸJ™J›L×/Ñ/°	Ó:¸E¿L¹LÈÓ<SÐTÕUð	Vð ˆØ"Ÿ?™?ò 	‰KˆD�%ØÐ/Ó/Ø38·;±;¸sÓ3CÖD¨a §¡¥	ÐD�ÐDÙð	ô
 % XÓ.ˆÜ$ XÓ.ˆð  Ø %°uÑ=Ø&Ÿ™¨qÑ1Ð2°!°G·O±OÀAÑ4FÐ3GÐHØ&Ÿ~™~°Ò8‘e¸dØ—L‘LØ,3×,<Ò,<˜×(Ò(À#Ø?F¿}º}˜GŸM™M×0Ñ0°Ô;ÐRUØŸ™×+Ñ+Ò1¨rØØØØ(ñ
ˆô  �4—;‘; Ô(Ø!Ÿ[™[×.Ñ.ˆE�'‰Nàˆùò3  Es   ÂF	c           	      ó�  — |j                   dk  ry| j                  |«      }d|j                   d   › d|j                   d   › d|› d|› d�	}|D ]R  \  }}t        |t        «      r|j	                  d	«      }t        |t        «      r|j	                  d	«      }||› d
|› d�z  }ŒT |dz  }| j                  |j                  d	«      «       y)ao  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™  NrY   r   rZ   r[   r\   r1   r2   z: )r^   Ú_get_reason_phraser&   ri   rj   rb  rT   )r   r_   rh   rv   r`   Úresponserl   rm   s           r   rŸ  z ASGIProtocol._send_informationalƒ  sÕ   € ð �?‰?˜VÒ#Øà×(Ñ(¨Ó0ˆØ˜7Ÿ?™?¨1Ñ-Ð.¨a°·±ÀÑ0BÐ/CÀ1ÀVÀHÈAÈfÈXÐUYÐZˆà"ò 	/‰KˆD�%Ü˜$¤Ô&Ø—{‘{ 9Ó-�Ü˜%¤Ô'ØŸ™ YÓ/�Ø˜4˜&  5 '¨Ð.Ñ.‰Hð	/ð 	�FÑˆØ×Ñ˜Ÿ™¨Ó3Õ4r   c                 óò  — | j                  |«      }t        |j                  ||«      }|g}d}d}|D ]ê  \  }	}
t        |	t        «      r"|	j                  «       }|j                  |	«       n?|	j                  «       j                  d«      }|j                  |	j                  d«      «       |j                  d«       t        |
t        «      r|j                  |
«       n |j                  |
j                  d«      «       |j                  d«       |dk(  rd}Œã|dk(  sŒéd}Œì |s|j                  t        «       |s|j                  t        «       «       |j                  d«       dj                  |«      | _        y	)
z¨Send HTTP response status and headers.

        Uses cached status lines and headers for common cases to avoid
        repeated string formatting and encoding.
        Fr2   s   : ó   
s   dateTs   serverr   N)rù  rc   r^   r&   ri   r†  rk   rT   Ú_CACHED_SERVER_HEADERrW   rþ   r¹   )r   r_   rh   rv   r`   Ústatus_lineÚpartsÚhas_dateÚ
has_serverrl   rm   r®  s               r   r¤  z!ASGIProtocol._send_response_startŸ  s:  € ð ×(Ñ(¨Ó0ˆÜ-¨g¯o©o¸vÀvÓNˆð �ˆàˆØˆ
à"ò 	"‰KˆD�%Ü˜$¤Ô&Ø!ŸZ™Z›\�
Ø—‘˜TÕ"à!ŸZ™Z›\×0Ñ0°Ó;�
Ø—‘˜TŸ[™[¨Ó3Ô4à�L‰L˜Ôä˜%¤Ô'Ø—‘˜UÕ#à—‘˜UŸ\™\¨)Ó4Ô5à�L‰L˜Ô!ð ˜WÒ$Ø‘Ø˜yÓ(Ø!‘
ð+	"ñ0 Ø�L‰LÔ.Ô/ÙØ�L‰LÔ0Ó2Ô3à�‰�WÔð !$§¡¨£ˆÕr   c                 óJ  — t        | j                  dd«      dk(  r|S t        || j                  j                  | j                  j	                  «       «      s|S | j
                  }|rt        |dd«      nd}|s|S |j                  d«      }|j                  d«      }|�|€|S ||fS )aµ  Return the client address advertised via PROXY protocol if any.

        Falls back to the transport peername when PROXY protocol is disabled,
        the framing was absent, the parser is the C variant (which currently
        does not surface PROXY metadata), or the transport peer is not in
        ``proxy_allow_ips`` (defense-in-depth: ``_setup_callback_parser``
        already disables PROXY parsing for untrusted peers).
        rð   rñ   Úproxy_protocol_infoNÚclient_addrÚclient_port)r¡   r›   r/   r  r  r½   rž  )r   rÇ   r>  rr  r  r  s         r   rk  z ASGIProtocol._effective_peernameÑ  s«   € ô �4—8‘8Ð-¨uÓ5¸Ò>ØˆOÜ#ØØ�H‰H×$Ñ$Ø�H‰H×)Ñ)Ó+ô
ð
 ˆOØ×&Ñ&ˆÙ?EŒw�vÐ4°dÔ;È4ˆÙØˆOØ—h‘h˜}Ó-ˆØ—h‘h˜}Ó-ˆØÐ +Ð"5ØˆOØ˜[Ð)Ð)r   c                 ó<   — | dk(  xs |dv xs d|cxk  xr dk  S c S )zÛReturn True when the response MUST NOT have a body (RFC 9110).

        Applies to HEAD requests and to status codes that semantically carry no body:
        1xx informational, 204 No Content, 304 Not Modified.
        ÚHEAD)éÌ   é0  éd   éÈ   r   )r  r_   s     r   r   z!ASGIProtocol._response_omits_bodyì  s:   € ð �fÑò #Ø˜Ð#ò#à�fÖ"˜sÑ"ð	
ñ #ð	
r   c                 ó0   — | dk(  xs d| cxk  xr dk  S c S )u/  Per RFC 9110 Â§6.4.2 a server MUST NOT send Content-Length on 1xx
        or 204 responses.  HEAD and 304 are NOT covered: HEAD MAY include the
        Content-Length the same GET would have returned, and 304 MAY include
        the Content-Length the unconditional response would have carried.
        r  r
  r  r   )r_   s    r   r¢  z-ASGIProtocol._response_forbids_content_lengthù  s#   € ð ˜‰}Ò3  vÖ 3°Ñ 3Ð3Ñ 3Ð3r   c                 óð   — ddh}| j                  |«      r|j                  ddh«       |D ��cg c];  \  }}t        |t        «      r|j	                  «       n|j	                  «       |vr||f‘Œ= c}}S c c}}w )a4  Remove framing headers that must not appear on a no-body response.

        Transfer-Encoding is always stripped (chunked framing implies a body
        we will not send).  Content-Length is stripped only when the status
        forbids it (1xx / 204); HEAD and 304 keep app-supplied Content-Length.
        r—  r˜  r•  r–  )r¢  Úupdater&   r  r†  )ré   rh   r_   Ú	forbiddenÚnÚvs         r   r¡  z(ASGIProtocol._strip_body_framing_headers  sy   € ð *Ð+>Ð?ˆ	Ø×/Ñ/°Ô7Ø×ÑÐ/Ð1AÐBÔCà&÷
Ù�q˜!Ü'¨¬3Ô/�—‘”	°Q·W±W³YÀyÑPð �ŠFó
ð 	
ùó 
s   ®A A2c                 óª  — |r‹|r@t        |«      }t        j                  |«      xs |d›d�j                  d«      }||z   dz   }nd}| j                  r&| j                  | j                  |z   «       d| _        y|r| j                  |«       yy| j                  r&| j                  | j                  |z   «       d| _        y|r| j                  |«       yy)zySend response body chunk.

        Combines buffered headers with first body chunk for efficient write batching.
        r0   r1   r2   rü  r   N)rB  Ú_CHUNK_PREFIXESrž  rT   r¹   rb  )r   rŒ   r‘   ÚsizeÚprefixÚ
chunk_datas         r   r¦  zASGIProtocol._send_body  sÔ   € ñ
 Ùô ˜4“y�Ü(×,Ñ,¨TÓ2ÒW¸¸a¸À°o×6LÑ6LÈYÓ6W�Ø# d™]¨WÑ4‘
à �
ð ×$Ò$Ø× Ñ  ×!6Ñ!6¸Ñ!CÔDØ(,�Õ%ÙØ× Ñ  Õ,ð ð ×$Ò$Ø× Ñ  ×!6Ñ!6¸Ñ!=Ô>Ø(,�Õ%ÙØ× Ñ  Õ&ð r   c                 ó²   — |j                  d«      }d|› d|› dt        |«      › d�}| j                  |j                  d«      «       | j                  |«       y)zSend an error response.zutf-8z	HTTP/1.1 r\   z,
Content-Type: text/plain
Content-Length: z
Connection: close

r2   N)rT   rB  rb  )r   r_   r§  rŒ   rú  s        r   r  z!ASGIProtocol._send_error_response/  sa   € à�~‰~˜gÓ&ˆà˜�x˜q  	ð *ä" 4›y˜kð *ðð 	ð 	×Ñ˜Ÿ™¨Ó3Ô4Ø×Ñ˜Õr   c                 óô   — i dd“dd“dd“dd“d	d
“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd “d!d"“i d#d$“d%d&“d'd(“d)d*“d+d,“d-d.“d/d0“d1d2“d3d4“d5d6“d7d8“d9d:“d;d<“d=d>“d?d@“dAdB“¥}|j                  |dC«      S )Dz'Get HTTP reason phrase for status code.r
  ÚContinueée   zSwitching Protocolség   zEarly Hintsr  ÚOKéÉ   ÚCreatedéÊ   ÚAcceptedr  z
No ContentéÎ   zPartial Contenti-  zMoved Permanentlyi.  ÚFoundi/  z	See Otherr	  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 Requestsr�  rº  iõ  zNot Implementediö  zBad Gatewayi÷  zService Unavailableiø  zGateway TimeoutÚUnknown)rž  )r   r_   Úreasonss      r   rù  zASGIProtocol._get_reason_phrase<  s¹  € ð"
Ø�ð"
àÐ&ð"
ð �ð"
ð �ð	"
ð
 �ð"
ð �ð"
ð �ð"
ð Ð"ð"
ð Ð$ð"
ð �ð"
ð �ð"
ð �ð"
ð Ð%ð"
ð Ð%ð"
ð �ð"
ð  �ð!"
ð" �ñ#"
ð$ �ð%"
ð& Ð%ð'"
ð( Ð"ð)"
ð* �ð+"
ð, �ð-"
ð. Ð"ð/"
ð0 Ð$ð1"
ð2 �ð3"
ð4 Ð)ð5"
ð6 Ð'ð7"
ð8 Ð$ð9"
ð: Ð(ð;"
ð< Ð"ð="
ð> �ð?"
ð@ Ð&ðA"
ðB Ð"ñC"
ˆðF �{‰{˜6 9Ó-Ð-r   c                 ó  — | j                   rd| j                  sW	 | j                   j                  «       r| j                   j                  «        | j                   j	                  «        d| _        yyy# t
        $ r Y Œw xY w)z°Close the transport safely.

        Calls write_eof() first if supported to signal end of writing,
        which helps ensure buffered data is flushed before closing.
        TN)r>   rs   Úcan_write_eofÚ	write_eofÚcloser8  rA   s    r   r  zASGIProtocol._close_transportc  sj   € ð �>Š> $§,¢,ðà—>‘>×/Ñ/Ô1Ø—N‘N×,Ñ,Ô.Ø—‘×$Ñ$Ô&ð  ˆD�Lð #/ˆ>øô ò Ùðús   šAA2 Á2	A>Á=A>c              ƒ   ó¸  K  — 	 ddl m} |j                  d«      }|j                  d«      }| j                  }t	        j
                  |«      }t	        j                  |||| j                  j                  «      }	 || j                  ||	|«      }
|€ |
j                  «       ƒ d{  –—†  |
| _        nc|\  }}}|
j                  |||«      ƒ d{  –—† }|
| _        | j                  ||
||«      ƒ d{  –—†  | j                  xj                  dz  c_        |
j                  sù| j                  j                   rã	 |
j#                  d¬«      ƒ d{  –—† }|D ]  }| j                  ||
||«      ƒ d{  –—†  Œ  | j                  xj                  t-        |«      z  c_        | j                  j                  | j                  j.                  k\  r-| j(                  j1                  d
«       d| j                  _        n#|
j                  s| j                  j                   rŒãt7        | d«      r#	 | j                  j9                  «       ƒ d{  –—†  | j;                  «        y7 �Œµ7 �Œ�7 �Œo7 �Œ# t        j$                  $ r Y �Œgt&        $ r&}| j(                  j+                  d	|«       Y d}~Œ‹d}~ww xY w7 �Œ?# t        j2                  $ r Y Œ«t&        $ r&}| j(                  j5                  d|«       Y d}~ŒÔd}~ww xY w7 Œ±# t&        $ r Y Œºw xY w# t7        | d«      r4	 | j                  j9                  «       ƒ d{  –—†7   n# t&        $ r Y nw xY w| j;                  «        w xY w­w)a4  Handle an HTTP/2 connection.

        ``upgrade`` is set when the connection arrives over Upgrade: h2c and
        carries ``(settings, http1_req, body)``. The request that asked for
        the upgrade becomes stream 1 and is served before the receive loop
        starts, per RFC 7540 section 3.2.
        r   )ÚAsyncHTTP2ConnectionrÇ   rd  Nr[   rN   rž   zHTTP/2 receive error: %srg  FzHTTP/2 connection error: %sÚ_h2_conn)Úgunicorn.http2.async_connectionr.  rÊ   r®   r;   ÚStreamReaderProtocolÚStreamWriterrª   r¤   r›   Úinitiate_connectionr/  Úinitiate_upgradeÚ_serve_http2_requestrp  Ú	is_closedrs  Úreceive_datar£   r8  r«   rz  rB  rq  rr  rj  ra  rË   r,  r  )r   r>   rÄ   r~  r.  rÇ   rd  r®   rw   r´   Úh2_connr€  Ú	http1_reqrŒ   ÚupgradedÚrequestsr:  Úreqs                     r   rÎ   z%ASGIProtocol._handle_http2_connections  sù  è ø€ ð?	$ÝLà ×/Ñ/°
Ó;ˆHØ ×/Ñ/°
Ó;ˆHð —[‘[ˆFÜ×3Ñ3°FÓ;ˆHÜ×)Ñ)Ø˜8 V¨T¯[©[×-=Ñ-=óˆFñ
 +Ø—‘˜& &¨(óˆGð ˆØ×1Ñ1Ó3×3Ð3Ø '�•à,3Ñ)�˜) TØ!(×!9Ñ!9Ø˜i¨ó"/÷ /�à '�”Ø×/Ñ/Ø˜g x°ó;÷ ;ð ;à—‘—’ !Ñ#•ð ×'Ò'¨D¯K©K×,=Ò,=ðØ%,×%9Ñ%9À#Ð%9Ó%F×F�Hð $ò :�CØ×3Ñ3Ø˜W h°ó:÷ :ñ :ð:ð
 —‘—’¤# h£-Ñ/•ð —;‘;—>‘> T§[¡[×%=Ñ%=Ò=Ø—H‘H—M‘MÐ"PÔQØ(-�D—K‘KÔ%Øð) ×'Ò'¨D¯K©K×,=Ó,=ô6 �t˜ZÔ(ðØŸ-™-×-Ñ-Ó/×/Ð/ð ×!Ñ!Õ#ðY 4ùð/ùð;ùð  GúÜ×+Ñ+ò ÚÜ ò Ø—H‘H—N‘NÐ#=¸qÔAÜûðúð
:úô ×%Ñ%ò 	ÙÜò 	AØ�H‰H×ÑÐ<¸a×@Ñ@ûð	Aúð
 0ùÜ ò Ùðûô �t˜ZÔ(ðØŸ-™-×-Ñ-Ó/×/Ò/øÜ ò Ùðúà×!Ñ!Õ#üs9  ‚M„BJ. Â#IÂ$(J. ÃIÃ"J. Ã/IÃ0AJ. Ä6I$ ÅI!ÅI$ ÅJ. Å,J+Å-B*J. ÈMÈ%K6 ÉK4ÉK6 ÉMÉJ. ÉJ. ÉJ. É!I$ É$J(É7J. É:J(ÊJ#ÊJ. Ê#J(Ê(J. Ê.K1ËL ËK1ËK,Ë'L Ë,K1Ë1L Ë4K6 Ë6	LË?MÌLÌMÌMÌL7Ì0L3Ì1L7Ì6MÌ7	MÍ MÍMÍMÍMc              ƒ   óÞ  K  — 	 | j                  ||||«      ƒ d{  –—†  |j                  |j
                  j                  «       y7 Œ*# t        $ ro}| j                  j                  d«       	 |j	                  |j
                  j                  dt        |«      «      ƒ d{  –—†7   n# t        $ r Y nw xY wY d}~Œ›d}~ww xY w# |j                  |j
                  j                  «       w xY w­w)z>Run one HTTP/2 request, answering 500 rather than dropping it.NzError handling HTTP/2 requestr�  )	Ú_handle_http2_requestr8  r«   ra  Ú
send_errorÚstreamÚ	stream_idr  Úcleanup_stream)r   r<  r8  rd  rÇ   r:  s         r   r5  z!ASGIProtocol._serve_http2_request¼  s¿   è ø€ ð		9Ø×,Ñ,¨S°'¸8ÀXÓN×NÐNð ×"Ñ" 3§:¡:×#7Ñ#7Õ8ð OùÜò 	Ø�H‰H×ÑÐ>Ô?ðØ×(Ñ(¨¯©×)=Ñ)=¸sÄCÈÃFÓK×KÒKøÜò Ùðÿûð		ûð ×"Ñ" 3§:¡:×#7Ñ#7Õ8üsy   ‚C-„A ›AœA  &C-ÁA Á	C ÁB;Á-3B'Â B#Â!B'Â&B;Â'	B3Â0B;Â2B3Â3B;Â6C Â;C Ã C Ã'C*Ã*C-c                 óä   — g }|D ]h  \  }}t        |t        «      r|j                  d«      }t        |t        «      r|j                  d«      }|j                  |j	                  «       |f«       Œj |S )z?Convert ASGI headers to HTTP/2 format (lowercase string names).r2   )r&   ri   rj   rk   r†  )r   rh   Úresultrl   rm   s        r   Ú_convert_h2_headersz ASGIProtocol._convert_h2_headersÉ  sh   € àˆØ"ò 	1‰KˆD�%Ü˜$¤Ô&Ø—{‘{ 9Ó-�Ü˜%¤Ô'ØŸ™ YÓ/�Ø�M‰M˜4Ÿ:™:›<¨Ð/Õ0ð	1ð ˆr   c              ƒ   óæ  ‡ ‡‡‡‡‡‡‡‡‡‡‡‡‡‡K  — ‰j                   j                  Š‰j                  j                  ‰«      Š‰ j	                  ‰||«      }dŠdŠdŠdŠdŠdŠdŠg ŠdŠdŠˆˆfd„}ˆˆˆˆˆˆˆˆˆˆˆˆ ˆfd„}‰ j
                  j                  }t        j                  «       }		 ‰ j                  j                  ‰ j                  ‰«       ‰ j                  |||«      ƒ d{  –—†  ‰�‰‚‰s‰j                  ‰dd«      ƒ d{  –—†  dŠn˜‰s–‰ j                  ‰«      }
dt        ‰«      fg}|j!                  |
«       ‰j                  j                  ‰«      Š‰rI‰j"                  j%                  ‰|d	¬
«       ‰j%                  |d	¬
«       ‰j'                  «       ƒ d{  –—†  	 t-        t        j                  «       |	z
  «      }|r?‰ j/                  ‰||«      }t1        ‰‰‰«      }‰ j
                  j3                  |‰||«       nd}d}‰ j                  j5                  ‰ j                  ‰||«       y7 �ŒP7 �Œ27 Œ™# t(        $ r> ‰ j
                  j+                  d«       ‰s‰j                  ‰dd«      ƒ d{  –—†7   dŠY ŒÝw xY w# t(        $ r ‰ j
                  j+                  d«       Y yw xY w# 	 t-        t        j                  «       |	z
  «      }|r?‰ j/                  ‰||«      }t1        ‰‰‰«      }‰ j
                  j3                  |‰||«       nd}d}‰ j                  j5                  ‰ j                  ‰||«       w # t(        $ r ‰ j
                  j+                  d«       Y w w xY wxY w­w)zûHandle 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.
        FNr�  r   c               “   óš  •K  — ‰�‰j                   j                  dk(  rddiS ‰s0‰j                  r$‰j                  sdŠ‰j	                  «       } d| ddœS 	 t        j                  ‰j                  «       d¬	«      ƒ d {  –—† }|€dŠdd
ddœS ‰j                  rdŠd|‰j                   dœS 7 Œ-# t
        j                  $ r ddicY S w xY w­w)NÚCLOSEDrˆ   r‰   TrŠ   Fr‹   r�   rž   r   )
r/  rl   Úrequest_completeÚ_body_chunksÚget_request_bodyr;   r¢   Úread_body_chunkr£   Ú_body_complete)rŒ   r|   Úbody_receivedr@  s     €€r   r”   z3ASGIProtocol._handle_http2_request.<locals>.receiveì  s  øè ø€ ð ˆ~ §¡×!2Ñ!2°hÒ!>ØÐ 1Ð2Ð2ñ ! V×%<Ò%<ÀV×EXÒEXØ $�Ø×.Ñ.Ó0�à*Ø Ø!&ñð ð3Ü%×.Ñ.Ø×*Ñ*Ó,Ø ô÷ �ð ˆ}Ø $�à*ØØ!&ñð ð ×$Ò$Ø $�ð 'ØØ!'×!6Ñ!6Ð6ñð ð%ùô ×'Ñ'ò 3ØÐ 1Ð2Ò2ð3üs<   ƒACÁ(B. Á>B,Á?B. Â)CÂ,B. Â.CÃCÃCÃCc              “   óè  •K  — | d   }|dk(  rP| j                  d«      }| j                  dg «      }‰j                  |«      }‰j                  ‰||«      ƒ d {  –—†  y |dk(  rD‰rt        d«      Šy dŠ| d   Š‰j	                  ‰j
                  ‰«      Š| j                  dg «      Šy |dk(  �rh‰st        d	«      Šy ‰rt        d
«      Šy | j                  dd«      }| j                  dd«      }‰r/|r+‰s)‰j                  j                  d‰j
                  ‰«       dŠd}‰s¤‰j                  ‰«      }dt        ‰«      fg}|j                  |«       ‰j                  j                  ‰«      }|€t        d«      Šy ‰j                  j                  ‰|d¬«       |j                  |d¬«       ‰j                  «       ƒ d {  –—†  dŠ|r+‰j                  ‰|| ¬«      ƒ d {  –—†  ‰t        |«      z  Š|s!|s‰j                  ‰dd¬«      ƒ d {  –—†  dŠy y |dk(  rL‰st        d«      Šy | j                  dg «      }	‰j                  |	«      }
‰j!                  ‰|
«      ƒ d {  –—†  y y 7 �Œ7 Œ¬7 Œ�7 Œa7 Œ­w)Nrˆ   r’  r_   rh   r“  r”  Trš  r›  rœ  rŒ   r   r�   Fr�  ú:statuszStream closed©Ú
end_streamúhttp.response.trailersz)Cannot send trailers before body complete)rž  rE  Úsend_informationalrý   r   r  r«   r¥  r  ÚextendÚstreamsr8  Úsend_headersÚ_send_pending_dataÚ	send_datarB  Úsend_trailers)r§  r¨  r©  rª  rh   rŒ   r�   Úresponse_hdrsr@  Útrailer_headersÚtrailersr°  r8  Úheaders_sentr±  r²  rv   r³  r´  rµ  r¶  r·  r   rA  s              €€€€€€€€€€€€€r   r¹  z0ASGIProtocol._handle_http2_request.<locals>.send  s¶  øè ø€ ð
 ˜v‘ˆHàÐ8Ò8à%Ÿk™k¨(Ó3�Ø&Ÿ{™{¨9°bÓ9�Ø×2Ñ2°<Ó@�Ø×0Ñ0°¸KÈÓQ×QÐQØàÐ0Ò0Ù#Ü#/Ð0JÓ#K�LØØ#'Ð Ø")¨(Ñ"3�ð "×6Ñ6Ø—N‘N Oó5�
à#*§;¡;¨y¸"Ó#=Ñ ð Ð1Ó1Ù'Ü#/Ð0FÓ#G�LØÙ$Ü#/Ð0KÓ#L�LØà—{‘{ 6¨3Ó/�Ø#ŸK™K¨°UÓ;�	áÙÑ$5ØŸ™×(Ñ(ðLà#ŸN™N¨Oôð
 -1Ð)Ø�Dñ $Ø"×6Ñ6Ð7GÓH�GØ&/´°_Ó1EÐ%FÐ$G�MØ!×(Ñ(¨Ô1ð %Ÿ_™_×0Ñ0°Ó;�FØ�~Ü'3°OÓ'D˜ØØ—O‘O×0Ñ0°¸MÐV[Ð0Ô\Ø×'Ñ'¨À%Ð'ÔHØ!×4Ñ4Ó6×6Ð6Ø#'�Lñ Ø!×+Ñ+¨I°tÈIÈÐ+ÓV×VÐVØ!¤S¨£YÑ.�Má Ùà%×/Ñ/°	¸3È4Ð/ÓP×PÐPØ(,Ñ%ð	 !ð Ð5Ò5Ù(Ü#/Ð0[Ó#\�LØØ")§+¡+¨i¸Ó"<�Ø×3Ñ3°OÓD�Ø×+Ñ+¨I°xÓ@×@Ñ@ð 6ðA Rùðd 7øð
 Wøð Qøð Aús\   ƒAI2ÁI'ÁE$I2Æ=I*Æ> I2ÇI,Ç-I2ÈI.ÈAI2É I0É!I2É*I2É,I2É.I2É0I2rº  rP  TrQ  r¼  r»  )r@  rA  rV  rž  Ú_build_http2_scoper«   r¾  rQ   r¿  r›   rÀ  rª   r­   r?  rE  r  rU  r8  rW  rX  r8  ra  r   Ú_build_http2_environre   rÂ  rÃ  )r   rv   r8  rd  rÇ   r�  r”   r¹  r¾  rÆ  rh   r[  rÇ  rÈ  rÉ  rN  r°  r^  r±  r²  r³  r´  rµ  r¶  r·  r@  rA  s   ```            @@@@@@@@@@@@r   r>  z"ASGIProtocol._handle_http2_requestÔ  sG  ÿþè ø€ ð —N‘N×,Ñ,ˆ	Ø—‘×$Ñ$ YÓ/ˆØ×'Ñ'¨°¸8ÓDˆà ÐØ!ÐØˆØˆ
Ø!ÐØˆØˆØÐØˆð ˆõ)	÷VR	A÷ R	Að R	Aðj "ŸX™X×8Ñ8ÐÜŸ™Ó(ˆð,	EØ�H‰H× Ñ  §¡¨gÔ6Ø—(‘(˜5 '¨4Ó0×0Ð0àÐ'Ø"Ð"ñ $Ø×(Ñ(¨°CÐ9PÓQ×QÐQØ"%‘ñ "à×2Ñ2Ð3CÓD�Ø"+¬S°Ó-AÐ!BÐ C�Ø×$Ñ$ WÔ-Ø Ÿ™×,Ñ,¨YÓ7�ÙØ—O‘O×0Ñ0°¸MÐVZÐ0Ô[Ø×'Ñ'¨À$Ð'ÔGØ!×4Ñ4Ó6×6Ð6ðEÜ+¬D¯N©NÓ,<¸}Ñ,LÓM�á%Ø"×7Ñ7¸ÀÈ8ÓT�GÜ+Ø'Ð)9¸=ó�Dð —H‘H—O‘O D¨'°7¸LÕIà"�GØ�DØ—‘×%Ñ% d§k¡k°7¸GÀTÕJðQ 1ùð Rùð 7ùäò 	&Ø�H‰H×ÑÐ:Ô;ÙØ×(Ñ(¨°CÐ9PÓQ×QÑQØ"%�ùð		&ûô& ò EØ—‘×"Ñ"Ð#CÖDðEûðEÜ+¬D¯N©NÓ,<¸}Ñ,LÓM�á%Ø"×7Ñ7¸ÀÈ8ÓT�GÜ+Ø'Ð)9¸=ó�Dð —H‘H—O‘O D¨'°7¸LÕIà"�GØ�DØ—‘×%Ñ% d§k¡k°7¸GÀTÕJøÜò EØ—‘×"Ñ"Ð#CÖDðEÿs½   ‘BM1Â,<I  Ã(H8Ã) I  Ä	H;Ä
BI  Æ$H>Æ%I  Æ*BJ
 È7M1È8I  È;I  È>I  É <JÉ<I?É=JÊJ4 ÊJÊJ4 Ê
$J1Ê.M1Ê0J1Ê1M1Ê4M.Ê6BMÍM.Í$M+Í(M.Í*M+Í+M.Í.M1c                 óì  — g }|j                   D ]D  \  }}|j                  |j                  «       j                  d«      |j                  d«      f«       ŒF t	        |«      }t	        |«      }ddddœd|j
                  |j                  |j                  t        |dd«      xs) |j                  r|j                  j                  d«      nd	|j                  r|j                  j                  d«      nd	| j                  j                  xs d
|||dœ}	t        | j                  d«      r| j                  j                  |	d<   i }
t        |d«      r|j                  |j                   dœ|
d<   i |
d<   |
|	d<   |	S )z*Build ASGI HTTP scope from HTTP/2 request.r2   re  rÌ  rÍ  rÎ  Ú2rÕ  Nr   rÐ  rÑ  r/  rÚ  rÜ  rÛ  rS  rß  )rh   rk   r†  rT   r#   r  rÓ  rÔ  r¡   rà  r›   r×  rË   rª   r/  rÚ  rá  )r   rv   rd  rÇ   rh   rl   rm   rØ  rÙ  r�  rß  s              r   r_  zASGIProtocol._build_http2_scope�  sd  € àˆØ"Ÿ?™?ò 	‰KˆD�%Ø�N‰NØ—
‘
“×#Ñ# IÓ.Ø—‘˜YÓ'ðõ ð	ô % XÓ.ˆÜ$ XÓ.ˆð Ø %°uÑ=ØØ—n‘nØ—n‘nØ—L‘LÜ ¨°TÓ:ÒwÐah×amÒam¸w¿|¹|×?RÑ?RÐS\Ô?]ÐsvØ?F¿}º}˜GŸM™M×0Ñ0°Ô;ÐRUØŸ™×+Ñ+Ò1¨rØØØñ
ˆô �4—;‘; Ô(Ø!Ÿ[™[×.Ñ.ˆE�'‰Nð ˆ
Ü�7Ð-Ô.à!×1Ñ1Ø%×9Ñ9ñ4ˆJÐ/Ñ0ð
 02ˆ
Ð+Ñ,Ø(ˆˆlÑàˆr   c                 óÚ   — |j                   |j                  |j                  |j                  xs dd|r|d   nddœ}|j                  D ]  \  }}d|j                  dd«      z   }|||<   Œ! |S )z.Build minimal environ dict for access logging.rÐ  zHTTP/2r   rã  rä  rë  r­  )r  rì  rÔ  rà  rh   rí  rî  s           r   r`  z!ASGIProtocol._build_http2_environÈ  sx   € ð &Ÿn™nØ—{‘{Ø Ÿ™Ø#ŸM™MÒ/¨RØ'Ù*2˜8 Aš;¸ñ
ˆð #Ÿ?™?ò 	!‰KˆD�%Ø˜DŸL™L¨¨cÓ2Ñ2ˆCØ ˆG�CŠLð	!ð ˆr   )r   )Fr4  )Ar   r   r   r   rá   rã   rä   rå   ræ   rç   r   r×   rÕ   Úclassmethodrê   rü   rÚ   rÿ   r   r  r  r&  r"  r-  rÔ   r+  rÝ   r7  r#  r$  rG  rL  rN  rJ  rV  rT  rJ   rL   rb  rÜ   rh  rl  rm  rn  ro  r½  rÁ  r‹  rŸ  r¤  rk  Ústaticmethodr   r¢  r¡  r¦  r  rù  r  rÎ   r5  rE  r>  r_  r`  r   r   r   r¨   r¨   S  s‰  „ ñð €NØÐØ€OØ"ÐØ!%ÐØ#'Ð ò2òh'óR1ð* ñ"ó ð"ð6'Ð#ò
P>òd7ò6	,ò/ò
ò."ò*$ò*(ò ò$#ò
ò8 òDòòòò*ò ò0$òd ò
/ò
0ò
ò&c$òJ-'ò^
òQò* ò"A8òF+òZò$$òL5ò800òd*ð6 ñ

ó ð

ð ñ4ó ð4ð ñ
ó ð
ó'ò:ò%.òN ó G$òR9ò	òGEòR)óVr   r¨   )(r   r;   r]  r'   rQ   Úgunicorn.asgi.unreaderr   Úgunicorn.asgi.parserr   r   r   r   r   r	   Úgunicorn.asgi.uwsgir
   Úgunicorn.http.errorsr   Úgunicorn.http2r   Úgunicorn.uwsgi.errorsr   r   r#   r/   r]   rý  rU   rR   ÚrangerT   r  rÑ   r4   rW   rc   re   ro   ÚProtocolr¨   )Úis   0r   ú<module>ro     sã   ðñ
ó Û Û Û å 0÷÷ õ 2Ý +Ý &Ý 5÷Fñ Fò5òð( Ð Ø4Ð ð Ð ØÐ ñ ?DÀE»lÖK¸�1˜˜1˜˜T�l×)Ñ)¨)Ó4Ñ4ÒK€ð Ð ÷%*ñ %*òP	ò%÷/ñ /÷ m ñ m ô`D�7×#Ñ#õ DùòG Ls   Á#B?