
    Ϫf                    @   d Z ddlZddlmZm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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l%Z%ddl&Z&ddl'm(Z(m)Z) ddl*m+Z+  G d d      Z- G d d      Z.d-dZ/d-dZ0d Z1 G d dejd                        Z3 e e3      Z4 G d dejd                        Z5 e e5      Z6 G d de5      Z7 e e7      Z8 G d dejd                        Z9 e e9      Z: G d d       Z; e e;      Z< G d! d"      Z= G d# d$ej|                  e=      Z? G d% d&ej|                  e=      Z@ G d' d(ej|                  e=      ZA G d) d*ej|                  e=      ZB G d+ d,ej|                  e=      ZCy# e,$ r dZ!Y w xY w).z
Test HTTP/2 support.
    N)directlyProvides
providedBy)defererrorreactortask)IPv4Address)MemoryReactorClockStringTransport)failure)	iterbytes)DummyProducer)unittest)http)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    =/usr/lib/python3/dist-packages/twisted/web/test/test_http2.py__init__zFrameFactory.__init__8       y    c                 "    t               | _        y r   r   r!   s    r#   refreshEncoderzFrameFactory.refreshEncoder;   r%   r&   c                      y)Ns   PRI * HTTP/2.0

SM

 r!   s    r#   clientConnectionPrefacez$FrameFactory.clientConnectionPreface>   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"   headersr4   streamIDpriorityKwargsfflagkvs	            r#   buildHeadersFramezFrameFactory.buildHeadersFrameA   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.
        )setr/   r0   	DataFramer3   r4   )r"   r3   r4   r9   r;   s        r#   buildDataFramezFrameFactory.buildDataFrameP   s?     $/E
SU&&x0r&   c                     t         j                  j                  d      }|r|j                  j	                  d       ||_        |S )z1
        Builds a single settings frame.
        r   ACK)r/   r0   SettingsFramer4   r5   settings)r"   rG   ackr;   s       r#   buildSettingsFramezFrameFactory.buildSettingsFrameZ   s9     **1-GGKK
r&   c                 R    t         j                  j                  |      }||_        |S )z5
        Builds a single WindowUpdate frame.
        )r/   r0   WindowUpdateFramewindow_increment)r"   r9   	incrementr;   s       r#   buildWindowUpdateFramez#FrameFactory.buildWindowUpdateFramee   s'     ..x8&r&   c                 n    t         j                  j                  d      }||_        ||_        ||_        |S )z/
        Builds a single GOAWAY frame.
        r   )r/   r0   GoAwayFrame
error_codelast_stream_idadditional_data)r"   lastStreamID	errorCodeadditionalDatar;   s        r#   buildGoAwayFramezFrameFactory.buildGoAwayFramem   s6     ((+ '*r&   c                 R    t         j                  j                  |      }||_        |S )z3
        Builds a single RST_STREAM frame.
        )r/   r0   RstStreamFramerQ   )r"   r9   rU   r;   s       r#   buildRstStreamFramez FrameFactory.buildRstStreamFramew   s&     ++H5 r&   c                 n    t         j                  j                  |      }||_        ||_        ||_        |S )z1
        Builds a single priority frame.
        )r/   r0   PriorityFrame
depends_onstream_weight	exclusive)r"   r9   weight	dependsOnr_   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.
        r.   )
r/   r0   PushPromiseFramepromised_stream_idr    r2   r3   rA   r4   r5   )r"   r9   promisedStreamIDr8   r4   r;   s         r#   buildPushPromiseFramez"FrameFactory.buildPushPromiseFrame   sX     --h7/$$W-e*	M"r&   Nr,   )F)r   r&   )r   )r   F)__name__
__module____qualname____doc__r$   r(   r+   r?   rC   rI   rN   rW   rZ   rb   rg   r*   r&   r#   r   r   1   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   )rq   )r"   r3   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)lenrq   StopIterationr/   r0   Frameparse_frame_header
parse_body
memoryview
isinstancer1   rp   decoder3   )r"   r0   lengths      r#   nextzFrameBuffer.next   s    tzz?Q/!"((..AA$**Ra.Qvtzz?VaZ'/!DJJq1v:$>?@ZZF
-
eZ--::;,,UZZT,BEJr&   N)	ri   rj   rk   rl   r$   rs   ru   r   __next__r*   r&   r#   rn   rn      s"    
  Hr&   rn   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}
    r8   r9   c              3   D   K   | ]  }j                  |         yw)r9   N)rC   ).0chunkframeFactoryr9   s     r#   	<genexpr>z%buildRequestFrames.<locals>.<genexpr>   s&      BG##EH#=s    
END_STREAM)r   appendr?   extendr4   r5   r8   r3   r   r9   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.
    )rn   rs   list)r3   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)ri   rj   rk   rl   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_requestReceivedrq   r"   argskwargss      r#   r$   zConsumerDummyHandler.__init__*  s?    d4T4V4 	##% %
r&   c                 8    | j                   j                          y)z&
        Start the data pipe.
        N)r   resumeProducingr!   s    r#   
acceptDatazConsumerDummyHandler.acceptData2  s     	$$&r&   c                 V    d| _         t        j                  j                  | g|i |S )NT)r   r   r   requestReceivedr   s      r#   r   z$ConsumerDummyHandler.requestReceived8  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readrq   r   r   )r"   
returnDatas     r#   r   zConsumerDummyHandler.process<  s>    S!\\&&(
H


:r&   N)ri   rj   rk   rl   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.acceptDataO  s$     	$$&""$r&   N)ri   rj   rk   rl   r   r*   r&   r#   r   r   G  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.processc  s"    S!mot4r&   N)ri   rj   rk   rl   r   r*   r&   r#   r   r   \  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__s  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)ri   rj   rk   rl   r$   r   r*   r&   r#   r   r   k  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)ri   rj   rk   rl   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   r+   r   makeConnectionr   dataReceived)r"   r   r8   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r,   N	stream_idr   s     r#   r   zGHTTP2ServerTests.test_basicRequest.<locals>.validate.<locals>.<genexpr>       EQq 0E   r,         r&   r   )r   valueassertEqualry   
assertTrueallr   r/   r0   r1   rB   dictr3   getResponseHeadersgetResponseDatar4   r9   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&   r,   )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  ry   r  r  r   r/   r0   r1   rB   r  r3   postResponseHeaderspostResponseDatar4   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&   r,   )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>4  r   r  r!  r"  r   r&   r   )r   r  r  ry   r  r  r   r/   r0   r1   rB   r  r3   r4   )r9   r   r$  r#  r"   r   s     r#   r  z;HTTP2ServerTests.test_postRequestNoLength.<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&*//2D9L4MNVBZ__.>?VBZ__c2OOLF2J,<,<<=r&   r,   )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.
        (   r,   r  r&   c              3   <   K   | ]  }|j                           y wr   r   r   r0   s     r#   r   z<HTTP2ServerTests.test_interleavedRequests.<locals>.<genexpr>\        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   r,   r  r&   r   )r   r  r  ry   r	  r   r/   r0   rK   r  r3   r#  r$  r  r4   )r   r   r9   r;   streamFramesbr"   	streamIDss        r#   r  z;HTTP2ServerTests.test_interleavedRequests.<locals>.validateb  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&  r+   	itertoolschainfrom_iterablezipr   r   r   r   r   DeferredListr  valuesr  )r"   REQUEST_COUNTr;   ar9   r   r   r  r  r6  r7  s   `        @@r#   test_interleavedRequestsz)HTTP2ServerTests.test_interleavedRequestsA  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  )r,   r     r   PRIORITY@   r,       rB     T)r9   r`   ra   r_   r&   c              3   <   K   | ]  }|j                           y wr   r   r1  s     r#   r   z@HTTP2ServerTests.test_sendAccordingToPriority.<locals>.<genexpr>  r2  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   )r,   r  r,   r,   r  r,   r,   r  rB  r  rB  r  rB  rB  rB  )	r   r  r  ry   r   r/   r0   rB   r	  )r   r   r;   r7  expectedOrderr6  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   r4   r5   r^   rb   insertr8  r9  r:  r+   r   r   r   r   r   r<  r   r  r=  r  )r"   r;   r?  r  r9   r   priorityFramer   r  r  r6  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.
        r,   r  r.   )r9   rf   r8   r4   r  r   N)r   r   r   r   r  r+   r   r  rg   r   r   r   r   disconnectingr   r  r  ry   r  r   r/   r0   rP   )r"   r;   r6  r?  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.
        r,   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  ry   r  r4   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  ry   r   r  rq   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>,        ?1 ?r   r,   c                    t        j                               }j                  t        |      d       j	                  t        |d   t        j                  j                               j                  |d   j                  d       y )Nr  r   r,   )
r   r  r  ry   r  r   r/   r0   rY   r	  )r9   r   r6  r"   s     r#   r  z@HTTP2ServerTests.test_abortStreamProducingData.<locals>.validate?  sf    $QWWY/F S[!,OOJvbz:3C3C3R3RSTVBZ1115r&   )r   r   r   !AbortingConsumerDummyHandlerProxyr  r   r%  r&  rA   r4   r+   r   r   r   r   rW  rX  rY  rZ  r   r  r   r  )
r"   r;   r?  r   r   r  r[  cleanupCallbackr  r6  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.
        r,      first chunk   second chunk)rU   Ns   third chunkc                    t        j                               }j                  t        |      d       j                  |d   j                  d       j                  t        |d   t        j                  j                               y Nr  r,   
r   r  r  ry   r	  r  r   r/   r0   r1   r  s     r#   r  z9HTTP2ServerTests.test_terminatedRequest.<locals>.validateu  e    $Y__%67FS[!,VAY00!4OOJvay*2B2B2O2OPQr&   )r   DummyProducerHandlerProxyr  r  r  rW  rX  rY  r   r  r   rZ   r   r  _disconnectedr   r  r"   r   r   r[  rb  r  r   s   `     @r#   test_terminatedRequestz'HTTP2ServerTests.test_terminatedRequestJ  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.
        r,   re  rf  r   rT   Nc                    t        j                               }j                  t        |      d       j                  |d   j                  d       j                  t        |d   t        j                  j                               y rh  ri  r  s     r#   r  z<HTTP2ServerTests.test_terminatedConnection.<locals>.validate  rj  r&   )r   rk  r  r  r  rW  rX  rY  r   r  r   rW   r   r  rl  r   rZ  _stillProducingr  rm  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 )NrB  c              3   :   K   | ]  }|j                   d k(    ywr  r  r   s     r#   r   zQHTTP2ServerTests.test_respondWith100Continue.<locals>.validate.<locals>.<genexpr>  r
  r  r,   )r   s   100r   r   )r   r  r  ry   r  r  r   r/   r0   r1   r3   r4   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&   r,   )r   r   r  r  r  r  r  )r"   r   r8   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.
        r,   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  r,   )r   s   400r   r   )r   r  r  ry   r  r   r/   r0   r1   r3   r4   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   rk  r  r  r  rW  rX  rY  r  !_respondToBadRequestAndDisconnectr  rl  r   r  )r"   r   r   streamr[  rb  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.
        r,   )   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 )Nrw   c              3   :   K   | ]  }|j                   d k(    ywr  r  r   s     r#   r   zQHTTP2ServerTests.test_loseH2StreamConnection.<locals>.validate.<locals>.<genexpr>  r
  r  r,   r   r   r&   r   r  r  ry   r  r  r   r/   r0   r1   r4   rB   r3   )r9   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   rk  r  r  r  rW  rX  rY  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.
        r,   TN)r   rk  r  r  r  rW  rX  rY  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.
        r,   c                 $    j                         S r   )r   )r+  r[  s    r#   <lambda>z;HTTP2ServerTests.test_handlesPullProducer.<locals>.<lambda>?  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  r4   r   r/   r0   rB   r3   r  r9   r   r;   r  r"   r   s       r#   r  z;HTTP2ServerTests.test_handlesPullProducer.<locals>.validateB  s    $Y__%67F OOLF2J,<,<<= !'*Q
8H8H8R8R*SJ  Q   )B)B)r   r   r  r  r  rW  rX  rY  _actualProducerresultr  r  )r"   r   r   r{  producerCompleter  r[  r   s   `     @@r#   test_handlesPullProducerz)HTTP2ServerTests.test_handlesPullProducer1  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.
        r,   N)r   r   r  r  r  rW  rX  rY  rZ  isSecureabortConnection)r"   r   r[  s      r#   test_isSecureWorksProperlyz+HTTP2ServerTests.test_isSecureWorksProperlyS  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.
        r,   {Gz?c                      t        j                               }j                  t        |      d       j	                  d|d   j
                  v        y )Nr  r   r   rU  )r   r   r"   r   s     r#   validateCompletezCHTTP2ServerTests.test_lateCompletionWorks.<locals>.validateCompletel  sE    $Y__%67F S[!,OOLF2J,<,<<=r&   )r   r   r  r  r  rW  rX  rY  r   	callLaterr   r  r  )r"   r   r   r[  r  r   s   `    @r#   test_lateCompletionWorksz)HTTP2ServerTests.test_lateCompletionWorks_  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}.
        r,   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  rW  rX  rY  r   writeSequencer   r  r  )r"   r   r   r{  r[  completionDeferredr  r   s   `      @r#   test_writeSequenceForChannelsz.HTTP2ServerTests.test_writeSequenceForChannelsu  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.
        rB  r,      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 )Nr,   2   r9   rM   )r   rN   r   )r   r?  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 )Nrw   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  )r9   r   r;   r  r6  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  r+   rI   h2rG   SettingCodesINITIAL_WINDOW_SIZEr   r   r  r   r   r   rW  rX  rY  r   r   
deferLaterr   r  r  )r"   r   r  r{  r  dr  r?  r6  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.
        r8   r3   r   r,   r   N)r   r   r   r   r  r+   r   r  rZ   r   r   r   r   r  r  ry   assertNotInr  )r"   r   r   r?  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)ri   rj   rk   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&   r,   )r   Deferredr   r   r   HTTPFactoryr   r  r  objectr  r  r  r  r  gatherResults)r"   r  httpFactoryr  rb  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.
        r,   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  ry   r  r  r   r  )r"   r   r   r   	deferredsr  r  rb  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}.
        r,   c                 (    j                  d       y Nz#Didn't errback, called back insteadfailignr"   s    r#   r  z;HTTP2ServerTests.test_notifyOnResetStream.<locals>.callback6      II;<r&   c                     j                  | t        j                         j                  | j                  t
        j                         y r   assertIsInstancer   Failurer  typer   ConnectionLostreasonr"   s    r#   errbackz:HTTP2ServerTests.test_notifyOnResetStream.<locals>.errback9  2    !!&'//:MM&++u';';<r&   r   r   )r   r   r   r  r  r  r   r  ry   addCallbacksrZ   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   r9   r  c                 (    j                  d       y r  r  r  s    r#   r  z=HTTP2ServerTests.test_failWithProtocolError.<locals>.callbacka  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>.errbackd  s8    !!&'//:!!&,,0K0KLr&      yo   r3   r9   )r   r   r   r  r  r  r   r   r   r  ry   r  rC   r   r   r  
r"   r   r   r   secondRequestr  r  r  r  r  s
   `         r#   test_failWithProtocolErrorz+HTTP2ServerTests.test_failWithProtocolErrorG  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&   rp  )r   r   r   r  r  r  r   r   r   r  ry   r  rW   r   r   r  r  s
   `         r#   test_failOnGoawayz"HTTP2ServerTests.test_failOnGoaways  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  ry   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}.
        r,   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  ry   r  rW  rz  )	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.
        r,   r   r   N)r
   r   r  r   r  r   r   r+   r   r   r   r  r   _maxBufferedControlFrameBytesrz  r  disconnected)r"   memoryReactorr   r9   r   r   r+   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   r,   e   N)r   r   r  r   r   r+   r   r   r   r   rI   r   r   r  r  ry   r   )r"   r   r   r   r+   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   r+   r   r   r   r
  rZ  rP  r   rI   r   r  r  )r"   r   r   r   r+   r   s         r#   2test_bufferingAutomaticFrameDataWithCircuitBreakerzCHTTP2ServerTests.test_bufferingAutomaticFrameDataWithCircuitBreaker6  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.write_  s*    %%d<T<V<,,.r&   N)ri   rj   rk   r   r*   r&   r#   AutoPausingStringTransportr  ^  s    /r&   r  Tr,   r   r  c   r  Z   N)r   r   r   r  r   r   r+   r   r   assertIsNotNone_consumerBlockedr   r  r  ry   _bufferedControlFrameBytesr   rI   r   r   )r"   r  r   r   r   r+   r   r   s           r#   0test_bufferingContinuesIfProducerIsPausedOnWritezAHTTP2ServerTests.test_bufferingContinuesIfProducerIsPausedOnWriteX  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   r+   r   r   r   r
  rC   r   r  r  )r"   r  r   r   r   r+   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)+ri   rj   rk   r  r%  r&  r  r  r#  r$  r  r  r'  r-  r@  rN  rQ  r\  rc  rn  rs  rw  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.
        rB  r,   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/   r0   rB   r3   r   s     r#   r   zMH2FlowControlTests.test_bufferExcessData.<locals>.validate.<locals>.<genexpr>  .      **Q
8H8H8R8R*S*   )==)r   r  r  r4   r   r  r  r9   r   actualResponseDatar6  r"   s      r#   r  z:H2FlowControlTests.test_bufferExcessData.<locals>.validate  sg    $QWWY/F OOLF2J,<,<<= "% * &* " T113EFr&   )r   r   r   r   r  r+   rI   r  rG   r  r  r   r   r  r   r   r   ry   r  r   rN   r  r  )
r"   r;   r?  r   r  bonusFramesr   r0   r  r6  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.
        rB  r,   
   helloworldpauser  r   resume)r1  r2  r1  r  )r1  r2  r1  r2  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   )r0  r0  r&   r  r9   r   r;   r  r6  r"   s       r#   r  zDH2FlowControlTests.test_producerBlockingUnblocking.<locals>.validate3  s}    $QWWY/F OOLF2J,<,<<= !'*Q
8H8H8R8R*SJ  Z)LMr  ) r   r   r   rk  r  r+   rI   r  rG   r  r  r   r   r  r   r   r   rW  rX  rY  r  _producerProducingr   rZ  r  r  eventsrN   unregisterProducerr   r  r  	r"   r;   r?  r   r  r{  r[  r  r6  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.
        rB  r,   r0  r1     hc                  ,    j                  j                  dd      j                                j                  j                         j                  j                  j                  ddg       j                          j                          y )Nr,   r  r  r1  r2  )
r   rN   r   r  r5  r  r  r6  r7  r   )r?  r;   r[  r"   r{  s   r#   window_openz=H2FlowControlTests.test_flowControlExact.<locals>.window_openh  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  r4  s       r#   r  z:H2FlowControlTests.test_flowControlExact.<locals>.validatet  s}    $QWWY/F OOLF2J,<,<<= !'*Q
8H8H8R8R*SJ  Z)HIr  )"r   r   r   rk  r  r+   rI   r  rG   r  r  r   r   r  r   r   r   rW  rX  rY  r  r5  r   rZ  r  r  r6  r   r  r   r  r  r   r<  )r"   r   r  r=  windowDeferr  validateDeferr?  r6  r;   r[  r{  s   `      @@@@@r#   test_flowControlExactz(H2FlowControlTests.test_flowControlExactA  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.
        rB  r,   r0  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  r4  s       r#   r  z=H2FlowControlTests.test_endingBlockedStream.<locals>.validate  s}    $QWWY/F OOLF2J,<,<<= !'*Q
8H8H8R8R*SJ  Z)BCr  )r   r   r   rk  r  r+   rI   r  rG   r  r  r   r   r  r   r   r   rW  rX  rY  r  r5  r   r7  r   finishedr   r  rN   r  r  r8  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.
        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 Nr  r   r   r&   r   r  r  ry   r  r4   r   r/   r0   rB   r3   r4  s       r#   r  z=H2FlowControlTests.test_responseWithoutBody.<locals>.validate      $QWWY/FS[!, OOLF2J,<,<<= !'*Q
8H8H8R8R*SJ     )B(B()r   r   r   rk  r  r+   r   r  r   r   r   rW  rX  rY  r  r7  r   r  rD  r  
r"   r;   r?  r   r  r{  r[  rb  r  r6  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.
        r,   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 rH  rI  r4  s       r#   r  zGH2FlowControlTests.test_windowUpdateForCompleteStream.<locals>.validate  rJ  rK  )r   r   r   rk  r  r+   r   r  r   r   r   rW  rX  rY  r  r7  r   r  rD  rN   r   r  rL  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.
        rB  r,      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   rR  r&   r  r4  s       r#   r  z;H2FlowControlTests.test_producerUnblocked.<locals>.validateZ  s    $QWWY/F OOLF2J,<,<<= !'*Q
8H8H8R8R*SJ  Z'38r  )r   r   r   rk  r  r+   rI   r  rG   r  r  r   r   r  r   r   r   rW  rX  rY  r  r5  r   r  r  r6  rN   r7  r   r  r  r8  s	   `       @r#   test_producerUnblockedz)H2FlowControlTests.test_producerUnblocked,  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.
        r,   r   rB  r  r&   c              3   <   K   | ]  }|j                           y wr   r   r   s     r#   r   zBH2FlowControlTests.test_unnecessaryWindowUpdate.<locals>.<genexpr>v  r_  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  r4   r   r  r$  r+  s      r#   r  zAH2FlowControlTests.test_unnecessaryWindowUpdate.<locals>.validate}  sg    $QWWY/F OOLF2J,<,<<= "% * &* " T224FGr&   )r   r   r   r   r  r   r%  r&  rL  rN   r+   r   r   r   r   r  r  )r"   r;   r?  r   r   r  r  r6  s   `      @r#   test_unnecessaryWindowUpdatez/H2FlowControlTests.test_unnecessaryWindowUpdateh  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.
        r,   r   rB  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   r?   r%  rN   r+   r   r   r   r   )r"   r;   r   connr   r3   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>  r_  r   r,   rB  r  r   N)r   r   r   r   r  r   r%  r&  r+   r   r   r   r   rW  r  rN   r   r   r  r  r   r/   r0   rY   )r"   r;   r6  r?  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>  r_  r   c                  j    j                  dd      }j                  |j                                y )Nr,   rB  r  )rN   r   r   )r   r`  r?  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  assertInr4   r   r   r6  r"   s     r#   r  zCH2FlowControlTests.test_windowUpdateAfterComplete.<locals>.validate  s-    $QWWY/F MM,r
(8(89r&   r,   )r   r   r   r   r  r   r%  r&  r+   r   r   r   r   r  r  )
r"   r   r   r  re  r  r  r?  r6  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   )ry   )r   r3   s     r#   r   z;H2FlowControlTests.test_dataAndRstStream.<locals>.<genexpr>  s     <$CI<s   Nr   zcontent-lengthr  r,   )r9   rU   r&   c              3   <   K   | ]  }|j                           y wr   r   r   s     r#   r   z;H2FlowControlTests.test_dataAndRstStream.<locals>.<genexpr>	  r_  r   r   )r   r   r   r   r  sumr%  r   r   rZ   r  errors
ErrorCodesINTERNAL_ERRORr+   r   r   r   r   r  r   r/   r0   rK   r	  r  r1   rB   rZ  )r"   r   r   r?  	frameData
bodyLengthr8   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.
        r,   r   r   N)r
   r   r  r   r  r   r   r+   r   r   r?   r%  r   r   r
  clearabortRequestrZ  r  r  r  )r"   r  r   r   r   r+   r9   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)ri   rj   rk   rl   r  r  r%  r&  r$  r.  r9  rA  rE  rM  rP  rT  rY  r]  ra  ri  rw  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"   r6  r?  s      r#   "test_registerProducerWithTransportz9HTTP2TransportChecking.test_registerProducerWithTransportT	  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>l	  r_  r   Tr,   c                  |   t        j                               }j                  t        |      d       j	                  t        |d   t        j                  j                               j                          j                          j                          j                          j                          S )Nr  r   )
r   r  r  ry   rZ  r   r/   r0   rB   r   )r   r   r?  r6  rb  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 rT  rU  rh  s     r#   r  zUHTTP2TransportChecking.test_pausingProducerPreventsDataSend.<locals>.validateComplete	  sD    $QWWY/F S[!,OOLF2J,<,<<=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  r  r  r?  r6  rb  s   `       @@@r#   $test_pausingProducerPreventsDataSendz;HTTP2TransportChecking.test_pausingProducerPreventsDataSend_	  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>	  r_  r   Tr  r   N)r   r   r   r   r  r   r  r+   r   r   r   r   r   r   r   r  r  ry   rZ  r   r/   r0   rB   rr  )r"   r;   r6  r?  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   r1  s     r#   r   zEHTTP2TransportChecking.test_passthroughHostAndPeer.<locals>.<genexpr>	  r2  r   r,   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  r+   r   r   r   rW  r  r  r  r  r  )r"   r   r   r   r   r   r  rb  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)ri   rj   rk   r  r  r  r  r  r*   r&   r#   r~  r~  I	  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.
        r,   r   r*   N)r   Clockr   getDelayedCallsr  ry   r  activetimefunc_sendPrioritisedDatar   kw)r"   r   r?  callscalls        r#   "test_initiallySchedulesOneDataCallz7HTTP2SchedulingTests.test_initiallySchedulesOneDataCall	  s    
 **,!''')UQ'Qx 	&A&A$:$:;B'"%r&   N)ri   rj   rk   rl   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   r\  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  ry   r  r   r/   r0   rP   rQ   rR   )r"   r3   
frameCountrU   rT   r   s         r#   assertTimedOutz HTTP2TimeoutTests.assertTimedOut9
  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  rU   rT   )_DEFAULTr   abortTimeoutr   r+   r  r   advancer  r  r  ro  rp  NO_ERRORr  rP  rZ  r  )r"   r  r   r  r   r\  r   s          r#   prepareAbortTestz"HTTP2TimeoutTests.prepareAbortTestF
  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   r+   r  r   r  r  r  rZ  rP  r  r  ro  rp  r  r  )r"   r   r  r   r\  r   preambles          r#   test_timeoutAfterInactivityz-HTTP2TimeoutTests.test_timeoutAfterInactivityl
  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   r+   r   r  rZ  rP  r  r  r  ro  rp  r  r  )r"   r   r  r   r\  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  r,   
   r   s
   some bytesr     r  N)r   r   r  r+   r   r  r   r  assertEqualsry   r   r   rZ  rP  r  r  r  ro  rp  PROTOCOL_ERROR)
r"   r   r  r   r  r   r\  r   r+  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  r,   r  N)r   r   r  r+   r   r  r   r  r  r  r  ro  rp  r  r  rP  )r"   r   r   r  r   r\  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  r,   r  N)r   r   r  r+   r   r  r   r  ry   r  connectionLostr  r  )
r"   r   r   r  r   r\  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.
           r,   Nr  r  r  rP  rZ  r  r"   r   r\  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  Nr,   )r  r  r  r  rP  rZ  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_losingConnectionWithNoAbortTimeOut1  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  rP  r  r  r   ConnectionDoner  s       r#   "test_connectionLostAfterForceClosez4HTTP2TimeoutTests.test_connectionLostAfterForceClose>  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.
        <   r,   N)r
   r   r  r  r   r   r+   r   r   r   r  rZ   r   r  r  r  )r"   r  r   r   r   r+   r   s          r#   ,test_timeOutClientThatSendsOnlyInvalidFramesz>HTTP2TimeoutTests.test_timeOutClientThatSendsOnlyInvalidFramesO  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)ri   rj   rk   rl   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  rh   )Drl   r8  zope.interfacer   r   twisted.internetr   r   r   r   twisted.internet.addressr	   twisted.internet.testingr
   r   twisted.pythonr   twisted.python.compatr   twisted.test.test_internetr   twisted.trialr   twisted.webr   twisted.web.test.test_httpr   r   r   r   r   r   r   r   r  	h2.errorsh2.exceptionsr/   r   hpack.hpackr   r   twisted.web._http2r   ImportErrorr   rn   r   r   r   r   r   rK  r   rV  r   ra  r   rk  r   NotifyingRequestFactoryProxyr   TestCaser   r$  r~  r  r  r*   r&   r#   <module>r     s  
  7 8 8 0 H " + 4 "    
* ,/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0aN  *)F*s   "F FF