
    \ei|                         d Z ddlZddlmZ ddl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 G d dej                        Zy)z
ASGI protocol handler for gunicorn.

Implements asyncio.Protocol to handle HTTP/1.x and HTTP/2 connections
and dispatch to ASGI applications.
    N)datetime)AsyncUnreader)AsyncRequest)AsyncUWSGIRequest)
NoMoreData)UWSGIParseExceptionc                       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 )Nlatin-1)statussentheaders
isinstancebytesdecodeappend)selfr   r   r   namevalues         L/var/www/ceduoda/envi/lib/python3.12/site-packages/gunicorn/asgi/protocol.py__init__zASGIResponseInfo.__init__   sp    	" 	/KD%$&{{9-%'Y/LLu.	/    N)__name__
__module____qualname____doc__r    r   r   r
   r
      s
    E
/r   r
   c                       e 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dZd Zd Zd Zd Zd Zd Zd Zy)ASGIProtocolzHTTP/1.1 protocol handler for ASGI applications.

    Handles connection lifecycle, request parsing, and ASGI app invocation.
    c                     || _         |j                  | _        |j                  | _        |j                  | _        d | _        d | _        d | _        d | _        d| _	        d| _
        y )Nr   F)workercfglogasgiapp	transportreaderwriter_task	req_count_closed)r   r"   s     r   r   zASGIProtocol.__init__,   sV    ::::;;
 r   c                    || _         | j                  xj                  dz  c_        |j                  d      }|rut	        |d      ri|j                         }|dk(  rTt        j                         | _        | j                  j                  j                  | j                  ||            | _        yt        j                         | _        || _        | j                  j                  j                  | j                               | _        y)z(Called when a connection is established.   
ssl_objectselected_alpn_protocolh2N)r'   r"   nr_connsget_extra_infohasattrr0   asyncioStreamReaderr(   loopcreate_task_handle_http2_connectionr*   r)   _handle_connection)r   r'   r/   alpns       r   connection_madezASGIProtocol.connection_made;   s    "! --l;
'*.FG446Dt| &224![[--9911)ZH
  **, [[%%11$2I2I2KL
r   c                 T    | j                   r| j                   j                  |       yy)z/Called when data is received on the connection.N)r(   	feed_data)r   datas     r   data_receivedzASGIProtocol.data_receivedU   s     ;;KK!!$' r   c                     d| _         | j                  xj                  dz  c_        | j                  r| j                  j	                          | j
                  r6| j
                  j                         s| j
                  j                          yyy)z-Called when the connection is lost or closed.Tr.   N)r,   r"   r2   r(   feed_eofr*   donecancel)r   excs     r   connection_lostzASGIProtocol.connection_lostZ   s`    !;;KK  "::djjoo/JJ 0:r   c                   K   t        | j                        }	 | j                  j                  d      }| j                  j                  d      }| j                  s| xj
                  dz  c_        	 t        | j                  dd      }|dk(  r5t        j                  | j                  ||| j
                         d{   }n4t        j                  | j                  ||| j
                         d{   }| j!                  |      r| j#                  |||       d{    n| j%                  |||       d{   }| j&                  xj(                  dz  c_        | j&                  j(                  | j&                  j*                  k\  r.| j                  j-                  d	       d
| j&                  _        d
}|r| j&                  j.                  sn=| j                  j0                  sn&|j3                          d{    | j                  s| j=                          y7 c7 1# t        $ r Y "t        $ r Y ,t        $ r&}| j                  j                  d|       Y d}~Ud}~ww xY w7 N7 57 u# t4        j6                  $ r Y zt8        $ r&}| j                  j;                  d|       Y d}~d}~ww xY w# | j=                          w xY ww)z/Main request handling loop for this connection.peernamesocknamer.   protocolhttpuwsgiNzuWSGI parse error: %s,Autorestarting worker after current request.FzError handling connection: %s)r   r(   r'   r3   r,   r+   getattrr#   r   parser   StopIterationr   r   r$   debug_is_websocket_upgrade_handle_websocket_handle_http_requestr"   nrmax_requestsinfoalive	keepalive
drain_bodyr5   CancelledError	Exception	exception_close_transport)r   unreaderrH   rI   rJ   requesterY   s           r   r:   zASGIProtocol._handle_connectionc   s[     -D	$~~44Z@H~~44Z@Hll!#&txxVDH7*(9(?(? HH$$ NN	) # )5(:(: HH$$ NN	) #" --g600(HMMM #'";";Xx# 	
 !# ;;>>T[[%=%==HHMM"PQ(-DKK% %I (9(9 xx)) ((***s ll@ !!#s## % ! * HHNN#:A> N* +%% 	 	CHH>BB	C !!#s   KAI4 2AH& =H >4H& 2H#3H& 7'I4 I,I4 :I/;CI4 <I2=I4 K H& #H& &	I)/I4 1I)9I4 ;I)I$I4 $I))I4 /I4 2I4 4J7J: 	J7J2-J: 2J77J: :KK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	websocketupgrade)methodr   lower)r   r`   rg   
connectionr   r   s         r   rR   z"ASGIProtocol._is_websocket_upgrade   sv     >>U"
"?? 	+KD%y ++-%"[[]
		+
 +%P*Pj9PPr   c                    K   ddl m} | j                  |||      } || j                  | j                  || j
                  | j                        }|j                          d{    y7 w)z!Handle WebSocket upgrade request.r   )WebSocketProtocolN)gunicorn.asgi.websocketrl   _build_websocket_scoper'   r(   r&   r$   run)r   r`   rI   rH   rl   scopews_protocols          r   rS   zASGIProtocol._handle_websocket   sT     =++GXxH'NNDKK$((
 oos   A!A+#A)$A+c           	      *   K    j                  ||      }dddddg dt        j                         j                  dk(  r*j                  sj                  dddd       d{    n%t        j                   j                               fd} f	d	} j                  ||      }d}	 t        j                         }	 j                  j                   j                          j                  |||       d{    s j                  dd
       d{    d	 t        j                         |	z
  }
t'              } j"                  j)                  |||
        j                  j+                   j                  ||       j-                         ry j                  j.                  xr  j                  j0                  S 7 t7 7 # t         $ r  j"                  j%                  d       s j                  dd
       d{  7   dY 	 t        j                         	z
  }
t'              } j"                  j)                  |||
        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 Kw xY w# 	 t        j                         	z
  }
t'              } j"                  j)                  |||
        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   http.requestr   typebody	more_bodyc                  @   K    j                          d {   S 7 w)Nget)receive_queues   r   receivez2ASGIProtocol._handle_http_request.<locals>.receive   s     &**,,,,s   c                   	K   | d   }|dk(  r?| j                  d      }| j                  dg       }j                  ||       d {    y |dk(  rwrt        d      y d| d   | j                  dg       
t        d 
D              }|s j                  d	k\  rdt        
      d
gz   
j                  
       d {    y |dk(  rst        d      y 	rt        d      y | j                  dd      }| j                  dd      }|r)j                  |       d {    t        |      z  |s rj                  j                  d       d	y y y 7 7 7 ;w)Nrv   http.response.informationalr   r   http.response.startResponse already startedTc              3      K   | ]o  \  }}t        |t              r|j                         n|j                         d k(  xs3 t        |t              r|j                         n|j                         dk(   q yw)s   content-lengthzcontent-lengthN)r   strri   ).0r   _s      r   	<genexpr>zBASGIProtocol._handle_http_request.<locals>.send.<locals>.<genexpr>   sg      )  a &0c%:TZZ\

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

4::<Tdde)s   A5A7r.   r.   )s   transfer-encodings   chunkedhttp.response.bodyResponse not startedResponse already completerw   r   rx   F)chunkeds   0

)r{   _send_informationalRuntimeErroranyversionlist_send_response_start
_send_bodylenr'   write)messagemsg_typeinfo_statusinfo_headershas_content_lengthrw   rx   exc_to_raiser`   response_completeresponse_headersresponse_sentresponse_startedresponse_statusr   use_chunkeds          r   sendz/ASGIProtocol._handle_http_request.<locals>.send   s     vH88%kk(3&{{9b9..{L'RRR00##/0J#KL#' ")("3#*;;y"#=  &) ) $4) &" *goo.G"&K'+,<'=Ac@d'd$//AQSZ[[[11'#/0F#GL$#/0K#LL{{63/#KKU;	//$/DDD!SY.M ",,\:(,%	 ! 23 S. \ Es8   AE$EA;E$E A"E$&E"'7E$ E$"E$Internal Server ErrorError in ASGI applicationException in post_request hook)_build_http_scoper5   Queuecontent_lengthr   putr8   _read_body_to_queue_build_environr   nowr#   pre_requestr"   r&   _send_error_responser\   r$   r]   r
   accesspost_requestshould_closerX   rY   )r   r`   rI   rH   rp   r}   r   environresprequest_startrequest_timer   r|   r   r   r   r   r   r   s   ``         @@@@@@@@r   rT   z!ASGIProtocol._handle_http_request   s<    &&w(C !    !!Q&w##&"%     8 8- PQ	-6	- 6	-r %%gxB	E$LLNMHH  g6((5'4000'"" $//5LMMM"%E'||~='9I=YgwE%%dkk7GTJ
 !{{  7TXX%7%77UX 1 N  	HH:;#//5LMMM"%E'||~='9I=YgwE%%dkk7GTJ E""#CDE	  E""#CDEE'||~='9I=YgwE%%dkk7GTJ E""#CDEs   A)N5G)6ANAG0 G,G0 8G.9G0  A*K *A N,G0 .G0 0;K+H.,K3K9 5A*J  N $KNKN
KK9 $K62N5K66N9N;A*M&%N&$N
NNNNc                 j  K   	 	 |j                  d       d{   }|r|j                  d|dd       d{    n|j                  dddd       d{    yX7 C7 &7 
# t        $ rD}| j                  j	                  d|       |j                  dddd       d{  7   Y d}~yd}~ww xY ww)	z.Read request body and put chunks on the queue.Ti   Nrt   ru   r   FzError reading body: %s)	read_bodyr   r\   r$   rQ   )r   r`   queuechunkra   s        r   r   z ASGIProtocol._read_body_to_queueJ  s     	%//66)) . %%)%     )) . #%*%   
  6  	HHNN3Q7))&"   	sl   B3A# AA# AA# A!A# B3A# A# !A# #	B0,4B+ B#!B+&B3+B00B3c                    g }|j                   D ]D  \  }}|j                  |j                         j                  d      |j                  d      f       F dddd|j                  d    d|j                  d    |j
                  |j                  |j                  |j                  r|j                  j                  d      nd	|j                  r|j                  j                  d      nd	| j                  j                  xs d
||r|nd|r|n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.r   rK   3.02.4r   spec_versionr   .r.   r    Nrv   r%   http_versionrh   schemepathraw_pathquery_string	root_pathr   serverclientstatepriority_weighthttp.response.priorityweight
depends_on
extensions)r   r   ri   encoder   rh   r   r   queryr#   r   r4   r"   r   r   priority_depends_on)r   r`   rI   rH   r   r   r   rp   s           r   r   zASGIProtocol._build_http_scoped  sM    "?? 	VKD%NNDJJL//	:ELL<STU	V  %u=&q12!GOOA4F3GHnnnnLL:A,,++I6C?F}}GMM00;RU++1r"*h"*h
  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   HTTP/r   r   r.   -REQUEST_METHODRAW_URI	PATH_INFOQUERY_STRINGSERVER_PROTOCOLREMOTE_ADDRHTTP_r   )rh   urir   r   r   r   replacer   r`   rI   rH   r   r   r   keys           r   r   zASGIProtocol._build_environ  s     &nn{{ #MM/R!&wq'9&:!GOOA<N;OP*28A;
 #?? 	!KD%DLLc22C GCL	! 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 dddd|j                  d    d	|j                  d
    |j                  dk(  rdnd|j                  |j                  r|j                  j                  d      nd|j                  r|j                  j                  d      nd| j                  j                  xs d||r|nd|r|nd|d}	t        | j                  d      r| j                  j                  |	d<   |	S c c}w )z/Build ASGI WebSocket scope from parsed request.r   zSEC-WEBSOCKET-PROTOCOL,rf   r   r   r   r   r   r.   httpswsswsr   r   N)rv   r%   r   r   r   r   r   r   r   r   r   subprotocolsr   )r   r   ri   r   splitstripr   r   r   r   r#   r   r4   r"   r   )
r   r`   rI   rH   r   r   r   r   srp   s
             r   rn   z#ASGIProtocol._build_websocket_scope  so    "?? 	VKD%NNDJJL//	:ELL<STU	V "?? 	KD%//38;;s3CDa	DD	   %u=&q12!GOOA4F3GH&~~8edLL:A,,++I6C?F}}GMM00;RU++1r"*h"*h(
  4;;(![[..E'N-  Es   F
c           	        K   |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                  |j                  d	             yw)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   Nr   r   r   r.    
r   : )r   _get_reason_phraser   r   r   r'   r   r   )r   r   r   r`   reasonresponser   r   s           r   r   z ASGIProtocol._send_informational  s      ??V#((07??1-.a0B/C1VHAfXUYZ" 	/KD%$&{{9-%'Y/4&5'..H	/ 	FX__Y78s   CCc           	        K   | j                  |      }d|j                  d    d|j                  d    d| d| d	}g }|D ]^  \  }}t        |t              r|j	                  d      }t        |t              r|j	                  d      }|j                  | d| d       ` |j                  d	       |d
j                  |      z   dz   }	| j                  j                  |	j                  d             yw)z&Send HTTP response status and headers.r   r   r   r.   r   r   r   r   zServer: gunicorn/asgi
r   N)
r   r   r   r   r   r   joinr'   r   r   )
r   r   r   r`   r   status_lineheader_linesr   r   r   s
             r   r   z!ASGIProtocol._send_response_start  s      ((0gooa017??13E2FaxqQWPXX\] " 	8KD%$&{{9-%'Y/4&5' 67	8 	78!66?X__Y78s   C3C5c                    K   |r^|r@t        |      ddj                  d      |z   dz   }| j                  j                  |       y| j                  j                  |       yyw)zSend response body chunk.xr   r   s   
N)r   r   r'   r   )r   rw   r   r   s       r   r   zASGIProtocol._send_body  s\     t9Q-t,33I>EO$$U+$$T* s   A"A$c                    K   |j                  d      }d| d| dt        |       d}| j                  j                  |j                  d             | j                  j                  |       yw)zSend an error response.zutf-8z	HTTP/1.1 r   z,
Content-Type: text/plain
Content-Length: z
Connection: close

r   N)r   r   r'   r   )r   r   r   rw   r   s        r   r   z!ASGIProtocol._send_error_response  sm     ~~g&xq	 *"4yk * 	 	X__Y78T"s   A-A/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.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 Redirecti  zBad Requesti  Unauthorizedi  	Forbiddeni  z	Not Foundi  zMethod Not Allowedi  zRequest Timeouti  Conflicti  Gonei  zLength Requiredi  zPayload Too Largei  zURI Too Longi  zUnsupported Media Typei  zUnprocessable Entityi  zToo Many Requestsrs   r   i  zNot Implementedi  zBad Gatewayi  zService Unavailablei  zGateway TimeoutUnknownrz   )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 {{69--r   c                     | j                   r0| j                  s#	 | j                   j                          d| _        yyy# t        $ r Y w xY w)zClose the transport safely.TN)r'   r,   closer\   )r   s    r   r^   zASGIProtocol._close_transport.  sH    >>$,,$$&  DL #/>  s   > 	A
	A
c           	        K   	 ddl m} |j                  d      }|j                  d      }| j                  }t	        j
                  |      }t	        j                  |||| j                  j                        } || j                  |||      }	|	j                          d{    |	| _        |	j                  s!| j                  j                  r
	 |	j                  d       d{   }
|
D ]D  }	 | j'                  ||	||       d{    |	j3                  |j,                  j.                         F | j                  xj4                  t7        |
      z  c_        | j                  j4                  | j                  j8                  k\  r-| j"                  j;                  d       d| j                  _        n$|	j                  s| j                  j                  r
t?        | d      r#	 | j                  jA                          d{    | jC                          y7 z7 7# t        j                  $ r Y t         $ r&}| j"                  j%                  d|       Y d}~d}~ww xY w7 _# t         $ rp}| j"                  j)                  d	       	 |	j+                  |j,                  j.                  d
t1        |             d{  7   n# t         $ r Y nw xY wY d}~d}~ww xY w# |	j3                  |j,                  j.                         w xY w# t        j<                  $ r Y Lt         $ r'}| j"                  j)                  d|       Y d}~vd}~ww xY w7 T# t         $ r Y ^w xY w# t?        | d      r4	 | j                  jA                          d{  7   n# t         $ r Y nw xY w| jC                          w xY ww)zHandle an HTTP/2 connection.r   )AsyncHTTP2ConnectionrH   rI   Ng      ?)timeoutzHTTP/2 receive error: %szError handling HTTP/2 requestrs   rM   FzHTTP/2 connection error: %s_h2_conn)"gunicorn.http2.async_connectionr  r3   r(   r5   StreamReaderProtocolStreamWriterr"   r7   r#   initiate_connectionr  	is_closedrX   receive_dataTimeoutErrorr\   r$   rQ   _handle_http2_requestr]   
send_errorstream	stream_idr   cleanup_streamrU   r   rV   rW   r[   r4   r  r^   )r   r'   r/   r  rH   rI   r(   rJ   r)   h2_connrequestsra   reqs                r   r9   z%ASGIProtocol._handle_http2_connection7  s0    C	$L //
;H //
;H [[F33F;H))8VT[[-=-=F
 +&&(G --///#DM ''DKK,=,=%,%9%9#%9%FFH $ ECE"88(H    ..szz/C/CDE" #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L !H"/L H! 'H(H! ,L 2I+	I(
I+CL O(M MM 
OL H! !I%4L 7I%?I L  I%%L (I++	K$4K3K
KK
	K
	KKKKK'K$$K'''LL M$M, 'M/MM, MM, M 	M)%O(M))O,N>:NNNN>	N*'N>)N**N>>Oc           	         K   j                   j                  | j                  ||      }ddddg dg fd}f	d}| j                  ||      }t	        j
                         }		 | j                  j                  | j                         | j                  |||       d{    rg }
D ]Z  \  }}t        |t              r|j                  d      }t        |t              r|j                  d      }|
j                  ||f       \ r dt              fg}|
D ]/  \  }}|j                  |j                         t        |      f       1 j                   j#                  |d	       j$                     }|j#                  |d	       j'                          d{    rIj                   j)                  d	       |j)                  d	       j'                          d{    j+                         d{    n:j-                  |
       d{    nj/                  dd
       d{    d	 t	        j
                         |	z
  }t7        t9                    }| j2                  j;                  |||       | j                  j=                  | j                  ||       y7 7 7 7 7 7 # t0        $ r> | j2                  j5                  d       sj/                  dd
       d{  7   dY w xY w# t0        $ r | j2                  j5                  d       Y yw xY w# 	 t	        j
                         |	z
  }t7        t9                    }| j2                  j;                  |||       | j                  j=                  | j                  ||       w # t0        $ r | j2                  j5                  d       Y w w xY wxY ww)zHandle a single HTTP/2 request.FNrs   r   c                  L   K   j                   j                         } d| ddS w)Nrt   Fru   )rw   read)rw   r`   s    r   r}   z3ASGIProtocol._handle_http2_request.<locals>.receive  s,     <<$$&D&" s   !$c                   	K   | d   }|dk(  r| j                  d      }| j                  dg       }g }|D ]Z  \  }}t        |t              r|j                  d      }t        |t              r|j                  d      }|j	                  ||f       \ j                  ||       d {    y |dk(  r(rt        d      y d| d   | j                  dg       y |d	k(  rMst        d
      y rt        d      y | j                  dd      }| j                  dd      }|r|z  |sdy y |dk(  rst        d      y | j                  dg       }	g }
|	D ]Z  \  }}t        |t              r|j                  d      }t        |t              r|j                  d      }|
j	                  ||f       \ j                  |
       y y 7 w)Nrv   r   r   r   r   r   r   Tr   r   r   rw   r   rx   Fhttp.response.trailersz)Cannot send trailers before body complete)r{   r   r   r   r   send_informationalr   extend)r   r   r   r   r   r   r   rw   rx   trailer_headerstrailersr   r  response_bodyr   r   r   r   response_trailersr  s              r   r   z0ASGIProtocol._handle_http2_request.<locals>.send  s     vH88%kk(3&{{9b9#/ 2KD%!$.#{{95!%/ %Y 7NND%=12 00KQQQ00##/0J#KL#' ")("3#*;;y"#= 11'#/0F#GL$#/0K#LL{{63/#KKU;	!T)M (,% ! 55(#/0[#\L")++i"<#2 3KD%!$.#{{95!%/ %Y 7OOT5M23 "((2 69 Rs   B%G	(G)DG	r   z:status)
end_streamr   r   r   )r  r  _build_http2_scope_build_http2_environr   r   r#   r   r"   r&   r   r   r   r   r   ri   r  send_headersstreams_send_pending_data	send_datasend_trailerssend_responser  r\   r$   r]   r
   r   r   r   )r   r`   r  rI   rH   rp   r}   r   r   r   r   r   r   response_hdrsr  r   r   r   r+  r   r   r   r   r,  r  s    ``              @@@@@@@@r   r  z"ASGIProtocol._handle_http2_request~  s    NN,,	''8D !	;	3 ;	3| ++GXxH <	EHH  g6((5'4000'""  #3 2KD%!$.#{{95!%/ %Y 7NND%=12 %&/_1E%F$GM'. Ie%,,djjlCJ-GHI OO00MV[0\$__Y7F''%'H!44666 %11)]W\1]((5(I%88::: "//	;LMMM!//!?G]   ((C9PQQQ"%E'||~='#%5s=7I gwE%%dkk7GTJq 14 7 ; N R  	&HH:;#((C9PQQQ"%		&  E""#CDEE'||~='#%5s=7I gwE%%dkk7GTJ E""#CDEs   A1O>><K' :K;DK' ?K A
K' 
KK' $K!%K' K#K' K%K' %A3L1 O>K' K' K' !K' #K' %K' '<L.#L&$L.+M -L..M 1$MO>MO>O;A3OO;$O85O;7O88O;;O>c                    g }|j                   D ]D  \  }}|j                  |j                         j                  d      |j                  d      f       F ddddd|j                  |j
                  |j                  |j                  r|j                  j                  d      nd|j                  r|j                  j                  d      nd| j                  j                  xs d||r|nd	|r|n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.r   rK   r   r   r   2r   r   Nr   r   r   r   r   r&  r   )r   r   ri   r   rh   r   r   r   r#   r   r4   r"   r   r   r   )	r   r`   rI   rH   r   r   r   rp   r   s	            r   r.  zASGIProtocol._build_http2_scope  sC   "?? 	KD%NN

##I.Y' 	  %u=nnnnLL:A,,++I6C?F}}GMM00;RU++1r"*h"*h
 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   )rh   r   r   r   r   r   r   s           r   r/  z!ASGIProtocol._build_http2_environ<  sx     &nn{{ #MM/R'*28A;
 #?? 	!KD%DLLc22C GCL	! r   N)F)r   r   r   r   r   r<   r@   rF   r:   rR   rS   rT   r   r   r   rn   r   r   r   r   r   r^   r9   r  r.  r/  r   r   r   r    r    &   s    
M4(
 H$TQ* |8|4#J$!F989,+#%.N E$NTEl&Pr   r    )r   r5   r   gunicorn.asgi.unreaderr   gunicorn.asgi.messager   gunicorn.asgi.uwsgir   gunicorn.http.errorsr   gunicorn.uwsgi.errorsr   r
   Protocolr    r   r   r   <module>r@     s?   
   0 . 1 + 5/ / e7## er   