
    Vh,                       d Z ddlZddlmZmZ ddlZddlmZmZm	Z	m
Z
 ddlmZ ddlmZ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 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%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+ dZ,	 ddl-Z-ddl.Z-ddl/Z-ddl0Z0ddl1Z1ddl2m3Z3m4Z4 ddl5m6Z6  G d d      Z8 G d d      Z9d4dZ:d4dZ;d Z< G d dejz                        Z> e+e>      Z? G d dejz                        Z@ e+e@      ZA G d  d!e@      ZB e+eB      ZC G d" d#ejz                        ZD e+eD      ZE G d$ d%      ZF e+eF      ZG G d& d'      ZH G d( d)ej                  eH      ZJ G d* d+ej                  eH      ZK G d, d-ej                  eH      ZL G d. d/ej                  eH      ZM G d0 d1ej                  eH      ZN G d2 d3ej                        ZOy# e7$ r dZ,Y 3w xY w)5z
Test HTTP/2 support.
    N)directlyProvides
providedBy)defererrorreactortask)IPv4Address)MemoryReactorClockStringTransport)deferToThread)failure)	iterbytes)requireModule)DummyProducer)!certificatesForAuthorityAndServer)unittest)http)Site)Data)DelayedHTTPHandlerDelayedHTTPHandlerProxyDummyHTTPHandlerDummyHTTPHandlerProxyDummyPullProducerHandlerProxy._IDeprecatedHTTPChannelToRequestInterfaceProxy_makeRequestProxyFactory)DecoderEncoder)H2ConnectionzHTTP/2 support not enabledc                   f    e Zd ZdZd Zd Zd Zg dfdZddZdd	Z	d
 Z
ddZddZddZg fdZy)FrameFactoryz
    A class containing lots of helper methods and state to build frames. This
    allows test cases to easily build correct HTTP/2 frames to feed to
    hyper-h2.
    c                 "    t               | _        y Nr   encoderselfs    K/home/dcms/DCMS/lib/python3.12/site-packages/twisted/web/test/test_http2.py__init__zFrameFactory.__init__>       y    c                 "    t               | _        y r#   r$   r&   s    r(   refreshEncoderzFrameFactory.refreshEncoderA   r*   r+   c                      y)Ns   PRI * HTTP/2.0

SM

 r&   s    r(   clientConnectionPrefacez$FrameFactory.clientConnectionPrefaceD   s    2r+      c                 H   t         j                  j                  |      }| j                  j	                  |      |_        |j                  j                  d       |D ]  }|j                  j                  |        |j                         D ]  \  }}t        |||        |S )zS
        Builds a single valid headers frame out of the contained headers.
        END_HEADERS)

hyperframeframeHeadersFramer%   encodedataflagsadditemssetattr)	r'   headersr9   streamIDpriorityKwargsfflagkvs	            r(   buildHeadersFramezFrameFactory.buildHeadersFrameG   s     ))(3$$W-	M" 	DGGKK	 #((* 	DAqAq!	 r+   Nc                     |t        |      n	t               }t        j                  j                  |      }||_        ||_        |S )zD
        Builds a single data frame out of a chunk of data.
        )setr4   r5   	DataFramer8   r9   )r'   r8   r9   r>   r@   s        r(   buildDataFramezFrameFactory.buildDataFrameV   s?     $/E
SU&&x0r+   c                     t         j                  j                  d      }|r|j                  j	                  d       ||_        |S )z1
        Builds a single settings frame.
        r   ACK)r4   r5   SettingsFramer9   r:   settings)r'   rL   ackr@   s       r(   buildSettingsFramezFrameFactory.buildSettingsFrame`   s9     **1-GGKK
r+   c                 R    t         j                  j                  |      }||_        |S )z5
        Builds a single WindowUpdate frame.
        )r4   r5   WindowUpdateFramewindow_increment)r'   r>   	incrementr@   s       r(   buildWindowUpdateFramez#FrameFactory.buildWindowUpdateFramek   s'     ..x8&r+   c                 n    t         j                  j                  d      }||_        ||_        ||_        |S )z/
        Builds a single GOAWAY frame.
        r   )r4   r5   GoAwayFrame
error_codelast_stream_idadditional_data)r'   lastStreamID	errorCodeadditionalDatar@   s        r(   buildGoAwayFramezFrameFactory.buildGoAwayFrames   s6     ((+ '*r+   c                 R    t         j                  j                  |      }||_        |S )z3
        Builds a single RST_STREAM frame.
        )r4   r5   RstStreamFramerV   )r'   r>   rZ   r@   s       r(   buildRstStreamFramez FrameFactory.buildRstStreamFrame}   s&     ++H5 r+   c                 n    t         j                  j                  |      }||_        ||_        ||_        |S )z1
        Builds a single priority frame.
        )r4   r5   PriorityFrame
depends_onstream_weight	exclusive)r'   r>   weight	dependsOnrd   r@   s         r(   buildPriorityFramezFrameFactory.buildPriorityFrame   s4     **84  r+   c                     t         j                  j                  |      }||_        | j                  j                  |      |_        t        |      |_        |j                  j                  d       |S )z5
        Builds a single Push Promise frame.
        r3   )
r4   r5   PushPromiseFramepromised_stream_idr%   r7   r8   rF   r9   r:   )r'   r>   promisedStreamIDr=   r9   r@   s         r(   buildPushPromiseFramez"FrameFactory.buildPushPromiseFrame   sX     --h7/$$W-e*	M"r+   Nr1   )F)r   r+   )r   )r   F)__name__
__module____qualname____doc__r)   r-   r0   rD   rH   rN   rS   r\   r_   rg   rl   r/   r+   r(   r!   r!   7   sL    !!3 02A 	 PR 	r+   r!   c                   ,    e Zd ZdZd Zd Zd Zd ZeZy)FrameBuffera  
    A test object that converts data received from Twisted's HTTP/2 stack and
    turns it into a sequence of hyperframe frame objects.

    This is primarily used to make it easier to write and debug tests: rather
    than have to serialize the expected frames and then do byte-level
    comparison (which can be unclear in debugging output), this object makes it
    possible to work with the frames directly.

    It also ensures that headers are properly decompressed.
    c                 0    t               | _        d| _        y )Nr+   )r   decoder_datar&   s    r(   r)   zFrameBuffer.__init__   s    y
r+   c                 .    | xj                   |z  c_         y r#   )rv   )r'   r8   s     r(   receiveDatazFrameBuffer.receiveData   s    

d
r+   c                     | S r#   r/   r&   s    r(   __iter__zFrameBuffer.__iter__   s    r+   c                 (   t        | j                        dk  r
t               t        j                  j
                  j                  | j                  d d       \  }}t        | j                        |dz   k  r
t               |j                  t        | j                  dd|z                 | j                  d|z   d  | _        t        |t        j                  j                        r,| j                  j                  |j                  d      |_        |S )N	   T)raw)lenrv   StopIterationr4   r5   Frameparse_frame_header
parse_body
memoryview
isinstancer6   ru   decoder8   )r'   r5   lengths      r(   nextzFrameBuffer.next   s    tzz?Q/!"((..AA$**Ra.Qvtzz?VaZ'/!DJJq1v:$>?@ZZF
-
eZ--::;,,UZZT,BEJr+   N)	rn   ro   rp   rq   r)   rx   rz   r   __next__r/   r+   r(   rs   rs      s"    
  Hr+   rs   c                     
t               g }|j                  j                  |              |j                  fd|D               |d   j                  j                  d       |S )a  
    Provides a sequence of HTTP/2 frames that encode a single HTTP request.
    This should be used when you want to control the serialization yourself,
    e.g. because you want to interleave other frames with these. If that's not
    necessary, prefer L{buildRequestBytes}.

    @param headers: The HTTP/2 headers to send.
    @type headers: L{list} of L{tuple} of L{bytes}

    @param data: The HTTP data to send. Each list entry will be sent in its own
    frame.
    @type data: L{list} of L{bytes}

    @param frameFactory: The L{FrameFactory} that will be used to construct the
    frames.
    @type frameFactory: L{FrameFactory}

    @param streamID: The ID of the stream on which to send the request.
    @type streamID: L{int}
    r=   r>   c              3   D   K   | ]  }j                  |         yw)r>   N)rH   ).0chunkframeFactoryr>   s     r(   	<genexpr>z%buildRequestFrames.<locals>.<genexpr>   s&      BG##EH#=s    
END_STREAM)r!   appendrD   extendr9   r:   r=   r8   r   r>   framess     `` r(   buildRequestFramesr      sk    * #~F
MM,0080TU
MM KO  2J&Mr+   c                 N    t        | |||      }dj                  d |D              S )a:  
    Provides the byte sequence for a collection of HTTP/2 frames representing
    the provided request.

    @param headers: The HTTP/2 headers to send.
    @type headers: L{list} of L{tuple} of L{bytes}

    @param data: The HTTP data to send. Each list entry will be sent in its own
    frame.
    @type data: L{list} of L{bytes}

    @param frameFactory: The L{FrameFactory} that will be used to construct the
    frames.
    @type frameFactory: L{FrameFactory}

    @param streamID: The ID of the stream on which to send the request.
    @type streamID: L{int}
    r+   c              3   <   K   | ]  }|j                           y wr#   	serializer   r@   s     r(   r   z$buildRequestBytes.<locals>.<genexpr>   s     2aAKKM2   )r   joinr   s        r(   buildRequestBytesr      s)    &  |XFF8826222r+   c                 N    t               }|j                  |        t        |      S )a  
    Given a sequence of bytes, decodes them into frames.

    Note that this method should almost always be called only once, before
    making some assertions. This is because decoding HTTP/2 frames is extremely
    stateful, and this function doesn't preserve any of that state between
    calls.

    @param data: The serialized HTTP/2 frames.
    @type data: L{bytes}

    @returns: A list of HTTP/2 frames.
    @rtype: L{list} of L{hyperframe.frame.Frame} subclasses.
    )rs   rx   list)r8   buffers     r(   framesFromBytesr      s#     ]F
t<r+   c                       e Zd ZdZdZd Zy)ChunkedHTTPHandlerz
    A HTTP request object that writes chunks of data back to the network based
    on the URL.

    Must be called with a path /chunked/<num_chunks>
    s   hello world!c                     t        | j                  j                  d      d         }| j                  d       t	        |      D ]  }| j                  | j                          | j                          y )N   /r      )inturisplitsetResponseCoderangewrite	chunkDatafinish)r'   chunks_s      r(   processzChunkedHTTPHandler.process  sZ    TXX^^D)"-.S!v 	'AJJt~~&	' 	r+   N)rn   ro   rp   rq   r   r   r/   r+   r(   r   r     s      Ir+   r   c                   (    e Zd ZdZd Zd Zd Zd Zy)ConsumerDummyHandlera  
    This is a HTTP request handler that works with the C{IPushProducer}
    implementation in the L{H2Stream} object. No current IRequest object does
    that, but in principle future implementations could: that codepath should
    therefore be tested.
    c                     t        j                  j                  | g|i | | j                  j	                          d| _        d | _        y )NF)r   Requestr)   channelpauseProducing_requestReceivedrv   r'   argskwargss      r(   r)   zConsumerDummyHandler.__init__0  s?    d4T4V4 	##% %
r+   c                 8    | j                   j                          y)z&
        Start the data pipe.
        N)r   resumeProducingr&   s    r(   
acceptDatazConsumerDummyHandler.acceptData8  s     	$$&r+   c                 V    d| _         t        j                  j                  | g|i |S )NT)r   r   r   requestReceivedr   s      r(   r   z$ConsumerDummyHandler.requestReceived>  s)     $||++DB4B6BBr+   c                     | j                  d       | j                  j                         | _        d}| j	                  |       | j                          y )Nr   s0   this is a response from a consumer dummy handler)r   contentreadrv   r   r   )r'   
returnDatas     r(   r   zConsumerDummyHandler.processB  s>    S!\\&&(
H


:r+   N)rn   ro   rp   rq   r)   r   r   r   r/   r+   r(   r   r   (  s    'Cr+   r   c                       e Zd ZdZd Zy)AbortingConsumerDummyHandlerz
    This is a HTTP request handler that works with the C{IPushProducer}
    implementation in the L{H2Stream} object. The difference between this and
    the ConsumerDummyHandler is that after resuming production it immediately
    aborts it again.
    c                 l    | j                   j                          | j                   j                          y)z@
        Start and then immediately stop the data pipe.
        N)r   r   stopProducingr&   s    r(   r   z'AbortingConsumerDummyHandler.acceptDataU  s$     	$$&""$r+   N)rn   ro   rp   rq   r   r/   r+   r(   r   r   M  s    %r+   r   c                       e Zd ZdZd Zy)DummyProducerHandlerz
    An HTTP request handler that registers a dummy producer to serve the body.

    The owner must call C{finish} to complete the response.
    c                 Z    | j                  d       | j                  t               d       y )Nr   T)r   registerProducerr   r&   s    r(   r   zDummyProducerHandler.processi  s"    S!mot4r+   N)rn   ro   rp   rq   r   r/   r+   r(   r   r   b  s    5r+   r   c                       e Zd ZdZd Zd Zy)NotifyingRequestFactorya(  
    A L{http.Request} factory that calls L{http.Request.notifyFinish} on all
    L{http.Request} objects before it returns them, and squirrels the resulting
    L{defer.Deferred} away on the class for later use. This is done as early
    as possible to ensure that we always see the result.
    c                 l    g | _         || _        t        | j                        D ]  }t        | |        y r#   )results_wrappedFactoryr   r   )r'   wrappedFactory	interfaces      r(   r)   z NotifyingRequestFactory.__init__y  s7    -
 $D$8$89 	.IT9-	.r+   c                      | j                   |i |}| j                  j                  |j                                t	        |      S r#   )r   r   r   notifyFinishr   )r'   r   r   reqs       r(   __call__z NotifyingRequestFactory.__call__  s?    "d""D3F3C,,./=cBBr+   N)rn   ro   rp   rq   r)   r   r/   r+   r(   r   r   q  s    .Cr+   r   c                       e Zd ZdZereZd Zy)HTTP2TestHelpersz]
    A superclass that contains no tests but provides test helpers for HTTP/2
    tests.
    c                 b    | j                  t        j                  t        |j                         y)z
        Confirm that all streams are blocked: that is, the priority tree
        believes that none of the streams have data ready to send.
        N)assertRaisespriorityDeadlockErrorr   )r'   
connections     r(   assertAllStreamsBlockedz(HTTP2TestHelpers.assertAllStreamsBlocked  s"    
 	(00$
8K8KLr+   N)rn   ro   rp   rq   skipH2skipr   r/   r+   r(   r   r     s    
 Mr+   r   c                      e Zd Zg dZg dZg dZg dZdZg 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( Z*y))*HTTP2ServerTests   :method   GETs
   :authoritys	   localhost   :pathr   s   :schemes   httpss
   user-agents   twisted-test-code)   custom-header   1)r      2)r      POSTr   )r      /post_endpointr   r   )   content-lengths   25s   hello s   world, s   it's s   http/2!)   :statuss   200)   requestr   )   commandr   s   versions   HTTP/2)r   s   13   '''
None
'''
)r   r   r   r   r   r   )r   s   36$   '''
25
hello world, it's http/2!'''
c                     t               }t               }|j                         }|t        |||      z  }|j	                  |       t        |      D ]  }|j                  |        ||fS )a!  
        Takes a single L{H2Connection} object and connects it to a
        L{StringTransport} using a brand new L{FrameFactory}.

        @param connection: The L{H2Connection} object to connect.
        @type connection: L{H2Connection}

        @param headers: The headers to send on the first request.
        @type headers: L{Iterable} of L{tuple} of C{(bytes, bytes)}

        @param body: Chunks of body to send, if any.
        @type body: L{Iterable} of L{bytes}

        @return: A tuple of L{FrameFactory}, L{StringTransport}
        )r!   r   r0   r   makeConnectionr   dataReceived)r'   r   r=   bodyr   	transportrequestBytesbytes           r(   connectAndReceivez"HTTP2ServerTests.connectAndReceive  sr      $~#%	#;;=)'4FF!!),l+ 	*D##D)	* Y&&r+   c                      t               }t        |_         j                  | j                  g       \  } fd}|j
                  d   j                  |      S )z
        Send request over a TCP connection and confirm that we get back the
        expected data in the order and style we expect.
        c                 @   t        j                               }j                  t        |      d       j	                  t        d |dd  D                     j	                  t        |d   t        j                  j                               j	                  t        |d   t        j                  j                               j	                  t        |d   t        j                  j                               j                  t        |d   j                        t        j                               j                  |d   j                  j                         j                  |d   j                  d       j	                  d|d   j                  v        y )N   c              3   :   K   | ]  }|j                   d k(    ywr1   N	stream_idr   s     r(   r   zGHTTP2ServerTests.test_basicRequest.<locals>.validate.<locals>.<genexpr>       EQq 0E   r1         r+   r   )r   valueassertEqualr~   
assertTrueallr   r4   r5   r6   rG   dictr8   getResponseHeadersgetResponseDatar9   r>   r   r'   r  s     r(   validatez4HTTP2ServerTests.test_basicRequest.<locals>.validate  s%   $Y__%67FS[!,OOCE&*EEFOOJvay*2B2B2O2OPQOOJvay*2B2B2L2LMNOOJvay*2B2B2L2LMNT&)..148O8O3PQVAY^^T-A-ABVAY^^S1OOLF1IOO;<r+   r1   )r   r   requestFactoryr  getRequestHeaders_streamCleanupCallbacksaddCallbackr'   r   r   r  r  s   `   @r(   test_basicRequestz"HTTP2ServerTests.test_basicRequest  sV     "^
$9
!--j$:P:PRTU9	= 11!4@@JJr+   c                      t               }t        |_         j                  | j                   j
                        \  } fd}|j                  d   j                  |      S )zV
        Send a POST request and confirm that the data is safely transferred.
        c                 @   t        j                               }j                  t        |      d       j	                  t        d |dd  D                     j	                  t        |d   t        j                  j                               j	                  t        |d   t        j                  j                               j	                  t        |d   t        j                  j                               j                  t        |d   j                        t        j                               j                  |d   j                  j                         j                  |d   j                  d       j	                  d|d   j                  v        y )Nr
  c              3   :   K   | ]  }|j                   d k(    ywr  r  r   s     r(   r   zFHTTP2ServerTests.test_postRequest.<locals>.validate.<locals>.<genexpr>       FQq 0Fr  r   r+   r   )r   r  r  r~   r  r  r   r4   r5   r6   rG   r  r8   postResponseHeaderspostResponseDatar9   r  s     r(   r  z3HTTP2ServerTests.test_postRequest.<locals>.validate
  s)   $Y__%67F S[!,OOCF&+FFGOOJvbz:3C3C3P3PQROOJvbz:3C3C3M3MNOOOJvbz:3C3C3M3MNOT&*//2D9Q9Q4RSVBZ__d.C.CDVBZ__c2OOLF2J,<,<<=r+   r1   )r   r   r  r  postRequestHeaderspostRequestDatar  r  r   s   `   @r(   test_postRequestz!HTTP2ServerTests.test_postRequest   s^     "^
$9
!--//1E1E
9	>  11!4@@JJr+   c                 $   	 g dd j                   D cg c]  \  }}|dk7  s||f }}}t               }t        |_         j	                  || j
                        \  }	 	fd}|j                  d   j                  |      S c c}}w )zm
        Send a POST request without length and confirm that the data is safely
        transferred.
        )r   r   r   r   )r   s   38s&   '''
None
hello world, it's http/2!'''
r   c                    t        j                               }j                  t        |      d       j	                  t        d |dd  D                     j	                  t        |d   t        j                  j                               j	                  t        |d   t        j                  j                               j	                  t        |d   t        j                  j                               j                  t        |d   j                        t                     j                  |d   j                         j                  |d   j                  d       j	                  d|d   j                  v        y )Nr
  c              3   :   K   | ]  }|j                   d k(    ywr  r  r   s     r(   r   zNHTTP2ServerTests.test_postRequestNoLength.<locals>.validate.<locals>.<genexpr>:  r%  r  r&  r'  r   r+   r   )r   r  r  r~   r  r  r   r4   r5   r6   rG   r  r8   r9   )r>   r   r)  r(  r'   r  s     r(   r  z;HTTP2ServerTests.test_postRequestNoLength.<locals>.validate5  s   $Y__%67F S[!,OOCF&+FFGOOJvbz:3C3C3P3PQROOJvbz:3C3C3M3MNOOOJvbz:3C3C3M3MNOT&*//2D9L4MNVBZ__.>?VBZ__c2OOLF2J,<,<<=r+   r1   )r*  r   r   r  r  r+  r  r  )
r'   xyr*  r   r   r  r)  r(  r  s
   `      @@@r(   test_postRequestNoLengthz)HTTP2ServerTests.test_postRequestNoLength  s    

 H  $66
q!!?P:PQF
 
 "^
$9
!--*D,@,@
9	>  11!4@@JJ5
s
   BBc           	         	
 d}t               }t               	t               }t        |_        t        t        d|dz  d            

D cg c]$  }t         j                   j                  ||      & }}|j                         }t        j                  j                  t        |       }|dj                  d |D              z  }|j!                  	       t#        |      D ]  }|j%                  |        	 
fd}t'        j(                  t        |j*                  j-                                     j/                  |      S c c}w )zi
        Many interleaved POST requests all get received and responded to
        appropriately.
        (   r1   r  r+   c              3   <   K   | ]  }|j                           y wr#   r   r   r5   s     r(   r   z<HTTP2ServerTests.test_interleavedRequests.<locals>.<genexpr>b        Gu!2 Gr   c                    t        j                               }j                  t        |      d       D ]  }|D cg c]7  }|j                  |k(  r&t        |t        j                  j                        s|9 }}j                  t        |      d       j                  t        |d   j                        t        j                               j                  |d   j                  j                         j                  |d   j                  d       j                  d|d   j                  v         y c c}w )Ny   r  r   r1   r  r+   r   )r   r  r  r~   r  r   r4   r5   rP   r  r8   r(  r)  r  r9   )r   r   r>   r@   streamFramesbr'   	streamIDss        r(   r  z;HTTP2ServerTests.test_interleavedRequests.<locals>.validateh  s   $QWWY/F
 S[,7 & G $ {{h.&q**:*:*L*LM       \!2A6  a--.T5M5M0N   a!5!5t7L7LM  a!5!5s;Q0E0E EFG s    <E )r!   r   r   r   r  r   r   r   r*  r+  r0   	itertoolschainfrom_iterablezipr   r  r   r  r   DeferredListr  valuesr  )r'   REQUEST_COUNTr@   ar>   r   r  r  r  r;  r<  s   `        @@r(   test_interleavedRequestsz)HTTP2ServerTests.test_interleavedRequestsG  s1    NN0 q-!"3Q78	
 &	
  '')=)=q(
 
 002 ..sF|< G GGG	l+ 	!DNN4 	!	G6 !!$q'@'@'G'G'I"JKWW
 	
[
s   )Ec           	      T   
 t               }t               
t               }t        |_         j
                  }d|d<   dD cg c]  }t        |g ||       }}|d   d   j                  j                  d       d|d   d   _	        |d   d   j                  j                  d       d|d   d   _	        |j                  d	d
dd      }|d   j                  d|       t        j                  j                  |      }|j                         }|dj!                  d |D              z  }|j#                  
       t%        |      D ]  }|j'                  |        
 fd}	t)        j*                  t-        |j.                  j1                                     j3                  |	      S c c}w )zR
        Data in responses is interleaved according to HTTP/2 priorities.
        )z:pathz
/chunked/4r  )r1   r     r   PRIORITY@   r1       rG     T)r>   re   rf   rd   r+   c              3   <   K   | ]  }|j                           y wr#   r   r6  s     r(   r   z@HTTP2ServerTests.test_sendAccordingToPriority.<locals>.<genexpr>  r7  r   c                     t        j                               }j                  t        |      d       |D cg c]3  }t	        |t
        j                  j                        s(|j                  5 }}g d}j                  ||       y c c}w )N   )r1   r  r1   r1   r  r1   r1   r  rG  r  rG  r  rG  rG  rG  )	r   r  r  r~   r   r4   r5   rG   r  )r   r   r@   r<  expectedOrderr;  r'   s        r(   r  z?HTTP2ServerTests.test_sendAccordingToPriority.<locals>.validate  s{    $QWWY/F S["- &, !z!Z=M=M=W=W/XI  JMY6	s   )B$B)r!   r   r   ChunkedHTTPHandlerProxyr  r  r   r9   r:   rc   rg   insertr=  r>  r?  r0   r   r  r   r  r   rA  r   r  rB  r  )r'   r@   rD  r  r>   r   priorityFramer  r  r  r;  s   `         @r(   test_sendAccordingToPriorityz-HTTP2ServerTests.test_sendAccordingToPriority  s   " NN2 226! &
 0"aB
 
 	q	!z*%'q	!"q	!z*%'q	!",,	 - 
 	q	M*..v6002 G GGG	l+ 	!DNN4 	!	7 !!$q'@'@'G'G'I"JKWW
 	
W
s   F%c                    t               }t               }t               }t        |_        |j                         }|t        | j                  g |      z  }||j                  dd| j                  dg      j                         z  }|j                  |       t        |      D ]!  }|j                  |       |j                  s! n t        |j                               }| j!                  t#        |      d       | j%                  t'        |d   t(        j*                  j,                               | j%                  |j                         y)zR
        A protocol error from the remote peer terminates the connection.
        r1   r  r3   )r>   rk   r=   r9   r  r   N)r!   r   r   r   r  r0   r   r  rl   r   r  r   r  disconnectingr   r  r  r~   r  r   r4   r5   rU   )r'   r@   r;  rD  r  r  r   s          r(   &test_protocolErrorTerminatesConnectionz7HTTP2ServerTests.test_protocolErrorTerminatesConnection  s    NN0 002)$*@*@"aHH//** /	 0 

 )+	 	
l+ 	DNN4  	 !+
 	Va(
6":z/?/?/K/KLM(r+   c                     t               }t        |_         j                  | j                   j
                        \  }|j                  d   j                  j                  } j                  |j                         t        j                               } j                  t        |      d       |j                           j!                  |j                          j!                  |j"                  d       t        j                               } j                  t        |      d        fd}|j$                  d   j'                  |      S )z
        The H2Stream data implements IPushProducer, and can have its data
        production controlled by the Request if the Request chooses to.
        r1   s   hello world, it's http/2!r  c                     t        j                               }j                  t        |      d       j	                  d|d   j
                  v        y Nr
  r   r   r   r  r  r~   r  r9   r  s     r(   r  z;HTTP2ServerTests.test_streamProducingData.<locals>.validate  sE    $Y__%67F S[!,OOLF2J,<,<<=r+   )r   ConsumerDummyHandlerProxyr  r  r*  r+  streams_requestoriginalassertFalser   r   r  r  r~   r   r  rv   r  r  )r'   r   r   requestr   r  r  s   `     @r(   test_streamProducingDataz)HTTP2ServerTests.test_streamProducingData  s   
 "^
$=
!--//1E1E
9 $$Q'0099112
 !!23Va(
 	001'CD
 !!23Va(	> 11!4@@JJr+   c                 `   	 t               }t               	t               }t        |_        t         j                   j                  |      }t               |d   _	        |j                         }|dj                  d |D              z  }|j                  	       t        |      D ]  }|j                  |        |j                  d   j                   j"                  } j%                  |j&                         |j(                  d   }|j+                          	 fd}|j-                  |      S )z
        The H2Stream data implements IPushProducer, and can have its data
        production controlled by the Request if the Request chooses to.
        When the production is stopped, that causes the stream connection to
        be lost.
        r   r+   c              3   <   K   | ]  }|j                           y wr#   r   r   s     r(   r   zAHTTP2ServerTests.test_abortStreamProducingData.<locals>.<genexpr>2        ?1 ?r   r1   c                    t        j                               }j                  t        |      d       j	                  t        |d   t        j                  j                               j                  |d   j                  d       y )Nr  r   r1   )
r   r  r  r~   r  r   r4   r5   r^   r  )r>   r   r;  r'   s     r(   r  z@HTTP2ServerTests.test_abortStreamProducingData.<locals>.validateE  sf    $QWWY/F S[!,OOJvbz:3C3C3R3RSTVBZ1115r+   )r!   r   r   !AbortingConsumerDummyHandlerProxyr  r   r*  r+  rF   r9   r0   r   r  r   r  r\  r]  r^  r_  r   r  r   r  )
r'   r@   rD  r   r  r  r`  cleanupCallbackr  r;  s
   `        @r(   test_abortStreamProducingDataz.HTTP2ServerTests.test_abortStreamProducingData"  s
    NN< $D$;$;T=Q=QSTU5r
002 ? ???	l+ 	!DNN4 	!
 ))A,''00112 33A6 		6 **844r+   c                 8    t               }t        |_         j                  | j                  g       \  }|j
                  d   j                  j                  }|j                  d       |j                  d       |j                  d   }|j                  |j                  dd      j                                 j                  |j                          j                  |j                  du        |j                  d        fd}|j!                  |      S )z
        When a RstStream frame is received, the L{H2Connection} and L{H2Stream}
        objects tear down the L{http.Request} and swallow all outstanding
        writes.
        r1      first chunk   second chunk)rZ   Ns   third chunkc                    t        j                               }j                  t        |      d       j                  |d   j                  d       j                  t        |d   t        j                  j                               y Nr  r1   
r   r  r  r~   r  r  r   r4   r5   r6   r  s     r(   r  z9HTTP2ServerTests.test_terminatedRequest.<locals>.validate{  e    $Y__%67FS[!,VAY00!4OOJvay*2B2B2O2OPQr+   )r   DummyProducerHandlerProxyr  r  r  r\  r]  r^  r   r  r  r_   r   r  _disconnectedr   r  r'   r   r   r`  rg  r  r  s   `     @r(   test_terminatedRequestz'HTTP2ServerTests.test_terminatedRequestP  s     "^
$=
!"&"8"8..#
i
 $$Q'0099 	n%o& %<<Q? 	,,Q!,<FFH	

 	--.4/0 	n%	R **844r+   c                 J    t               }t        |_         j                  | j                  g       \  }|j
                  d   j                  j                  }|j                  d       |j                  d       |j                  d   }|j                  |j                  d      j                                 j                  |j                          j                  |j                  du         j!                  |j"                          fd}|j%                  |      S )z
        When a GoAway frame is received, the L{H2Connection} and L{H2Stream}
        objects tear down all outstanding L{http.Request} objects and stop all
        writing.
        r1   rj  rk  r   rY   Nc                    t        j                               }j                  t        |      d       j                  |d   j                  d       j                  t        |d   t        j                  j                               y rm  rn  r  s     r(   r  z<HTTP2ServerTests.test_terminatedConnection.<locals>.validate  ro  r+   )r   rp  r  r  r  r\  r]  r^  r   r  r  r\   r   r  rq  r   r_  _stillProducingr  rr  s   `     @r(   test_terminatedConnectionz*HTTP2ServerTests.test_terminatedConnection  s    "^
$=
!"&"8"8..#
i
 $$Q'0099 	n%o& %<<Q? 	))q)9CCE	

 	--.4/0 	334	R **844r+   c                      t               }t        |_         j                  dgz   } j	                  ||g       \  } fd}|j
                  d   j                  |      S )zq
        Requests containing Expect: 100-continue cause provisional 100
        responses to be emitted.
        )s   expects   100-continuec                    t        j                               }j                  t        |      d       j	                  t        d |dd  D                     j	                  t        |d   t        j                  j                               j                  |d   j                  dg       j	                  d|d   j                  v        y )NrG  c              3   :   K   | ]  }|j                   d k(    ywr  r  r   s     r(   r   zQHTTP2ServerTests.test_respondWith100Continue.<locals>.validate.<locals>.<genexpr>  r  r  r1   )r   s   100r   r   )r   r  r  r~   r  r  r   r4   r5   r6   r8   r9   r  s     r(   r  z>HTTP2ServerTests.test_respondWith100Continue.<locals>.validate  s    $Y__%67FS[!,OOCE&*EEFOOJvay*2B2B2O2OPQVAY^^.B-CDOOLF2J,<,<<=r+   r1   )r   r   r  r  r  r  r  )r'   r   r=   r   r  r  s   `    @r(   test_respondWith100Continuez,HTTP2ServerTests.test_respondWith100Continue  se    
 "^
$9
! ((,H+II--j'2F9
	> 11!4@@JJr+   c                     t               }t        |_         j                  | j                  g       \  }|j
                  d   }|j                  j                  }|j                  d   }|j                           j                  |j                          j                  |j                  du         fd}|j                  |      S )z
        Triggering the call to L{H2Stream._respondToBadRequestAndDisconnect}
        leads to a 400 error being sent automatically and the stream being torn
        down.
        r1   Nc                 Z   t        j                               }j                  t        |      d       j	                  t        |d   t        j                  j                               j                  |d   j                  dg       j	                  d|d   j                  v        y )Nr  r1   )r   s   400r   r   )r   r  r  r~   r  r   r4   r5   r6   r8   r9   r  s     r(   r  z6HTTP2ServerTests.test_respondWith400.<locals>.validate  s    $Y__%67FS[!,OOJvay*2B2B2O2OPQVAY^^.B-CDOOLF2J,<,<<=r+   )r   rp  r  r  r  r\  r]  r^  r  !_respondToBadRequestAndDisconnectr  rq  r   r  )r'   r   r   streamr`  rg  r  r  s   `      @r(   test_respondWith400z$HTTP2ServerTests.test_respondWith400  s     "^
$=
!--j$:P:PRTU9 ##A&//**$<<Q? 	002 	--.4/0	> **844r+   c                 ^    t               }t        |_         j                  | j                  g       \  }|j
                  d   }|j                  j                  }g dD ]  }|j                  |        |j                           fd}|j                  d   j                  |      S )z
        Calling L{Request.loseConnection} causes all data that has previously
        been sent to be flushed, and then the stream cleanly closed.
        r1   )   hello   world   here   are   some   writesc                    t        j                               }j                  t        |      d       j	                  t        d |dd  D                     j	                  t        |d   t        j                  j                               j	                  d|d   j                  v        |D cg c]3  }t        |t        j                  j                        s(|j                  5 }}j                  |dgz          y c c}w )Nr|   c              3   :   K   | ]  }|j                   d k(    ywr  r  r   s     r(   r   zQHTTP2ServerTests.test_loseH2StreamConnection.<locals>.validate.<locals>.<genexpr>  r  r  r1   r   r   r+   r   r  r  r~   r  r  r   r4   r5   r6   r9   rG   r8   )r>   r   r@   receivedDataChunks
dataChunksr'   r  s       r(   r  z>HTTP2ServerTests.test_loseH2StreamConnection.<locals>.validate  s    $Y__%67F S[!,OOCE&*EEFOOJvay*2B2B2O2OPQOOLF2J,<,<<= !'"*Q
8H8H8R8R*S" " "cU""s   4)DD)r   rp  r  r  r  r\  r]  r^  r   loseConnectionr  r  )	r'   r   r   r  r`  r   r  r  r  s	   `      @@r(   test_loseH2StreamConnectionz,HTTP2ServerTests.test_loseH2StreamConnection  s     "^
$=
!--j$:P:PRTU9 ##A&//** O
 	!EMM% 	! 	 	$ 11!4@@JJr+   c                     t               }t        |_        | j                  || j                  g        |j
                  d   }|j                  j                  }| j                  t        |j                  |d       y)zK
        The L{H2Stream} object forbids registering two producers.
        r1   TN)r   rp  r  r  r  r\  r]  r^  r   
ValueErrorr   )r'   r   r  r`  s       r(   test_cannotRegisterTwoProducersz0HTTP2ServerTests.test_cannotRegisterTwoProducers)  sf     "^
$=
!z4+A+A2F ##A&//***f&=&=wMr+   c                 X    t               }t        |_         j                  | j                  g       \  }|j
                  d   }|j                  j                  j                  j                  }|j                  fd        fd}|j                  d   j                  |      S )z
        L{Request} objects that have registered pull producers get blocked and
        unblocked according to HTTP/2 flow control.
        r1   c                 $    j                         S r#   )r   )r0  r`  s    r(   <lambda>z;HTTP2ServerTests.test_handlesPullProducer.<locals>.<lambda>E  s    w~~/? r+   c                 &   t        j                               }j                  d|d   j                  v        |D cg c]3  }t	        |t
        j                  j                        s(|j                  5 }}j                  |g d       y c c}w )Nr   r   )   0r   r      3   4   5   6   7   8   9r+   
r   r  r  r9   r   r4   r5   rG   r8   r  r>   r   r@   r  r'   r  s       r(   r  z;HTTP2ServerTests.test_handlesPullProducer.<locals>.validateH  s    $Y__%67F OOLF2J,<,<<= !'*Q
8H8H8R8R*SJ  Q   )B)B)r   r   r  r  r  r\  r]  r^  _actualProducerresultr  r  )r'   r   r   r  producerCompleter  r`  r  s   `     @@r(   test_handlesPullProducerz)HTTP2ServerTests.test_handlesPullProducer7  s    
 "^
$A
!--j$:P:PRTU9 ##A&//**"2299$$%?@	 11!4@@JJr+   c                 &   t               }t        |_        | j                  || j                  g        |j
                  d   j                  j                  }| j                  |j                                |j
                  d   j                          y)zJ
        L{Request} objects can correctly ask isSecure on HTTP/2.
        r1   N)r   r   r  r  r  r\  r]  r^  r_  isSecureabortConnection)r'   r   r`  s      r(   test_isSecureWorksProperlyz+HTTP2ServerTests.test_isSecureWorksProperlyY  su     "^
$;
!z4+A+A2F$$Q'0099))+,1--/r+   c                 >    t               }t        |_         j                  | j                  g       \  }|j
                  d   j                  j                  }t        j                  d|j                          fd}|j                  d   j                  |      S )zL
        L{H2Connection} correctly unblocks when a stream is ended.
        r1   {Gz?c                      t        j                               }j                  t        |      d       j	                  d|d   j
                  v        y )Nr  r   r   rZ  )r   r   r'   r  s     r(   validateCompletezCHTTP2ServerTests.test_lateCompletionWorks.<locals>.validateCompleter  sE    $Y__%67F S[!,OOLF2J,<,<<=r+   )r   r   r  r  r  r\  r]  r^  r   	callLaterr   r  r  )r'   r   r   r`  r  r  s   `    @r(   test_lateCompletionWorksz)HTTP2ServerTests.test_lateCompletionWorkse  s     "^
$;
!--j$:P:PRTU9 $$Q'0099$/	> 11!4@@AQRRr+   c                 n    t               }t        |_         j                  | j                  g       \  }|j
                  d   }|j                  j                  }|j                  d       |j                  g d       |j                          |j                  d   } fd}|j                  |      S )zW
        L{H2Stream} objects can send a series of frames via C{writeSequence}.
        r1   r   )   Hello   ,   world!c                 &   t        j                               }j                  d|d   j                  v        |D cg c]3  }t	        |t
        j                  j                        s(|j                  5 }}j                  |g d       y c c}w )Nr   r   )r  r  r  r+   r  r  s       r(   r  z@HTTP2ServerTests.test_writeSequenceForChannels.<locals>.validate  s~    $Y__%67F OOLF2J,<,<<= !'*Q
8H8H8R8R*SJ  Z)IJr  )r   r   r  r  r  r\  r]  r^  r   writeSequencer   r  r  )r'   r   r   r  r`  completionDeferredr  r  s   `      @r(   test_writeSequenceForChannelsz.HTTP2ServerTests.test_writeSequenceForChannels{  s     "^
$;
!--j$:P:PRTU9##A&//**$89'??B
	K "--h77r+   c                    	
 t               
t               t               t        _        
j                         }|
j                  t        j                  j                  j                  di      j                         z  }|t         j                  g 
      z  }j                         t        |      D ]  }j!                  |        j"                  d   }|j$                  j&                  j)                  d       g d		fd}t+        j,                  t.        d|      }|j1                  
fd       	 fd}j2                  d   j1                  |      S )	z
        Delaying writes from L{Request} causes the L{H2Connection} to block on
        sending until data is available. However, data is *not* sent if there's
        no room in the flow control window.
        rG  r1      fiver)r  r  r  r  c                  V    D ]  } j                  |         j                          y r#   )r   r   )r   r  r`  s    r(   write_chunksz7HTTP2ServerTests.test_delayWrites.<locals>.write_chunks  s(    # %e$%NNr+   r  c                  d    j                  j                  dd      j                               S )Nr1   2   r>   rR   )r  rS   r   )r   rD  r@   s    r(   r  z3HTTP2ServerTests.test_delayWrites.<locals>.<lambda>  s,    !..((!r(BLLN r+   c                    t        j                               }j                  t        |      d       j	                  t        d |dd  D                     j	                  t        |d   t        j                  j                               j	                  d|d   j                  v        |D cg c]3  }t        |t        j                  j                        s(|j                  5 }}j                  |dgz   dgz          y c c}w )Nr|   c              3   :   K   | ]  }|j                   d k(    ywr  r  r   s     r(   r   zFHTTP2ServerTests.test_delayWrites.<locals>.validate.<locals>.<genexpr>  r  r  r  r   r   r  r+   r  )r>   r   r@   r  r;  r  r'   s       r(   r  z3HTTP2ServerTests.test_delayWrites.<locals>.validate  s    $QWWY/F S[!,OOCE&*EEFOOJvay*2B2B2O2OPQOOLF2J,<,<<= !'"*Q
8H8H8R8R*S" " "
Z'3%/"s   4)D	D	)r!   r   r   r   r  r0   rN   h2rL   SettingCodesINITIAL_WINDOW_SIZEr   r   r  r  r   r  r\  r]  r^  r   r   
deferLaterr   r  r  )r'   r  r  r  r  dr  rD  r;  r  r@   r`  s   `      @@@@@r(   test_delayWritesz!HTTP2ServerTests.test_delayWrites  s/    NN2002,,[[%%991=

)+	 	)$*@*@"aHH	l+ 	!DNN4 	! 1//** 	h:
	 OOGT<8		
	$ ((+77AAr+   c                    t               }t               }t               }t        |_        |j                         }|t        | j                  g |      z  }||j                  d      j                         z  }|j                  |       |j                  |       t        |j                               }| j                  t        |      d       | j!                  d|j"                         y)zu
        A client that immediately resets after sending the body causes Twisted
        to send no response.
        r=   r8   r   r1   r   N)r!   r   r   r   r  r0   r   r  r_   r   r  r  r   r  r  r~   assertNotInr  )r'   r   r  rD  r  r   s         r(   test_resetAfterBodyz$HTTP2ServerTests.test_resetAfterBody  s    
 $~#%	N0#;;=)**,
 	
 	88!8DNNPP	#	|$ !23Va(A556r+   c                     t        j                          G fddt              }t               t	        j
                         }t        |      _        |_        t               _
         j                   j                  g         fd}j                  |       j                  d   }t        j                  |g      S )z
        A custom L{Request} subclass that requires the site and factory in the
        constructor is able to get them.
        c                       e Zd Z fdZy)THTTP2ServerTests.test_RequestRequiringFactorySiteInConstructor.<locals>.SuperRequestc                     t        j                  | g|i | j                  | j                  j                  | j                  j
                  f       y r#   )r   r)   callbackr   sitefactory)r'   r   r   r  s      r(   r)   z]HTTP2ServerTests.test_RequestRequiringFactorySiteInConstructor.<locals>.SuperRequest.__init__  s@     ))$@@@

DLL--t||/C/CDEr+   N)rn   ro   rp   r)   )r  s   r(   SuperRequestr    s	    Fr+   r  c                     | \  }}j                  |j                         j                  |j                         y r#   )assertIsr  r  )r   r  r  r   r'   s      r(   validateFactoryAndSitez^HTTP2ServerTests.test_RequestRequiringFactorySiteInConstructor.<locals>.validateFactoryAndSite	  s2     MD'MM$
0MM':#5#56r+   r1   )r   Deferredr   r   r   HTTPFactoryr   r  r  objectr  r  r  r  r  gatherResults)r'   r  httpFactoryr  rg  r   r  s   `    @@r(   -test_RequestRequiringFactorySiteInConstructorz>HTTP2ServerTests.test_RequestRequiringFactorySiteInConstructor  s    
 NN	F+ 	F
 "^
&&($<\$J
! )
 (
z4+A+A2F	7
 	
,- %<<Q?""A#788r+   c                 d    t               }t        t              |_         j	                  | j
                  g       \  }}|j                  j                  } j                  t        |      d        fd}|d   }|j                  |       |j                  d   }t        j                  ||g      S )z
        A request sent to a HTTP/2 connection fires the
        L{http.Request.notifyFinish} callback with a L{None} value.
        r1   c                 (    j                  |        y r#   )assertIsNone)r  r'   s    r(   r  z?HTTP2ServerTests.test_notifyOnCompleteRequest.<locals>.validate!  s    f%r+   r   )r   r   r   r  r  r  r   r  r~   r  r  r   r  )r'   r   r   r  	deferredsr  r  rg  s   `       r(   test_notifyOnCompleteRequestz-HTTP2ServerTests.test_notifyOnCompleteRequest  s    
 "^
$;<L$M
!--j$:P:PRTU9--55	Y+	& aL	h %<<Q?""A#788r+   c                     t               }t        t              |_         j	                  | j
                  g       \  }}|j                  j                  } j                  t        |      d        fd} fd}|d   }|j                  ||       |j                  d      j                         }|j                  |       |S )zw
        A HTTP/2 reset stream fires the L{http.Request.notifyFinish} deferred
        with L{ConnectionLost}.
        r1   c                 (    j                  d       y Nz#Didn't errback, called back insteadfailignr'   s    r(   r  z;HTTP2ServerTests.test_notifyOnResetStream.<locals>.callback<      II;<r+   c                     j                  | t        j                         j                  | j                  t
        j                         y r#   assertIsInstancer   Failurer  typer   ConnectionLostreasonr'   s    r(   errbackz:HTTP2ServerTests.test_notifyOnResetStream.<locals>.errback?  2    !!&'//:MM&++u';';<r+   r   r   )r   r   r   r  r  r  r   r  r~   addCallbacksr_   r   r  )	r'   r   r   r  r  r  r  r  invalidDatas	   `        r(   test_notifyOnResetStreamz)HTTP2ServerTests.test_notifyOnResetStream,  s    
 "^
$;<N$O
!"&"8"8..#
i --55	Y+	=	
 aL	x) #666BLLN,r+   c                 
    t               }t        t              |_         j	                  | j
                  g       \  }}t         j
                  g |d      }|j                  |       |j                  j                  } j                  t        |      d        fd} fd}|D ]  }|j                  ||        |j                  dd      j                         }	|j                  |	       t        j                  |      S )	z
        A HTTP/2 protocol error triggers the L{http.Request.notifyFinish}
        deferred for all outstanding requests with a Failure that contains the
        underlying exception.
        r  r   r>   r  c                 (    j                  d       y r  r  r  s    r(   r  z=HTTP2ServerTests.test_failWithProtocolError.<locals>.callbackg  r  r+   c                     j                  | t        j                         j                  | j                  t        j
                  j                         y r#   )r  r   r  r  r  
exceptionsProtocolErrorr  s    r(   r  z<HTTP2ServerTests.test_failWithProtocolError.<locals>.errbackj  s8    !!&'//:!!&,,0K0KLr+      yo   r8   r>   )r   r   r   r  r  r  r   r  r   r  r~   r  rH   r   r   r  
r'   r   r   r  secondRequestr  r  r  r  r  s
   `         r(   test_failWithProtocolErrorz+HTTP2ServerTests.test_failWithProtocolErrorM  s     "^
$;<N$O
!"&"8"8..#
i *""B\A
 	. --55	Y+	=	
  	.ANN8W-	.
 #11ut1LVVX,""9--r+   c                     t               }t        t              |_         j	                  | j
                  g       \  }}t         j
                  g |d      }|j                  |       |j                  j                  } j                  t        |      d        fd} fd}|D ]  }|j                  ||        |j                  d      j                         }	|j                  |	       t        j                  |      S )z
        A HTTP/2 GoAway triggers the L{http.Request.notifyFinish}
        deferred for all outstanding requests with a Failure that contains a
        RemoteGoAway error.
        r  r  r  c                 (    j                  d       y r  r  r  s    r(   r  z4HTTP2ServerTests.test_failOnGoaway.<locals>.callback  r  r+   c                     j                  | t        j                         j                  | j                  t
        j                         y r#   r  r  s    r(   r  z3HTTP2ServerTests.test_failOnGoaway.<locals>.errback  r  r+   ru  )r   r   r   r  r  r  r   r  r   r  r~   r  r\   r   r   r  r  s
   `         r(   test_failOnGoawayz"HTTP2ServerTests.test_failOnGoawayy  s     "^
$;<N$O
!"&"8"8..#
i *""B\A
 	. --55	Y+	=	
  	.ANN8W-	. #333CMMO,""9--r+   c                     t               }t        t              |_         j	                  | j
                  g       \  }}t         j
                  g |d      }|j                  |       |j                  j                  } j                  t        |      d        fd} fd}|D ]  }|j                  ||        |j                          t        j                  |      S )z
        The transport telling the HTTP/2 connection to stop producing will
        fire all L{http.Request.notifyFinish} errbacks with L{error.}
        r  r  r  c                 (    j                  d       y r  r  r  s    r(   r  z;HTTP2ServerTests.test_failOnStopProducing.<locals>.callback  r  r+   c                     j                  | t        j                         j                  | j                  t
        j                         y r#   r  r  s    r(   r  z:HTTP2ServerTests.test_failOnStopProducing.<locals>.errback  r  r+   )r   r   r   r  r  r  r   r  r   r  r~   r  r   r   r  )	r'   r   r   r  r   r  r  r  r  s	   `        r(   test_failOnStopProducingz)HTTP2ServerTests.test_failOnStopProducing  s     "^
$;<N$O
!"&"8"8..#
i *""B\A
 	. --55	Y+	=	
  	.ANN8W-	. 	  """9--r+   c                 f    t               }t        t              |_         j	                  | j
                  g       \  }}|j                  j                  } j                  t        |      d        fd} fd}|d   }|j                  ||       |j                  d   }|j                          |S )z
        A HTTP/2 stream that has had _respondToBadRequestAndDisconnect called
        on it from a request handler calls the L{http.Request.notifyFinish}
        errback with L{ConnectionLost}.
        r1   c                 (    j                  d       y r  r  r  s    r(   r  z7HTTP2ServerTests.test_notifyOnFast400.<locals>.callback  r  r+   c                     j                  | t        j                         j                  | j                  t
        j                         y r#   r  r  s    r(   r  z6HTTP2ServerTests.test_notifyOnFast400.<locals>.errback  r  r+   r   )r   r   r   r  r  r  r   r  r~   r  r\  r  )	r'   r   r   r  r  r  r  r  r  s	   `        r(   test_notifyOnFast400z%HTTP2ServerTests.test_notifyOnFast400  s     "^
$;<N$O
!"&"8"8..#
i --55	Y+	=	
 aL	x) ##A&002r+   c                    t               }t        |      }|j                  |_        t        |_        d}t               }t               }|j                         }|j                  |       |j                  |       |j                  t        | j                  g ||             |j                          d|_        |j                  |       | j                  |j                          y)z
        A HTTP/2 stream that has had _respondToBadRequestAndDisconnect
        called on it does not write control frame data if its
        transport is paused and its control frame limit has been
        reached.
        r1   r   r   N)r
   r   r  r   r  r!   r   r0   r  r  r   r  r   _maxBufferedControlFrameBytesr  r  disconnected)r'   memoryReactorr   r>   r   r  r0   s          r(   test_fast400WithCircuitBreakerz/HTTP2ServerTests.test_fast400WithCircuitBreaker  s     +,!-0
,66
 %7
!#~#%	 #/"F"F"H!!), 78&&L8	
 	!!#34
044X>	../r+   c                 H   t               }t        |_        t               }t	               }|j                         }|j                  |       |j                  |       |j                          t        dd      D ]0  }|j                  |j                  i       j                                2 t        |j                               }| j                  t        |      d       |j!                          t        |j                               }| j                  t        |      d       y)z
        If a the L{H2Connection} has been paused by the transport, it will
        not write automatic frame data triggered by writes.
        r   d   r1   e   N)r   r   r  r!   r   r0   r  r  r   r   rN   r   r   r  r  r~   r   )r'   r   r   r  r0   r   r   s          r(    test_bufferingAutomaticFrameDataz1HTTP2ServerTests.test_bufferingAutomaticFrameData  s     "^
$9
!#~#%	"."F"F"H!!), 78 	!!# q# 	UA##L$C$CB$G$Q$Q$ST	U !!23Va( 	""$ !23Vc*r+   c                 d   t               }t        |_        t               }t	               }|j                         }|j                  |       |j                  |       |j                          d|_	        | j                  |j                         t        dd      D ]0  }|j                  |j                  i       j                                2 | j                  |j                         |j                  |j                  i       j                                | j                  |j                          y)z
        If the L{H2Connection} has been paused by the transport, it will
        not write automatic frame data triggered by writes. If this buffer
        gets too large, the connection will be dropped.
        r  r      N)r   r   r  r!   r   r0   r  r  r   r  r_  rU  r   rN   r   r  r  )r'   r   r   r  r0   r   s         r(   2test_bufferingAutomaticFrameDataWithCircuitBreakerzCHTTP2ServerTests.test_bufferingAutomaticFrameDataWithCircuitBreaker<  s     "^
$9
!#~#%	"."F"F"H!!), 78 	!!# 47
0 	001q" 	UA##L$C$CB$G$Q$Q$ST	U001 	 ? ? C M M OP	../r+   c                     G d dt               }t               }t        |_        t	               } |       }|j                  |d       |j                         }|j                  |       |j                  |       | j                  |j                         t        |j                               }| j                  t        |      d       | j                  |j                  d       t!        dd      D ]0  }|j                  |j#                  i       j%                                2 t        |j                               }| j                  t        |      d       | j                  |j                  d       |j'                          t        |j                               }| j                  t        |      d       | j                  |j                  d	       y
)z
        If the L{H2Connection} has buffered control frames, is unpaused, and then
        paused while unbuffering, it persists the buffer and stops trying to write.
        c                       e Zd Zd Zy)eHTTP2ServerTests.test_bufferingContinuesIfProducerIsPausedOnWrite.<locals>.AutoPausingStringTransportc                 j    t        j                  | g|i | | j                  j                          y r#   )r   r   producerr   r   s      r(   r   zkHTTP2ServerTests.test_bufferingContinuesIfProducerIsPausedOnWrite.<locals>.AutoPausingStringTransport.writee  s*    %%d<T<V<,,.r+   N)rn   ro   rp   r   r/   r+   r(   AutoPausingStringTransportr  d  s    /r+   r  Tr1   r   r  c   r  Z   N)r   r   r   r  r!   r   r0   r  r  assertIsNotNone_consumerBlockedr   r  r  r~   _bufferedControlFrameBytesr   rN   r   r   )r'   r  r   r   r  r0   r   r   s           r(   0test_bufferingContinuesIfProducerIsPausedOnWritezAHTTP2ServerTests.test_bufferingContinuesIfProducerIsPausedOnWrite^  s|   	/ 	/ "^
$9
!#~.0	"":t4"."F"F"H!!), 78 	Z889 !23Va(>>B q" 	UA##L$C$CB$G$Q$Q$ST	U !!23Va(>>G 	""$ !23Va(>>Gr+   c                    t               }t        |      }|j                  |_        t               }t	               }|j                         }|j                  |       |j                  |       |j                          d|_	        |j                  dd      j                         }|j                  |       | j                  |j                         y)z
        A client that triggers a L{h2.exceptions.ProtocolError} over a
        paused connection that's reached its buffered control frame
        limit causes that connection to be aborted.
        r   r  r  r  N)r
   r   r  r!   r   r0   r  r  r   r  rH   r   r  r  )r'   r  r   r   r  r0   r  s          r(   +test_circuitBreakerAbortsAfterProtocolErrorz<HTTP2ServerTests.test_circuitBreakerAbortsAfterProtocolError  s     +,!-0
,66
#~#%	 #/"F"F"H!!), 78 	!!#34
0 #11ut1LVVX 	,	../r+   N)+rn   ro   rp   r  r*  r+  r  r  r(  r)  r  r!  r,  r2  rE  rS  rV  ra  rh  rs  rx  r|  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r	  r  r  r  r  r%  r'  r/   r+   r(   r   r     s    DO *O B':K8K8)KV>
@E
N%)N+KZ,5\35j25hK8%5N+KZN KD
0S,8>@BD7. 9D9.B*.X(.T'.R%N(0T+> 0D+HZ0r+   r   c                   ~    e Zd ZdZg dZdZg dZg 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y)H2FlowControlTestszT
    Tests that ensure that we handle HTTP/2 flow control limits appropriately.
    )r   r   r   r   r   r   r   r   r   c                    	 t               }t               	t               }t        |_        |j                         }||j                  t        j                  j                  j                  di      j                         z  }|t         j                  g |      z  }|j                  	       t        |      D ]  }|j!                  |        t#         j$                        dz
  }t'        |      D ]4  }|j)                  dd      }|j!                  |j                                6 	 fd}|j*                  d   j-                  |      S )z
        When a L{Request} object is not using C{IProducer} to generate data and
        so is not having backpressure exerted on it, the L{H2Stream} object
        will buffer data until the flow control window is opened.
        rG  r1   r  c                     t        j                               }j                  d|d   j                  v        dj	                  d |D              }j                  j                  |       y )Nr   r   r+   c              3   ~   K   | ]5  }t        |t        j                  j                        s(|j                   7 y wr#   r   r4   r5   rG   r8   r   s     r(   r   zMH2FlowControlTests.test_bufferExcessData.<locals>.validate.<locals>.<genexpr>  .      **Q
8H8H8R8R*S*   )==)r   r  r  r9   r   r  r  r>   r   actualResponseDatar;  r'   s      r(   r  z:H2FlowControlTests.test_bufferExcessData.<locals>.validate  sg    $QWWY/F OOLF2J,<,<<= "% * &* " T113EFr+   )r!   r   r   r   r  r0   rN   r  rL   r  r  r   r   r  r  r   r  r~   r  r   rS   r  r  )
r'   r@   rD  r  r  bonusFramesr   r5   r  r;  s
   `        @r(   test_bufferExcessDataz(H2FlowControlTests.test_bufferExcessData  s*    NN0 002,,[[%%991=

)+	 	)$*@*@"aHH	l+ 	!DNN4 	! $../!3{# 	.A,,a1,EENN5??,-	.

	G ((+77AAr+   c                     t               }t               t               }t        |_        |j                         }||j                  t        j                  j                  j                  di      j                         z  }|t         j                  g |      z  }|j                         t        |      D ]  }|j!                  |        |j"                  d   }|j$                  j&                  } j)                  |j*                         |j-                  d        j/                  |j*                          j1                  |j2                  j4                  dg       |j!                  |j7                  dd      j                                 j/                  |j*                          j1                  |j2                  j4                  dg       |j!                  |j7                  dd      j                                 j/                  |j*                          j1                  |j2                  j4                  dg       |j!                  |j7                  dd      j                                 j)                  |j*                          j1                  |j2                  j4                  ddg       |j-                  d        j/                  |j*                          j1                  |j2                  j4                  g d       |j!                  |j7                  dd	      j                                 j)                  |j*                          j1                  |j2                  j4                  g d
       |j9                          |j;                           fd}|j<                  d   j?                  |      S )z
        L{Request} objects that have registered producers get blocked and
        unblocked according to HTTP/2 flow control.
        rG  r1   
   helloworldpauser  r   resume)r6  r7  r6  r  )r6  r7  r6  r7  c                 &   t        j                               }j                  d|d   j                  v        |D cg c]3  }t	        |t
        j                  j                        s(|j                  5 }}j                  |g d       y c c}w )Nr   r   )r5  r5  r+   r  r>   r   r@   r  r;  r'   s       r(   r  zDH2FlowControlTests.test_producerBlockingUnblocking.<locals>.validate9  s}    $QWWY/F OOLF2J,<,<<= !'*Q
8H8H8R8R*SJ  Z)LMr  ) r!   r   r   rp  r  r0   rN   r  rL   r  r  r   r   r  r  r   r  r\  r]  r^  r  _producerProducingr   r_  r  r  eventsrS   unregisterProducerr   r  r  	r'   r@   rD  r  r  r  r`  r  r;  s	   `       @r(   test_producerBlockingUnblockingz2H2FlowControlTests.test_producerBlockingUnblocking  s   
 NN4 002,,[[%%991=

)+	 	)$*@*@"aHH	l+ 	!DNN4 	! 1//** 	112 	m$ 	223))007)< 	
q//a/HRRTU223))007)< 	
q//a/HRRTU223))007)< 	
q//a/HRRTU112))007H2EF
 	m$223))002NO 	
q//b/ISSUV112##%K	
 	""$
	N ((+77AAr+   c                    	
 t               	t               t               t        _        	j                         }|	j                  t        j                  j                  j                  di      j                         z  }|t         j                  g 	      z  }j                         t        |      D ]  }j!                  |        j"                  d   j$                  j&                  
 j)                  j*                         
j-                  d        j/                  j*                          j1                  
j2                  j4                  dg       
j-                  d       	
 fd}t7        j8                  t:        d|      } fd}j<                  d   j?                  |      }tA        jB                  ||g      S )	zQ
        Exactly filling the flow control window still blocks producers.
        rG  r1   r5  r6     hc                  ,    j                  j                  dd      j                                j                  j                         j                  j                  j                  ddg       j                          j                          y )Nr1   r  r  r6  r7  )
r  rS   r   r  r:  r  r  r;  r<  r   )rD  r@   r`  r'   r  s   r(   window_openz=H2FlowControlTests.test_flowControlExact.<locals>.window_openn  sv    NN((!r(BLLN OOF556W--44w6IJ&&(NNr+   r   c                 &   t        j                               }j                  d|d   j                  v        |D cg c]3  }t	        |t
        j                  j                        s(|j                  5 }}j                  |g d       y c c}w )Nr   r   )r  r  r@  r+   r  r9  s       r(   r  z:H2FlowControlTests.test_flowControlExact.<locals>.validatez  s}    $QWWY/F OOLF2J,<,<<= !'*Q
8H8H8R8R*SJ  Z)HIr  )"r!   r   r   rp  r  r0   rN   r  rL   r  r  r   r   r  r  r   r  r\  r]  r^  r  r:  r   r_  r  r  r;  r   r  r   r  r  r   rA  )r'   r  r  rB  windowDeferr  validateDeferrD  r;  r@   r`  r  s   `      @@@@@r(   test_flowControlExactz(H2FlowControlTests.test_flowControlExactG  s    NN4 002,,[[%%991=

)+	 	)$*@*@"aHH	l+ 	!DNN4 	! 1//** 	112 	m$223))007)< 	d	 	 oogq+>
	J 11!4@@J!!;">??r+   c                 |    t               }t               t               }t        |_        |j                         }||j                  t        j                  j                  j                  di      j                         z  }|t         j                  g |      z  }|j                         t        |      D ]  }|j!                  |        |j"                  d   }|j$                  j&                  } j)                  |j*                         |j-                  d       |j/                          |j1                           j)                  |j2                         t5        j6                  d|j                   |j9                  dd      j                                 fd}|j:                  d   j=                  |      S )z
        L{Request} objects that end a stream that is currently blocked behind
        flow control can still end the stream and get cleaned up.
        rG  r1   r5  r   r  r  c                 &   t        j                               }j                  d|d   j                  v        |D cg c]3  }t	        |t
        j                  j                        s(|j                  5 }}j                  |g d       y c c}w )Nr   r   )r  r  r+   r  r9  s       r(   r  z=H2FlowControlTests.test_endingBlockedStream.<locals>.validate  s}    $QWWY/F OOLF2J,<,<<= !'*Q
8H8H8R8R*SJ  Z)BCr  )r!   r   r   rp  r  r0   rN   r  rL   r  r  r   r   r  r  r   r  r\  r]  r^  r  r:  r   r<  r   finishedr   r  rS   r  r  r=  s	   `       @r(   test_endingBlockedStreamz+H2FlowControlTests.test_endingBlockedStream  sw   
 NN4 002,,[[%%991=

)+	 	)$*@*@"aHH	l+ 	!DNN4 	! 1//** 	112 	m$""$ 	(() 	NN$$a2$>HHJ	

	D ((+77AAr+   c                    	 t               }t               	t               }t        |_        |j                         }|t         j                  g |      z  }|j                  	       t        |      D ]  }|j                  |        |j                  d   }|j                  j                  }|j                  d   }|j                          |j!                           j#                  |j$                         	 fd}|j'                  |      S )z<
        We safely handle responses without bodies.
        r1   c                 Z   t        j                               }j                  t        |      d       j	                  d|d   j
                  v        |D cg c]3  }t        |t        j                  j                        s(|j                  5 }}j                  |dg       y c c}w Nr  r   r   r+   r   r  r  r~   r  r9   r   r4   r5   rG   r8   r9  s       r(   r  z=H2FlowControlTests.test_responseWithoutBody.<locals>.validate      $QWWY/FS[!, OOLF2J,<,<<= !'*Q
8H8H8R8R*SJ     )B(B()r!   r   r   rp  r  r0   r   r  r  r   r  r\  r]  r^  r  r<  r   r  rI  r  
r'   r@   rD  r  r  r  r`  rg  r  r;  s
   `        @r(   test_responseWithoutBodyz+H2FlowControlTests.test_responseWithoutBody  s     NN 5 002)$*@*@"aHH	l+ 	!DNN4 	! 1//**33A6 	""$ 	(()	" **844r+   c                 |   	 t               }t               	t               }t        |_        |j                         }|t         j                  g |      z  }|j                  	       t        |      D ]  }|j                  |        |j                  d   }|j                  j                  }|j                  d   }|j                          |j!                           j#                  |j$                         |j                  |j'                  dd      j)                                	 fd}|j+                  |      S )zk
        WindowUpdate frames received after we've completed the stream are
        safely handled.
        r1   r  r  c                 Z   t        j                               }j                  t        |      d       j	                  d|d   j
                  v        |D cg c]3  }t        |t        j                  j                        s(|j                  5 }}j                  |dg       y c c}w rM  rN  r9  s       r(   r  zGH2FlowControlTests.test_windowUpdateForCompleteStream.<locals>.validate  rO  rP  )r!   r   r   rp  r  r0   r   r  r  r   r  r\  r]  r^  r  r<  r   r  rI  rS   r   r  rQ  s
   `        @r(   "test_windowUpdateForCompleteStreamz5H2FlowControlTests.test_windowUpdateForCompleteStream  s    NN 5 002)$*@*@"aHH	l+ 	!DNN4 	! 1//**33A6 	""$ 	(() 	
q//b/ISSUV	" **844r+   c                 *    t               }t               t               }t        |_        |j                         }||j                  t        j                  j                  j                  di      j                         z  }|t         j                  g |      z  }|j                         t        |      D ]  }|j!                  |        |j"                  d   }|j$                  j&                  } j)                  |j*                         |j-                  d        j)                  |j*                          j/                  |j0                  j2                  g        |j!                  |j5                  dd      j                                 j)                  |j*                          j/                  |j0                  j2                  g        |j7                          |j9                           fd}|j:                  d   j=                  |      S )z
        L{Request} objects that have registered producers that are not blocked
        behind flow control do not have their producer notified.
        rG  r1      wordr  c                 &   t        j                               }j                  d|d   j                  v        |D cg c]3  }t	        |t
        j                  j                        s(|j                  5 }}j                  |ddg       y c c}w )Nr   r   rW  r+   r  r9  s       r(   r  z;H2FlowControlTests.test_producerUnblocked.<locals>.validate`  s    $QWWY/F OOLF2J,<,<<= !'*Q
8H8H8R8R*SJ  Z'38r  )r!   r   r   rp  r  r0   rN   r  rL   r  r  r   r   r  r  r   r  r\  r]  r^  r  r:  r   r  r  r;  rS   r<  r   r  r  r=  s	   `       @r(   test_producerUnblockedz)H2FlowControlTests.test_producerUnblocked2  s   
 NN4 002,,[[%%991=

)+	 	)$*@*@"aHH	l+ 	!DNN4 	! 1//** 	112 	g 	112))00"5 	
q//a/HRRTU112))00"5 	""$
	9 ((+77AAr+   c                     t               }t               t               }t        |_        t         j                   j                  |      }|j                  d|j                  dd             |j                         }|dj                  d |D              z  }|j                         t        |      D ]  }|j                  |         fd}|j                  d   j!                  |      S )z
        When a WindowUpdate frame is received for the whole connection but no
        data is currently waiting, nothing exciting happens.
        r1   r   rG  r  r+   c              3   <   K   | ]  }|j                           y wr#   r   r   s     r(   r   zBH2FlowControlTests.test_unnecessaryWindowUpdate.<locals>.<genexpr>|  rd  r   c                     t        j                               }j                  d|d   j                  v        dj	                  d |D              }j                  j                  |       y )Nr   r   r+   c              3   ~   K   | ]5  }t        |t        j                  j                        s(|j                   7 y wr#   r-  r   s     r(   r   zTH2FlowControlTests.test_unnecessaryWindowUpdate.<locals>.validate.<locals>.<genexpr>  r.  r/  )r   r  r  r9   r   r  r)  r0  s      r(   r  zAH2FlowControlTests.test_unnecessaryWindowUpdate.<locals>.validate  sg    $QWWY/F OOLF2J,<,<<= "% * &* " T224FGr+   )r!   r   r   r   r  r   r*  r+  rQ  rS   r0   r   r  r   r  r  r  )r'   r@   rD  r   r  r  r  r;  s   `      @r(   test_unnecessaryWindowUpdatez/H2FlowControlTests.test_unnecessaryWindowUpdaten  s    
 NN0 $D$;$;T=Q=QSTUa1111JK002 ? ???	l+ 	!DNN4 	!
	H ((+77AAr+   c                    t               }t               }t               }t        |_        g }|j                  |j                  | j                  d             |j                  |j                  dd             |j                         }|dj                  d |D              z  }|j                  |       |j                  |       | j                  |       y)z
        When a WindowUpdate frame is received for a stream but no data is
        currently waiting, that stream is not marked as unblocked and the
        priority tree continues to assert that no stream can progress.
        r1   r   rG  r  r+   c              3   <   K   | ]  }|j                           y wr#   r   r   s     r(   r   zKH2FlowControlTests.test_unnecessaryWindowUpdateForStream.<locals>.<genexpr>  s     717r   N)r!   r   r   r   r  r   rD   r*  rS   r0   r   r  r  r   )r'   r@   r  connr   r8   s         r(   %test_unnecessaryWindowUpdateForStreamz8H2FlowControlTests.test_unnecessaryWindowUpdateForStream  s     N#%	~3
 a))$2I2ITU)VWa..Q.GH((*7777I&$$$T*r+   c                    t               }t               }t               }t        |_        t        | j                  | j                  |      }|j                         }|dj                  d |D              z  }|j                  |       t        |      D ]  }|j                  |        |j                  d   j                          |j                  dd      }|j                  |j!                                t#        |j%                               }| j'                  t)        |d   t*        j,                  j.                               y)zq
        When a WindowUpdate frame is received for a stream that has been
        aborted it is ignored.
        r+   c              3   <   K   | ]  }|j                           y wr#   r   r   s     r(   r   zEH2FlowControlTests.test_windowUpdateAfterTerminate.<locals>.<genexpr>  rd  r   r1   rG  r  r   N)r!   r   r   r   r  r   r*  r+  r0   r   r  r   r  r\  r  rS   r   r   r  r  r   r4   r5   r^   )r'   r@   r;  rD  r   r  r  windowUpdateFrames           r(   test_windowUpdateAfterTerminatez2H2FlowControlTests.test_windowUpdateAfterTerminate  s   
 NN0 $D$;$;T=Q=QSTU002 ? ???	l+ 	!DNN4 	! 	
		!$$& 44a14M	(2245 !+ 	
6":z/?/?/N/NOPr+   c                    	 t               	t               t               t        _        t         j                   j                  	      }	j                         }|dj                  d |D              z  }j                         t        |      D ]  }j                  |        	fd} fd}j                  d   j                  |      }|j                  |      S )zs
        When a WindowUpdate frame is received for a stream that has been
        completed it is ignored.
        r+   c              3   <   K   | ]  }|j                           y wr#   r   r   s     r(   r   zDH2FlowControlTests.test_windowUpdateAfterComplete.<locals>.<genexpr>  rd  r   c                  j    j                  dd      }j                  |j                                y )Nr1   rG  r  )rS   r  r   )r   re  rD  r@   s     r(   update_windowzHH2FlowControlTests.test_windowUpdateAfterComplete.<locals>.update_window  s/     ! 8 8!q 8 QNN,6689r+   c                  v    t        j                               }j                  d|d   j                         y )Nr   r   )r   r  assertInr9   r   r   r;  r'   s     r(   r  zCH2FlowControlTests.test_windowUpdateAfterComplete.<locals>.validate  s-    $QWWY/F MM,r
(8(89r+   r1   )r!   r   r   r   r  r   r*  r+  r0   r   r  r   r  r  r  )
r'   r   r  r  rj  r  r  rD  r;  r@   s
   `      @@@r(   test_windowUpdateAfterCompletez1H2FlowControlTests.test_windowUpdateAfterComplete  s    
 NN0 $D$;$;T=Q=QSTU002 ? ???	l+ 	!DNN4 	!	:
	: %%a(44]C}}X&&r+   c                     t               }t               }t               }t        |_        ddz  gdz  }t        d |D               }| j                  dd d|fgz   }t        |||      }|d= |j                  |j                  d	t        j                  j                  j                  
             |j                         }|dj                  d |D              z  }|j!                  |       |j#                  |       t%        |j'                               }|D 	cg c]2  }	t)        |	t*        j,                  j.                        r|	j0                  4 }
}	| j3                  dg|
       |D 	cg c])  }	t)        |	t*        j,                  j4                        s(|	+ }}	|D 	cg c])  }	t)        |	t*        j,                  j6                        s(|	+ }}	| j9                  |       | j9                  |       yc c}	w c c}	w c c}	w )z
        When a DATA frame is received at the same time as RST_STREAM,
        Twisted does not send WINDOW_UPDATE frames for the stream.
            i @  r
  c              3   2   K   | ]  }t        |        y wr#   )r~   )r   r8   s     r(   r   z;H2FlowControlTests.test_dataAndRstStream.<locals>.<genexpr>  s     <$CI<s   Nr   zcontent-lengthr  r1   )r>   rZ   r+   c              3   <   K   | ]  }|j                           y wr#   r   r   s     r(   r   z;H2FlowControlTests.test_dataAndRstStream.<locals>.<genexpr>	  rd  r   r   )r!   r   r   r   r  sumr*  r   r   r_   r  errors
ErrorCodesINTERNAL_ERRORr0   r   r  r  r   r  r   r4   r5   rP   r  r  r6   rG   r_  )r'   r   r  rD  	frameData
bodyLengthr=   r   r  r@   windowUpdateFrameIDsheadersFrames
dataFramess                r(   test_dataAndRstStreamz(H2FlowControlTests.test_dataAndRstStream  s   
 $~#%	N0
 &'!+	<)<<=
))#2.3CZ2P1QQ#),
 2J,,bii&:&:&I&I - 	
 $;;= ? ???	# 	
|$ !!23
  
!Z--??@ KK 
  

 	!23
 
Az/?/?/L/L!MA
 
 "(UA:a9I9I9S9S+TaU
U'$ 

 Vs   7G1*)G6G6)G;G;c                 R   t               }t        |      }|j                  |_        t        |_        t               }t               }|j                         }|j                  |       |j                  |       d}|j                  | j                  |      j                         }|j                  |       |j                          d|_        |j                          |j!                  |       | j#                  |j%                                | j'                  |j(                         y)z
        Aborting a request associated with a paused connection that's
        reached its buffered control frame limit causes that
        connection to be aborted.
        r1   r   r   N)r
   r   r  r   r  r!   r   r0   r  r  rD   r*  r   r   r  clearabortRequestr_  r  r  r  )r'   r  r   r   r  r0   r>   headersFrameDatas           r(   #test_abortRequestWithCircuitBreakerz6H2FlowControlTests.test_abortRequestWithCircuitBreaker#	  s    +,!-0
,66
$9
!#~#%	 #/"F"F"H!!), 78 '99++h : 

)+ 	 	 01 	!!#34
0 	 	) 	*+ 		../r+   N)rn   ro   rp   rq   r  r  r*  r+  r)  r3  r>  rF  rJ  rR  rU  rY  r^  rb  rf  rn  r|  r  r/   r+   r(   r)  r)    s     *O DOA+BZQBf@@D8Bt25h95v:Bx!BF+2Q@ 'D5%n)0r+   r)  c                   ,    e Zd Zg dZd Zd Zd Zd Zy)HTTP2TransportCheckingr   c                     t               }t               }t        |_        |j	                  |d       | j                  |j                  |u        y)zU
        L{H2Connection} can be registered with the transport as a producer.
        TN)r   r   r   r  r   r  r  )r'   r;  rD  s      r(   "test_registerProducerWithTransportz9HTTP2TransportChecking.test_registerProducerWithTransportZ	  s?     N0	1d#

a(r+   c                    	
 t               }t               	t               t        _        t         j                  g |      }|j                         }|dj                  d |D              z  }j                  	       	j                  d       t        |      D ]  }j                  |        j                          j                  d   
	
 fd}	 fd}t        j                   t"        d|      }|j%                  |       |S )z|
        L{H2Connection} can be paused by its consumer. When paused it stops
        sending data to the transport.
        r+   c              3   <   K   | ]  }|j                           y wr#   r   r   s     r(   r   zNHTTP2TransportChecking.test_pausingProducerPreventsDataSend.<locals>.<genexpr>r	  rd  r   Tr1   c                  |   t        j                               }j                  t        |      d       j	                  t        |d   t        j                  j                               j                          j                          j                          j                          j                          S )Nr  r   )
r   r  r  r~   r_  r   r4   r5   rG   r   )r   r   rD  r;  rg  r'   s     r(   validateNotSentzTHTTP2TransportChecking.test_pausingProducerPreventsDataSend.<locals>.validateNotSent	  s    $QWWY/FS[!,Zr
J4D4D4N4NOP ""r+   c                      t        j                               }j                  t        |      d       j	                  d|d   j
                  v        y rY  rZ  rm  s     r(   r  zUHTTP2TransportChecking.test_pausingProducerPreventsDataSend.<locals>.validateComplete	  sD    $QWWY/F S[!,OOLF2J,<,<<=r+   r  )r!   r   r   r   r  r   r  r0   r   r  r   r   r  r   r  r   r  r   r  )r'   r@   r   r  r  r  r  r  rD  r;  rg  s   `       @@@r(   $test_pausingProducerPreventsDataSendz;HTTP2TransportChecking.test_pausingProducerPreventsDataSende	  s    
 NN0 $D$:$:BB002 ? ???		1d# l+ 	!DNN4 	! 	
 33A6	#	> OOGT?;	&'r+   c                    t               }t               }t               }t        |_        t        | j                  g |      }|j                         }|dj                  d |D              z  }|j                  |       |j                  |d       t        |      D ]  }|j                  |        |j                          t        |j                               }| j!                  t#        |      d       | j%                  t'        |d   t(        j*                  j,                               | j%                  |j.                         y)zo
        L{H2Connection} can be stopped by its producer. That causes it to lose
        its transport.
        r+   c              3   <   K   | ]  }|j                           y wr#   r   r   s     r(   r   z<HTTP2TransportChecking.test_stopProducing.<locals>.<genexpr>	  rd  r   Tr  r   N)r!   r   r   r   r  r   r  r0   r   r  r   r   r  r   r   r  r  r~   r_  r   r4   r5   rG   rw  )r'   r@   r;  rD  r   r  r  s          r(   test_stopProducingz)HTTP2TransportChecking.test_stopProducing	  s   
 NN0 $D$:$:BB002 ? ???		1d# l+ 	!DNN4 	!
 	
 +Va(F2J
0@0@0J0JKL**+r+   c                 l   	
 t        ddd      	t        ddd      
t               }t        	
      }t               }t        |_        |j                  |       t         j                  g |      }|j                         }|dj                  d |D              z  }t        |      D ]  }|j                  |        |j                  d	    j                  j                         	        j                  j!                         
       |j"                  d	   }	
 fd
}|j%                  |      S )z{
        A L{H2Stream} object correctly passes through host and peer information
        from its L{H2Connection}.
        TCPz
17.52.24.8i  z17.188.0.12i}  )hostAddresspeerAddressr+   c              3   <   K   | ]  }|j                           y wr#   r   r6  s     r(   r   zEHTTP2TransportChecking.test_passthroughHostAndPeer.<locals>.<genexpr>	  r7  r   r1   c                      j                  j                                j                  j                                y r#   )r  getHostgetPeer)r   r  r  r'   r  s    r(   r  zDHTTP2TransportChecking.test_passthroughHostAndPeer.<locals>.validate	  s1    V^^-{;V^^-{;r+   )r	   r!   r   r   r   r  r  r   r  r0   r   r   r  r\  r  r  r  r  r  )r'   r   r  r   r   r  r  rg  r  r  r  r  s   `        @@@r(   test_passthroughHostAndPeerz2HTTP2TransportChecking.test_passthroughHostAndPeer	  s   
 "%s;!%>#~#U	!^
$9
!!!),#D$:$:BM#;;= G GGGl+ 	*D##D)	* ##A&);7);7 %<<Q?	< **844r+   N)rn   ro   rp   r  r  r  r  r  r/   r+   r(   r  r  O	  s    	)<|,>!5r+   r  c                       e Zd ZdZd Zy)HTTP2SchedulingTestsz
    The H2Connection object schedules certain events (mostly its data sending
    loop) using callbacks from the reactor. These tests validate that the calls
    are scheduled correctly.
    c                    t        j                         }t        |      } |j                         }| j	                  t        |      d       |d   }| j                  |j                                | j	                  |j                  d       | j	                  |j                  |j                         | j	                  |j                  d       | j	                  |j                  i        y)z}
        When a H2Connection is established it schedules one call to be run as
        soon as the reactor has time.
        r1   r   r/   N)r   Clockr   getDelayedCallsr  r~   r  activetimefunc_sendPrioritisedDatar   kw)r'   r   rD  callscalls        r(   "test_initiallySchedulesOneDataCallz7HTTP2SchedulingTests.test_initiallySchedulesOneDataCall	  s    
 **,!''')UQ'Qx 	&A&A$:$:;B'"%r+   N)rn   ro   rp   rq   r  r/   r+   r(   r  r  	  s    &r+   r  c                   ~    e Zd ZdZg dZ e       Zd Zd Zd Z	efdZ
d Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zy)HTTP2TimeoutTestsz@
    The L{H2Connection} object times out idle connections.
    r   c                 &    |j                   |_         y)a  
        Unfortunately, TimeoutMixin does not allow passing an explicit reactor
        to test timeouts. For that reason, we need to monkeypatch the method
        set up by the TimeoutMixin.

        @param connection: The HTTP/2 connection object to patch.
        @type connection: L{H2Connection}

        @param reactor: The reactor whose callLater method we want.
        @type reactor: An object implementing
            L{twisted.internet.interfaces.IReactorTime}
        N)r  )r'   r   r   s      r(   patch_TimeoutMixin_clockz*HTTP2TimeoutTests.patch_TimeoutMixin_clock
  s      '00
r+   c                    t        j                         }t        |      }d|_        | j	                  ||       t               }t        |      |_        |j                  |       t        |      D ]  }|j                  |        |||fS )a  
        Performs test setup by building a HTTP/2 connection object, a transport
        to back it, a reactor to run in, and sending in some initial data as
        needed.

        @param initialData: The initial HTTP/2 data to be fed into the
            connection after setup.
        @type initialData: L{bytes}

        @param requestFactory: The L{Request} factory to use with the
            connection.
        r  )r   r  r   timeOutr  r   r   r  r  r   r  )r'   initialDatar  r   ra  r  r  s          r(   initiateH2Connectionz&HTTP2TimeoutTests.initiateH2Connection#
  s     **,G$%%dG4#%	6~FI& k* 	$Dd#	$ y))r+   c                 8   t        |      }| j                  t        |      |       | j                  t	        |d   t
        j                  j                               | j                  |d   j                  |       | j                  |d   j                  |       y)z
        Confirm that the data that was sent matches what we expect from a
        timeout: namely, that it ends with a GOAWAY frame carrying an
        appropriate error code and last stream ID.
        r   N)
r   r  r~   r  r   r4   r5   rU   rV   rW   )r'   r8   
frameCountrZ   rY   r   s         r(   assertTimedOutz HTTP2TimeoutTests.assertTimedOut?
  sy     !&Vj1
6":z/?/?/K/KLM..	:22LAr+   c                    || j                   u rt        j                  }t               }|j	                         }| j                  |t              \  }}}||_         |j                  d       | j                  |j                         dt        j                  j                  j                  d       | j                  |j                         | j!                  |j"                         |||fS )a  
        Does the common setup for tests that want to test the aborting
        functionality of the HTTP/2 stack.

        @param abortTimeout: The value to use for the abortTimeout. Defaults to
            whatever is set on L{H2Connection.abortTimeout}.
        @type abortTimeout: L{int} or L{None}

        @return: A tuple of the reactor being used for the connection, the
            connection itself, and the transport.
        r  r  r  r   r  rZ   rY   )_DEFAULTr   abortTimeoutr!   r0   r  r   advancer  r  r  rt  ru  NO_ERRORr  rU  r_  r  )r'   r  r   r  r   ra  r  s          r(   prepareAbortTestz"HTTP2TimeoutTests.prepareAbortTestL
  s     4==('44L#~"::<#'#<#<+ $= $
 y ) 	OOii**33	 	 	
 		//0//0i''r+   c                    t               }|j                         }| j                  |t              \  }}}|j	                         } |j
                  d       | j                  ||j	                                | j                  |j                          |j
                  d       | j                  |j	                         dt        j                  j                  j                  d       | j                  |j                         y)z
        When a L{H2Connection} does not receive any data for more than the
        time out interval, it closes the connection cleanly.
        r  r   r  r   r  N)r!   r0   r  r   r  r  r  r_  rU  r  r  rt  ru  r  r  )r'   r   r  r   ra  r  preambles          r(   test_timeoutAfterInactivityz-HTTP2TimeoutTests.test_timeoutAfterInactivityr
  s    
 $~"::<#'#<#<+ $= $
 y ??$ 	 	9??#45001 	OOii**33	 	 	
 		//0r+   c                    t               }d}| j                  |t              \  }}}t        |j	                               D ]@  }|j                  |        |j                  d       | j                  |j                         B  |j                  d       | j                  |j                         dt        j                  j                  j                  d       | j                  |j                         y)zM
        When a L{H2Connection} receives data, the timeout is reset.
        r+   r  r   r  r   r  N)r!   r  r   r   r0   r  r  r_  rU  r  r  r  rt  ru  r  r  )r'   r   r  r   ra  r  r  s          r(   test_timeoutResetByRequestDataz0HTTP2TimeoutTests.test_timeoutResetByRequestData
  s    
 $~#'#<#<+ $= $
 y lBBDE 	6Dd# GOOB Y445	6 	OOii**33	 	 	
 		//0r+   c                   	 t               }d}g 	t        | j                  g |      }|j                         }|dj	                  d |D              z  }	fd}| j                  ||      \  }}}|j                  |j                                 |j                  d       | j                  t        	      d       t        d      D ]C  }	d   j                  d	        |j                  d       | j                  |j                         E  |j                  d
       | j                  |j                         dt         j"                  j$                  j&                  d       y)zJ
        When a L{H2Connection} sends data, the timeout is reset.
        r+   c              3   <   K   | ]  }|j                           y wr#   r   r   s     r(   r   zDHTTP2TimeoutTests.test_timeoutResetByResponseData.<locals>.<genexpr>
       >!>r   c                 D    t        | |      }j                  |       |S )N)queued)r   r   )r  r  r   requestss      r(   saveRequestzFHTTP2TimeoutTests.test_timeoutResetByResponseData.<locals>.saveRequest
  s     $VF;COOC Jr+   r  r   r1   
   r   s
   some bytesr     r  N)r!   r   r  r0   r   r  r  r  assertEqualsr~   r   r   r_  rU  r  r  r  rt  ru  PROTOCOL_ERROR)
r'   r   r  r   r  r   ra  r  r0  r  s
            @r(   test_timeoutResetByResponseDataz1HTTP2TimeoutTests.test_timeoutResetByResponseData
  sD   
 $~#D$:$:BM"::<sxx>v>>>	
 $(#<#<& $= $
 y
 	,>>@A 	#h-+r 	6AQKm,GOOBY445		6 	OOii**99	 	 	
r+   c                    t               }t        | j                  g |      }|j                         }|dj	                  d |D              z  }| j                  |t              \  }}} |j                  d       | j                  |j                         dt        j                  j                  j                  d       | j                  |j                         y)	z
        When a L{H2Connection} times out with active streams, the error code
        returned is L{h2.errors.ErrorCodes.PROTOCOL_ERROR}.
        r+   c              3   <   K   | ]  }|j                           y wr#   r   r   s     r(   r   zOHTTP2TimeoutTests.test_timeoutWithProtocolErrorIfStreamsOpen.<locals>.<genexpr>
  r  r   r  r  r  r1   r  N)r!   r   r  r0   r   r  r   r  r  r  r  rt  ru  r  r  rU  )r'   r   r   r  r   ra  r  s          r(   *test_timeoutWithProtocolErrorIfStreamsOpenz<HTTP2TimeoutTests.test_timeoutWithProtocolErrorIfStreamsOpen
  s    
 $~#D$:$:BM"::<sxx>v>>>#'#<#</ $= $
 y 	OOii**99	 	 	
 		//0r+   c                 
   t               }t        | j                  g |      }|j                         }|dj	                  d |D              z  }| j                  |t              \  }}}|j                         }t         |j                               }|j                  d       t         |j                               }	| j                  |dz
  |	        |j                  d       | j                  |j                         |       y)zU
        When a L{H2Connection} loses its connection it cancels its timeout.
        r+   c              3   <   K   | ]  }|j                           y wr#   r   r   s     r(   r   zCHTTP2TimeoutTests.test_noTimeoutIfConnectionLost.<locals>.<genexpr>  r  r   r  r  r1   r  N)r!   r   r  r0   r   r  r   r  r~   r  connectionLostr  r  )
r'   r   r   r  r   ra  r  sentDataoldCallCountcurrentCallCounts
             r(   test_noTimeoutIfConnectionLostz0HTTP2TimeoutTests.test_noTimeoutIfConnectionLost
  s     $~#D$:$:BM"::<sxx>v>>>#'#<#</ $= $
 y
 ??$272245 	H% 6w6689)+;< 	*H5r+   c                 L   | j                         \  }}} |j                  d       | j                  |j                         | j	                  |j
                          |j                  d       | j                  |j                         | j                  |j
                         y)z
        When a L{H2Connection} has timed the connection out, and the transport
        doesn't get torn down within 15 seconds, it gets forcibly closed.
           r1   Nr  r  r  rU  r_  r  r'   r   ra  r  s       r(   ,test_timeoutEventuallyForcesConnectionClosedz>HTTP2TimeoutTests.test_timeoutEventuallyForcesConnectionClosed  s    
 $(#8#8#: y 		//0//0	//0	../r+   c                    | j                         \  }}} |j                  d       |j                  d        |j                  d       | j                  |j                         | j                  |j                         y)z
        When a L{H2Connection} has timed the connection out, getting
        C{connectionLost} called on it cancels the forcible connection close.
        r  Nr1   )r  r  r  r  rU  r_  r  r  s       r(   $test_losingConnectionCancelsTheAbortz6HTTP2TimeoutTests.test_losingConnectionCancelsTheAbort'  sm    
 $(#8#8#: y 	D! 		//0//0r+   c                     | j                  d      \  }}} |j                  d       | j                  |j                         | j	                  |j
                         y)z
        When a L{H2Connection} has timed the connection out but the
        C{abortTimeout} is set to L{None}, the connection is never aborted.
        N)r  l        r  r  s       r(   'test_losingConnectionWithNoAbortTimeOutz9HTTP2TimeoutTests.test_losingConnectionWithNoAbortTimeOut7  sT    
 $(#8#8d#8#K y 		//0//0r+   c                     | j                         \  }}} |j                  d       | j                  |j                         | j                  |j                         |j                  t        j                         y)z}
        If a timed out transport doesn't close after 15 seconds, the
        L{HTTPChannel} will forcibly close it.
           N)r  r  r  rU  r  r  r   ConnectionDoner  s       r(   "test_connectionLostAfterForceClosez4HTTP2TimeoutTests.test_connectionLostAfterForceCloseD  sc    
 $(#8#8#: y 		//0	../
 	E001r+   c                    t               }t        |      }|j                  |_        d|_        t	               }t               }|j                         }|j                  |       |j                  |       t        |j                  |j                  z         D ]A  }|j                  |j                  d      j                                |j                  d       C | j                  |j                         y)zR
        A client that sends only invalid frames is eventually timed out.
        <   r1   N)r
   r   r  r  r!   r   r0   r  r  r   r  r_   r   r  r  r  )r'   r  r   r   r  r0   r   s          r(   ,test_timeOutClientThatSendsOnlyInvalidFramesz>HTTP2TimeoutTests.test_timeOutClientThatSendsOnlyInvalidFramesU  s     +,!-0
,66

#~#%	"."F"F"H!!), 78 z))J,C,CCD 	%A##L$D$DQ$G$Q$Q$ST!!!$	% 		../r+   N)rn   ro   rp   rq   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r/   r+   r(   r  r  
  sh     xH1*8B -5 $(L 1D 1D*
X146801 12"0r+   r  c                   0    e Zd ZdZes ed      seZddZy)EndToEndTestszK
    Tests that run real TCP-based communication with a HTTP/2 server.
    OpenSSLNc                   K   t        d      \  }}t        dd      }d|_        t        j                  dt        |      |j                               }|j                         j                  | j                  |j                         fd}t        |       d{   \  }}| j                  |d       | j                  |d       y7 ,w)	zR
        Twisted's HTTP/2 server can talk to a third-party HTTP/2 client.
        z
test.locals   hello worldzapplication/octet-streamTr   c                      t        j                  dd      } | j                  d d      }|j                  |j                  f}| j                          |S )NTF)http2verifyzhttps://127.0.0.1:/)httpxClientgethttp_versionr   close)clientresponser  portNums      r(   run_http2_queryz7EndToEndTests.test_realRequest.<locals>.run_http2_query  sO    \\U;Fzz$6wiq"ABH++X-=-=>FLLNMr+   NzHTTP/2)r   r   isLeafr   	listenSSLr   optionsr  port
addCleanupstopListeningr   r  )	r'   r   
serverCertresourcer  r  httpVersionr   r  s	           @r(   test_realRequestzEndToEndTests.test_realRequesty  s      :,G:(BC  DNJ4F4F4HI,,.%%**+	 (5_'E!Egh/.1 "Fs   BC
C-C
)returnN)rn   ro   rp   rq   r   r   r   r  r/   r+   r(   r  r  q  s     ]9-2r+   r  rm   )Prq   r=  zope.interfacer   r   r  twisted.internetr   r   r   r   twisted.internet.addressr	   twisted.internet.testingr
   r   twisted.internet.threadsr   twisted.pythonr   twisted.python.compatr   twisted.python.reflectr   twisted.test.test_internetr   twisted.test.test_sslverifyr   twisted.trialr   twisted.webr   twisted.web.serverr   twisted.web.staticr   twisted.web.test.test_httpr   r   r   r   r   r   r   r   r  	h2.errorsh2.exceptionsr4   r   hpack.hpackr   r   twisted.web._http2r   ImportErrorr!   rs   r   r   r   r   r   rP  r   r[  r   rf  r   rp  r   NotifyingRequestFactoryProxyr   TestCaser   r)  r  r  r  r  r/   r+   r(   <module>r     s    7  8 8 0 H 2 " + 0 4 I "  # #   
* ,/a aH' 'TB3.( ( 33EF 4<< D 55IJ %#7 %  %= % !
	54<< 	5 55IJ C C0  88OP M M"K0x((*: K0\(a
0**,< a
0HT5X..0@ T5n&8,,.> &8l0))+; l0^2H%% 2Y  *)F*s   >"G	 	GG