+
    Dfj	                      R t ^ RIHt ^ RIt^ RIHt ^ RIHt ^ RIH	t	H
t
HtHtHtHt ^ RIHtHt ^ RIHt ^ RIHt ^ R	IHt ^ R
IHtHt ^ RIHtHt ^ RIHtH t H!t! ^ RI"H#t#H$t$ ^ RI%H&t&H't'H(t( ^ RI)H*t* ^ RI+H,t,H-t- ^ RI.H/t/ ^ RI0H1t1 ^ RI2H3t3H4t4H5t5H6t6 ^ RI7H8t8 ^ RI9H:t: ^ RI;H<t< ^ RI=H>t> ^ RI?H@t@HAtA ^ RIBHCtC ^ RIDHEtEHFtF ^ RIGHHtHHItIHJtJ ^ RIKHLtLHMtMHNtNHOtOHPtPHQtQHRtR ^ RISHTtTHUtUHVtVHWtWHXtXHYtYHZtZH[t[ ^ RI\H]t] ^ RI^H_t_ ^ R I`HataHbtbHctcHdtdHeteHftf ^ R!IgHhthHiti ]	'       d   ]Ftj]ktlM]ktj]Ftl ^ R"IHmtn ]ntmR#to^ R$IpHqtqHrtr ^ R%IsHttt ^ R&IuHvtv ^ R'IwHxtxHyty ]! ]r4       ! R( R)4      4       tz ! R+ R,]-4      t| ! R- R.4      t} ! R/ R0]F4      t~R1tR2tR3tR4tR5tR6t ! R7 R84      t ! R9 R:4      t ! R; R<4      t ! R= R>],4      t ! R? R@]F]4      t ! RA RB4      t ! RC RD4      t]! ]c4       ! RE RF4      4       t ! RG RH]F]]]4      t ! RI RJ]]h]E4      t ! RK RL]]i]E4      t]! ]o'       * RM4       ! RN RO]F]]4      4       t ! RP RQ]F4      t ! RR RS]F]4      t ! RT RU4      t ! RV RW]F]4      t ! RX RY]F]]]4      t ! RZ R[]:! ]f4      4      t ! R\ R]]4      t ! R^ R_]F]]4      t ! R` Ra]-4      t ! Rb Rc]F]4      t ! Rd Re]F]]4      t. R~Ot ! Rf Rg]j4      t ! Rh Ri]]]]l4      t ! Rj Rk]]]]l4      t ! Rl Rm]64      t ! Rn Ro4      t ! Rp Rq]4      t ! Rr Rs]F4      t]! ]o'       * RM4       ! Rt Ru]F4      4       t ! Rv Rw]h]E4      t ! Rx Ry]h]E4      t ! Rz R{]i]E4      t ! R| R}]i]E4      tR#   ]{ d	    RtmR*to EL
i ; i)zD
Tests for L{twisted.web.client.Agent} and related new client APIs.
)annotationsN)	CookieJar)BytesIO)TYPE_CHECKINGDictListOptionalSequenceTuple)SkipTestskipIfimplementer)verifyObject)Version)defertask)IPv4AddressIPv6Address)CancelledErrorDeferredsucceed)HostnameEndpointTCP4ClientEndpoint)ConnectionDoneConnectionLostConnectionRefusedError)IOpenSSLClientConnectionCreator)FactoryProtocol)Clock)deterministicResolvingReactor)AccumulatingProtocolEventLoggingObserverMemoryReactorClockStringTransport)globalLogPublisher)proxyForInterface)getDeprecationWarningString)Failure)FakeTransportIOPump)!certificatesForAuthorityAndServer)SynchronousTestCaseTestCase)clienterrorhttp_headers)HTTP11ClientProtocolPotentialDataLossRequestNotSentRequestTransmissionFailedResponseResponseFailedResponseNeverReceived)URIBrowserLikePolicyForHTTPSFileBodyProducerHostnameCachingHTTPSPolicyHTTPConnectionPoolRequestResponseDone_HTTP11ClientFactory)SchemeNotSupported)Headers)UNKNOWN_LENGTHIAgentIAgentEndpointFactoryIBodyProducerIPolicyForHTTPS	IResponse)MethodInjectionTestsMixinURIInjectionTestsMixin)sslT)ClientTLSOptionsIOpenSSLTrustRoot)optionsForClientTLS)tls)TLSMemoryBIOFactoryTLSMemoryBIOProtocolc                  $    ] tR t^htRtRtR tRtR# )CustomOpenSSLTrustRootFNc                	     R V n         Wn        R# )TNcalledcontext)selfrW   s   &&=/usr/lib/python3/dist-packages/twisted/web/test/test_agent.py_addCACertsToContext+CustomOpenSSLTrustRoot._addCACertsToContextm   s    DK"L    rU   )__name__
__module____qualname____firstlineno__rV   rW   rZ   __static_attributes__ r\   rY   rS   rS   h   s    	#r\   rS   Fc                  ,    ] tR t^rtRtR R ltR tRtR# )StubHTTPProtocola:  
A protocol like L{HTTP11ClientProtocol} but which does not actually know
HTTP/1.1 and only collects requests in a list.

@ivar requests: A C{list} of two-tuples.  Each time a request is made, a
    tuple consisting of the request and the L{Deferred} returned from the
    request method is appended to this list.
c                   V ^8  d   QhRR/#    returnNonerb   )formats   "rY   __annotate__StubHTTPProtocol.__annotate__|   s     ! !$ !r\   c                	"    . V n         R V n        R# )	QUIESCENTNrequestsstaterX   s   &rY   __init__StubHTTPProtocol.__init__|   s    CE 
r\   c                R    \        4       pV P                  P                  W34       V# )zj
Capture the given request for later inspection.

@return: A L{Deferred} which this code will never fire.
)r   rp   append)rX   requestresults   && rY   rw   StubHTTPProtocol.request   s%     g./r\   ro   N)r]   r^   r_   r`   __doc__rs   rw   ra   rb   r\   rY   rd   rd   r   s    !r\   rd   c                  "    ] tR t^tR tR tRtR# )FileConsumerc                	    Wn         R # N
outputFile)rX   r   s   &&rY   rs   FileConsumer.__init__   s    $r\   c                	<    V P                   P                  V4       R # r~   )r   write)rX   bytess   &&rY   r   FileConsumer.write   s    e$r\   r   N)r]   r^   r_   r`   rs   r   ra   rb   r\   rY   r|   r|      s    %%r\   r|   c                  n    ] tR t^tRtR tR tR tR tR t	R t
R tR	 tR
 tR tR tR tR tR tRtR# )FileBodyProducerTestsze
Tests for the L{FileBodyProducer} which reads bytes from a file and writes
them to an L{IConsumer}.
c                    R # )a<  
This method can be used as the C{terminationPredicateFactory} for a
L{Cooperator}.  It returns a predicate which immediately returns
C{False}, indicating that no more work should be done this iteration.
This has the result of only allowing one iteration of a cooperative
task to be run per L{Cooperator} iteration.
c                     R # )Trb   rb   r\   rY   <lambda>4FileBodyProducerTests._termination.<locals>.<lambda>   s    tr\   rb   rr   s   &rY   _termination"FileBodyProducerTests._termination   s
     r\   c                    . V n         \        P                  ! V P                  V P                   P                  4      V n        R# )zt
Create a L{Cooperator} hooked up to an easily controlled, deterministic
scheduler to use with L{FileBodyProducer}.
N)
_scheduledr   
Cooperatorr   rv   
cooperatorrr   s   &rY   setUpFileBodyProducerTests.setUp   s-    
 //$*;*;T__=S=STr\   c           
     h    V P                  \        \        \        \	        R4      4      4      4       R# )z9
L{FileBodyProducer} instances provide L{IBodyProducer}.
r\   N)
assertTruer   rF   r;   r   rr   s   &rY   test_interface$FileBodyProducerTests.test_interface   s!     	]4DWS\4RSTr\   c                     ! R R4      p ! R R4      p\        V! 4       4      pV P                  \        VP                  4       \        V! 4       4      pV P                  \        VP                  4       R# )z
If the L{FileBodyProducer} is constructed with a file-like object
without either a C{seek} or C{tell} method, its C{length} attribute is
set to C{UNKNOWN_LENGTH}.
c                      ] tR t^tR tRtR# )9FileBodyProducerTests.test_unknownLength.<locals>.HasSeekc                	    R # r~   rb   )rX   offsetwhences   &&&rY   seek>FileBodyProducerTests.test_unknownLength.<locals>.HasSeek.seek       r\   rb   N)r]   r^   r_   r`   r   ra   rb   r\   rY   HasSeekr          r\   r   c                      ] tR t^tR tRtR# )9FileBodyProducerTests.test_unknownLength.<locals>.HasTellc                	    R # r~   rb   rr   s   &rY   tell>FileBodyProducerTests.test_unknownLength.<locals>.HasTell.tell   r   r\   rb   N)r]   r^   r_   r`   r   ra   rb   r\   rY   HasTellr      r   r\   r   N)r;   assertEqualrC   length)rX   r   r   producers   &   rY   test_unknownLength(FileBodyProducerTests.test_unknownLength   sX    	 		 	 $GI.9#GI.9r\   c                    Rp\        V4      pVP                  ^4       \        V4      pV P                  \	        V4      ^,
          VP
                  4       V P                  VP                  4       ^4       R# )z
If the L{FileBodyProducer} is constructed with a file-like object with
both C{seek} and C{tell} methods, its C{length} attribute is set to the
size of the file as determined by those methods.
s   here are some bytesN)r   r   r;   r   lenr   r   )rX   
inputBytes	inputFiler   s   &   rY   test_knownLength&FileBodyProducerTests.test_knownLength   s]     ,
J'	q#I.Z1,hoo>)1-r\   c                    \        \        R4      4      pV P                  \        P                  VP
                  4       R# )z_
If no L{Cooperator} instance is passed to L{FileBodyProducer}, the
global cooperator is used.
r\   N)r;   r   r   r   	cooperate
_cooperate)rX   r   s   & rY   test_defaultCooperator,FileBodyProducerTests.test_defaultCooperator   s,    
 $GCL1)<)<=r\   c                   Rp^p\        4       p\        V4      p\        \        V4      V P                  V4      pVP	                  V4      p\        \        V4      V,          ^,           4       F#  pV P                  P                  ^ 4      ! 4        K%  	  V P                  . V P                  4       V P                  WP                  4       4       V P                  RV P                  V4      4       R# )z
L{FileBodyProducer.startProducing} starts writing bytes from the input
file to the given L{IConsumer} and returns a L{Deferred} which fires
when they have all been written.
   hello, worldN)r   r|   r;   r   startProducingranger   r   popr   getvaluesuccessResultOf)rX   expectedResultreadSizeoutputconsumerr   completeis   &       rY   test_startProducing)FileBodyProducerTests.test_startProducing   s     )'#GN$;T__hW**84s>*h6:;AOO"$ <T__-):;t33H=>r\   c                `   ^pRp\        V4      p\        W0P                  V4      p\        \        4       4      pVP	                  V4       \        \        V4      V,          ^,           4       F#  pV P                  P                  ^ 4      ! 4        K%  	  V P                  VP                  4       R# )zg
When L{FileBodyProducer} reaches end-of-file on the input file given to
it, the input file is closed.
s   some friendly bytesN)r   r;   r   r|   r   r   r   r   r   r   closed)rX   r   r   r   r   r   r   s   &      rY   test_inputClosedAtEOF+FileBodyProducerTests.test_inputClosedAtEOF   s    
 +
J'	#II	*)s:(2Q67AOO"$ 8	(()r\   c                    ! R R4      p\        V! 4       V P                  4      pVP                  \        \	        4       4      4      pV P
                  P                  ^ 4      ! 4        V P                  V4      P                  \        4       R# )z
If a read from the input file fails while producing bytes to the
consumer, the L{Deferred} returned by
L{FileBodyProducer.startProducing} fires with a L{Failure} wrapping
that exception.
c                      ] tR tRtR tRtR# )GFileBodyProducerTests.test_failedReadWhileProducing.<locals>.BrokenFilei  c                	    \        R 4      h)zSimulated bad thing)OSError)rX   counts   &&rY   readLFileBodyProducerTests.test_failedReadWhileProducing.<locals>.BrokenFile.read  s    344r\   rb   N)r]   r^   r_   r`   r   ra   rb   r\   rY   
BrokenFiler     s    5r\   r   N)
r;   r   r   r|   r   r   r   failureResultOftrapIOError)rX   r   r   r   s   &   rY   test_failedReadWhileProducing3FileBodyProducerTests.test_failedReadWhileProducing   se    	5 	5 $JL$//B**<	+BCA X&++G4r\   c                   Rp^p\        4       p\        V4      p\        V4      p\        WPP                  V4      pVP	                  V4      pVP                  4        V P                  VP                  4       V P                  P                  ^ 4      ! 4        V P                  RVP                  4       4       V P                  V4       R# )z
When the L{Deferred} returned by L{FileBodyProducer.startProducing} is
cancelled, the input file is closed and the task is stopped.
r   r\   N)r   r|   r;   r   r   cancelr   r   r   r   r   r   assertNoResultrX   r   r   r   r   r   r   r   s   &       rY   test_cancelWhileProducing/FileBodyProducerTests.test_cancelWhileProducing  s    
 )'N+	#II**84	(()A foo/0H%r\   c                   Rp^p\        4       p\        V4      p\        V4      p\        WPP                  V4      pVP	                  V4      pVP                  4        V P                  VP                  4       V P                  P                  ^ 4      ! 4        V P                  RVP                  4       4       V P                  V4       R# )z
L{FileBodyProducer.stopProducing} stops the underlying L{IPullProducer}
and the cooperative task responsible for calling C{resumeProducing} and
closes the input file but does not cause the L{Deferred} returned by
C{startProducing} to fire.
r   r\   Nr   r|   r;   r   r   stopProducingr   r   r   r   r   r   r   r   s   &       rY   test_stopProducing(FileBodyProducerTests.test_stopProducing  s     )'N+	#II**84 	(()A foo/0H%r\   c                0   Rp^p\        4       p\        V4      p\        \        V4      V P                  V4      pVP	                  V4      pV P
                  P                  ^ 4      ! 4        V P                  VP                  4       VR,          4       VP                  4        V P
                  P                  ^ 4      ! 4        V P                  VP                  4       VR,          4       V P                  . V P
                  4       V P                  V4       R# )zv
L{FileBodyProducer.pauseProducing} temporarily suspends writing bytes
from the input file to the given L{IConsumer}.
r   N   NN)r   r|   r;   r   r   r   r   r   r   pauseProducingr   )rX   r   r   r   r   r   r   s   &      rY   test_pauseProducing)FileBodyProducerTests.test_pauseProducing2  s    
 )'#GN$;T__hW**84A *N2,>?! 	A  	*N2,>?T__-H%r\   c                   Rp^p\        4       p\        V4      p\        \        V4      V P                  V4      pVP	                  V4       V P
                  P                  ^ 4      ! 4        V P                  VRV VP                  4       4       VP                  4        VP                  4        V P
                  P                  ^ 4      ! 4        V P                  VRV^,           VP                  4       4       R# )z
L{FileBodyProducer.resumeProducing} re-commences writing bytes from the
input file to the given L{IConsumer} after it was previously paused
with L{FileBodyProducer.pauseProducing}.
r   N)r   r|   r;   r   r   r   r   r   r   r   resumeProducing)rX   r   r   r   r   r   s   &     rY   test_resumeProducing*FileBodyProducerTests.test_resumeProducingL  s     )'#GN$;T__hW)A 	2FOO4EF!  "A (Q,79JKr\   c                   Rp^p\        4       p\        V4      p\        V4      p\        WPP                  V4      pVP	                  V4      pVP                  4        VP                  4        V P                  VP                  4       V P                  P                  ^ 4      ! 4        V P                  RVP                  4       4       V P                  V4       R# )z^
L{FileBodyProducer.stopProducing} can be called more than once without
raising an exception.
s   testr\   Nr   r   s   &       rY   test_multipleStop'FileBodyProducerTests.test_multipleStop_  s    
 !'N+	#II**84  	(()A foo/0H%r\   )r   r   N)r]   r^   r_   r`   rz   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ra   rb   r\   rY   r   r      sP    
UU:(.>?$*5"&$&(&4L&&r\   r   	127.0.0.7::7z	127.0.0.8z	127.0.0.9z
127.0.0.10z
127.0.0.11c                  @    ] tR tRtRtR t ! R R4      tR tR tRt	R	# )
FakeReactorAndConnectMixini{  z
A test mixin providing a testable C{Reactor} class and a dummy C{connect}
method which allows instances to pretend to be endpoints.
c                    \        4       p\        VR\        .R\        .R\        .R\
        .R\        .R\        .RR.RR./R	7      pVP                  Vn        VP                  Vn	        V# )
a.  
Create a L{MemoryReactorClock} and give it some hostnames it can
resolve.

@return: a L{MemoryReactorClock}-like object with a slightly limited
    interface (only C{advance} and C{tcpClients} in addition to its
    formally-declared reactor interfaces), which can resolve a fixed
    set of domains.
example.comzipv6.example.comzexample.netzexample.orgfoozfoo.comr   r   )hostMap)
r$   r!   EXAMPLE_COM_IPEXAMPLE_COM_V6_IPEXAMPLE_NET_IPEXAMPLE_ORG_IPFOO_LOCAL_IP
FOO_COM_IP
tcpClientsadvance)rX   mrcdrrs   &  rY   createReactor(FakeReactorAndConnectMixin.createReactor  sx     !"+/"%6$7//~J<k]w	
  kk
r\   c                  &    ] tR tRtRtR tR tRtR# )'FakeReactorAndConnectMixin.StubEndpointi  z
Endpoint that wraps existing endpoint, substitutes StubHTTPProtocol, and
resulting protocol instances are attached to the given test case.
c                	   a  VS n         VS n        R  p\        V\        S P                   4      4      S n        \        4       S n        V 3R lS P                  n        R# )c                     R# )zthis function does nothingNrb   rb   r\   rY   nothingAFakeReactorAndConnectMixin.StubEndpoint.__init__.<locals>.nothing  s    r\   c                   < SP                   # r~   protocol)addrrX   s   &rY   r   BFakeReactorAndConnectMixin.StubEndpoint.__init__.<locals>.<lambda>  s	    dmmr\   N)endpointtestCaser@   reprfactoryrd   r  buildProtocol)rX   r  r  r
  s   f&& rY   rs   0FakeReactorAndConnectMixin.StubEndpoint.__init__  sE    $DM$DM1 0dmm9LMDL,.DM)CDLL&r\   c                	    V P                   V P                  n         V P                  P                  V P                  4       \        V P                   4      # r~   )r  r  r  connectr  r   )rX   ignoredFactorys   &&rY   r  /FakeReactorAndConnectMixin.StubEndpoint.connect  s7    %)]]DMM"MM!!$,,/4==))r\   )r  r  r  r  N)r]   r^   r_   r`   rz   rs   r  ra   rb   r\   rY   StubEndpointr    s    	
		D	*r\   r  c                f   a a \         P                  ! V4      pVP                  oVV 3R lVn        V# )zr
Return an Agent suitable for use in tests that wrap the Agent and want
both a fake reactor and StubHTTPProtocol.
c                 0   < SP                  S! V !  S4      # r~   )r  )args_oldGetEndpointrX   s   *rY   r   EFakeReactorAndConnectMixin.buildAgentForWrapperTest.<locals>.<lambda>  s    ot4d;r\   )r/   Agent_getEndpoint)rX   reactoragentr  s   f& @rY   buildAgentForWrapperTest3FakeReactorAndConnectMixin.buildAgentForWrapperTest  s/    
 W%,,
 r\   c                Z    \        4       pVP                  R4       W n        \        V4      # )z~
Fake implementation of an endpoint which synchronously
succeeds with an instance of L{StubHTTPProtocol} for ease of
testing.
N)rd   makeConnectionr  r   rX   r  r  s   && rY   r  "FakeReactorAndConnectMixin.connect  s*     $%% x  r\   r  N)
r]   r^   r_   r`   rz   r  r  r%  r  ra   rb   r\   rY   r   r   {  s     
>* *,
	!r\   r   c                       ] tR tRtRtR tRtR# )DummyEndpointi  z)
An endpoint that uses a fake transport.
c                	l    VP                  R 4      pVP                  \        4       4       \        V4      # r~   r  r(  r%   r   r)  s   && rY   r  DummyEndpoint.connect  s.    ((. 12x  r\   rb   Nr]   r^   r_   r`   rz   r  ra   rb   r\   rY   r,  r,    s    !r\   r,  c                       ] tR tRtRtR tRtR# )BadEndpointi  z'
An endpoint that shouldn't be called.
c                	    \        R 4      h)z(This endpoint should not have been used.)RuntimeError)rX   r  s   &&rY   r  BadEndpoint.connect  s    EFFr\   rb   Nr0  rb   r\   rY   r2  r2    s    Gr\   r2  c                  $    ] tR tRtRtR t]tRtR# )DummyFactoryi  z'
Create C{StubHTTPProtocol} instances.
c                	    R # r~   rb   )rX   quiescentCallbackmetadatas   &&&rY   rs   DummyFactory.__init__  s    r\   rb   N)	r]   r^   r_   r`   rz   rs   rd   r  ra   rb   r\   rY   r7  r7    s      Hr\   r7  c                  b    ] tR tRtRtR tR tR tR tR t	R t
R	 tR
 tR tR tR tR tRtR# )HTTPConnectionPoolTestsi  z,
Tests for the L{HTTPConnectionPool} class.
c                	    V P                  4       V n        \        V P                  4      V n        \        V P                  n        R V P                  n        R# )FN)r  fakeReactorr=   poolr7  _factoryretryAutomaticallyrr   s   &rY   r   HTTPConnectionPoolTests.setUp  s=    --/&t'7'78	)		',		$r\   c                   a  S P                  S P                  P                  / 4       V 3R lpRpS P                  P                  V\	        4       4      pVP                  V4      # )zc
If there are no cached connections,
L{HTTPConnectionPool.getConnection} returns a new connection.
c                   < SP                  V \        4       SP                  V SP                  P                  P                  4       4       R # r~   )assertIsInstancerd   assertNotInr@  _connectionsvalues)connrX   s   &rY   gotConnectionMHTTPConnectionPoolTests.test_getReturnsNewIfCacheEmpty.<locals>.gotConnection   s7    !!$(89T499#9#9#@#@#BCr\   /  )r   r@  rH  getConnectionr,  addCallback)rX   rK  
unknownKeyds   f   rY   test_getReturnsNewIfCacheEmpty6HTTPConnectionPoolTests.test_getReturnsNewIfCacheEmpty  sS    
 	//4	D
 
II##J@}}]++r\   c                p   \        4       pVP                  \        4       4       V P                  P	                  RV4       V P                  VP                  P                  R4       V P                  WP                  P                  R,          4       V P                  P                  ^4       V P                  VP                  P                  R4       V P                  WP                  P                  R,          4       V P                  WP                  P                  4       V P                  P                  R4       V P                  VP                  P                  R4       V P                  WP                  P                  R,          4       V P                  WP                  P                  4       R# )z
If a connection is put back to the pool, a 240-sec timeout is started.

When the timeout hits, the connection is closed and removed from the
pool.
Fg?TNhttp   example.comP   )rd   r(  r%   r@  _putConnectionr   	transportdisconnectingassertInrH  r?  r  	_timeoutsrG  rX   r  s   & rY   test_putStartsTimeout-HTTPConnectionPoolTests.test_putStartsTimeout	  s8    $% 12		  !=xH 	++995Ah		 6 67S TU 	  %++995Ah		 6 67S TUh		 3 34 	  %++994@99#9#9:V#WX99#6#67r\   c                   V P                   p\        4       \        4       .pV F.  pVP                  \        4       4       VP	                  RV4       K0  	  V P                  VP                  R,          V4       VP                  P                  4       p\        4       pVP                  \        4       4       VP	                  RV4       VP                  R,          pV P                  \        V4      ^4       V P                  Wb^,          V.4       T P                  V Uu. uF  q3P                  P                  NK  	  upRR.4       V P                  V^ ,          P                  P                  R4       V P                  WB^ ,          ,          P                  4       V P                  V^ ,          VP                  4       R# u upi )z
If an idle connection is put back in the cache and the max number of
persistent connections has been exceeded, one of the connections is
closed and removed from the cache.
FTNrU  )r@  rd   r(  r%   rY  r   rH  r]  copyr   rZ  r[  r   	cancelledrG  )rX   r@  
origCachedptimeoutsnewProtocol	newCacheds   &      rY   test_putExceedsMaxPersistent4HTTPConnectionPoolTests.test_putExceedsMaxPersistent%  si    yy '(*:*<=
A_./ <a@  	**+GH*U>>&&( '(""?#458+F %%&BC	Y+]K$@AYGY++33YG%QVXA00>>EA/99:A7 Hs   G c                  a  V 3R lp. pVP                  V! RR^P4      4       VP                  V! RR^P4      4       V! RRR4       V! RR^P4       S P                  S P                  P                  R,          V4       S P                  \	        S P                  P                  R	,          4      ^4       S P                  \	        S P                  P                  R
,          4      ^4       R# )zq
C{maxPersistentPerHost} is enforced per C{(scheme, host, port)}:
different keys have different max connections.
c                   < \        4       pVP                  \        4       4       SP                  P	                  WV3V4       V# r~   )rd   r(  r%   r@  rY  )schemehostportre  rX   s   &&& rY   addProtocolFHTTPConnectionPoolTests.test_maxPersistentPerHost.<locals>.addProtocolI  s:     "A_./II$$fD%91=Hr\   rV  rW  https     www2.example.comNrU  )rr  rW  rs  )rV  rt  rX  )rv   r   r@  rH  r   )rX   rp  
persistents   f  rY   test_maxPersistentPerHost1HTTPConnectionPoolTests.test_maxPersistentPerHostC  s    	 
+fnbAB+fnbABG^S1F/4II""#?@*	
 	TYY334RSTVWX		&&'HIJA	
r\   c                   a a \        4       oSP                  \        4       4       S P                  P	                  RS4       VV 3R lpS P                  P                  R\        4       4      P                  V4      # )z
Getting an address which has a cached connection returns the cached
connection, removes it from the cache and cancels its timeout.
c                T  < SP                  SV 4       SP                  V SP                  P                  R,          4       SP                  P                  ^4       SP                  V P                  P                  R4       SP                  V SP                  P                  4       R# )rV  FNrU  )
assertIdenticalrG  r@  rH  r?  r  r   rZ  r[  r]  )rJ  r  rX   s   &rY   rK  GHTTPConnectionPoolTests.test_getCachedConnection.<locals>.gotConnectiong  s{      40T499#9#9:V#WX$$S)T^^995AT499#6#67r\   rU  )rd   r(  r%   r@  rY  rN  r2  rO  )rX   rK  r  s   f @rY   test_getCachedConnection0HTTPConnectionPoolTests.test_getCachedConnection]  se     $% 12		  !=xH	8 yy&&(M
 +m
$	%r\   c                  a aa \        4       oSP                  \        4       4       RoS P                  P	                  SS4       VVV 3R lpS P                  P                  S\        4       4      pVP                  V4      # )zB
The pool's C{_newConnection} method constructs a new connection.
rM  c                   < SP                  SV 4       SP                  SSP                  P                  S,          4       SP	                  V SP                  P                  P                  4       4       R # r~   )assertNotIdenticalr\  r@  rH  rG  rI  )newConnectionkeyr  rX   s   &rY   rK  AHTTPConnectionPoolTests.test_newConnection.<locals>.gotConnection  sS    ##Hm<MM(DII$:$:3$?@]DII,B,B,I,I,KLr\   )rd   r(  r%   r@  rY  _newConnectionr,  rO  )rX   rK  rQ  r  r  s   f  @@rY   test_newConnection*HTTPConnectionPoolTests.test_newConnectionu  sf    
 $% 12		  h/	M II$$S-/:}}]++r\   c                N   V P                   pRp\        4       \        4       .pV F-  pVP                  \        4       4       VP	                  W$4       K/  	  V P                  VP                  V,          V4       RV^ ,          n        . pV P                   P                  V\        4       4      P                  VP                  4       V P                  V^ ,          V^,          4       V P                  VP                  V,          . 4       V P                  VP                  / 4       R# )zc
When getting connections out of the cache, disconnected connections
are removed and not returned.
DISCONNECTEDNrU  )r@  rd   r(  r%   rY  r   rH  rq   rN  r2  rO  rv   rz  r]  )rX   r@  r  rd  re  rx   s   &     rY   test_getSkipsDisconnected1HTTPConnectionPoolTests.test_getSkipsDisconnected  s    
 yy* '(*:*<=
A_./'  	**3/< -
1 		[]3??NVAY
16 	**3/4,r\   c                <   \        4       pV P                  VP                  R4       \        P                  ! V \
        4      pRVn        V P                  P                  RV4       V P                  ^\        V4      4       V^ ,          pVR,          pV P                  VP                  \        4       V P                  VP                  4       R4       V P                  RV P                  P                  P!                  R4      4       V P#                  \        4       R# )zM
If a non-quiescent connection is put back in the cache, an error is
logged.
rn   NOTQUIESCENTlog_failurez5BUG: Non-quiescent protocol added to connection pool.NrU  )rd   r   rq   r#   createWithCleanupr&   r@  rY  assertEqualsr   rF  valuer4  getErrorMessagerz  rH  getflushLoggedErrors)rX   r  logObservereventfs   &    rY   test_putNotQuiescent,HTTPConnectionPoolTests.test_putNotQuiescent  s    
 $%5*<<TCUV'		  !=xH!S-.A- agg|4!X	
 	$))((,,-IJ	
 	|,r\   c                    ! R R4      p\        V P                  R4      pRVn        . pRpVP                  WA! 4       4      P	                  VP
                  4       V^ ,          pV P                  V\        4       RVn        VP                  V4       . pVP                  WA! 4       4      P	                  VP
                  4       V P                  V^ ,          V4       R# )a  
When L{HTTPConnectionPool.getConnection} connects, it returns a
C{Deferred} that fires with an instance of L{HTTP11ClientProtocol}
that has the correct quiescent callback attached. When this callback
is called the protocol is returned to the cache correctly, using the
right key.
c                      ] tR tRtR tRtR# )MHTTPConnectionPoolTests.test_getUsesQuiescentCallback.<locals>.StringEndpointi  c                	l    VP                  R 4      pVP                  \        4       4       \        V4      # r~   r.  )rX   r  re  s   && rY   r  UHTTPConnectionPoolTests.test_getUsesQuiescentCallback.<locals>.StringEndpoint.connect  s-    ))$/  !23qz!r\   rb   Nr]   r^   r_   r`   r  ra   rb   r\   rY   StringEndpointr    s    "r\   r  TFza keyrn   N)r=   r?  rB  rN  rO  rv   rF  r2   _state_quiescentCallbackrz  )rX   r  r@  rx   r  r  result2s   &      rY   test_getUsesQuiescentCallback5HTTPConnectionPoolTests.test_getUsesQuiescentCallback  s    	" 	" "$"2"2D9"'3 01==fmmL!9h(<= &##H-
 3 01==gnnMWQZ2r\   c                4  a a . oVV 3R lpV! RR^P4       V! RR^P4       S P                   P                  4       pS F)  pS P                  VP                  P                  R4       K+  	  S P                  S P                   P
                  / 4       S P                  P                  4        F  pS P                  VP                  R4       K!  	  S P                  S P                   P                  / 4       . pVP                  VP                  4       S P                  V. 4       S^ ,          P                  \        \        4       4      4       S P                  V. 4       S^,          P                  \        \        4       4      4       S P                  VR.4       R# )z
L{HTTPConnectionPool.closeCachedConnections} closes all cached
connections and removes them from the cache. It returns a Deferred
that fires when they have all lost their connections.
c                   < \        4       pVP                  \        4       4       SP                  P	                  WV3V4       SP                  V4       R # r~   )r2   r(  r%   r@  rY  rv   )rm  rn  ro  re  ru  rX   s   &&& rY   rp  HHTTPConnectionPoolTests.test_closeCachedConnections.<locals>.addProtocol  sC    $&A_./II$$fD%91=a r\   rV  rW  rt  TN)r@  closeCachedConnectionsr   rZ  r[  rH  r?  getDelayedCallsrc  r]  rO  rv   connectionLostr)   r   )rX   rp  doneDeferredre  dcrx   ru  s   f     @rY   test_closeCachedConnections3HTTPConnectionPoolTests.test_closeCachedConnections  sB    
	! 	FNB/F/4yy779 AQ[[66= //4""224BR\\40 5,,b1   /$1$$W^-=%>?$1$$W^-=%>?$(r\   c                B  a V P                  V P                  P                  / 4       \        4       o ! V3R lR4      pV P                  P	                  RV! 4       4      pVP                  4        V P                  V P                  S4      P                  \        4       R# )z
Cancelling the C{Deferred} returned from
L{HTTPConnectionPool.getConnection} cancels the C{Deferred} returned
by opening a new connection with the given endpoint.
c                  $   < ] tR tRtV 3R ltRtR# )XHTTPConnectionPoolTests.test_cancelGetConnectionCancelsEndpointConnect.<locals>.Endpointi  c                	   < S# r~   rb   )rX   r  connectionResults   &&rY   r  `HTTPConnectionPoolTests.test_cancelGetConnectionCancelsEndpointConnect.<locals>.Endpoint.connect  s	    ''r\   rb   Nr  )r  s   rY   Endpointr    s    ( (r\   r  i90  N)	r   r@  rH  r   rN  r   r   typer   )rX   r  rQ  r  s   &  @rY   .test_cancelGetConnectionCancelsEndpointConnectFHTTPConnectionPoolTests.test_cancelGetConnectionCancelsEndpointConnect  sv     	//4#:	( 	( II##E8:6	
--.>?DDnUr\   )r?  r@  N)r]   r^   r_   r`   rz   r   rR  r_  ri  rv  r|  r  r  r  r  r  r  ra   rb   r\   rY   r=  r=    sF    -, 888<
4%0,*-8-6!3F")HVr\   r=  c                       ] tR tRtRtR tRtR# )AgentTestsMixini  z)
Tests for any L{IAgent} implementation.
c                `    V P                  \        \        V P                  4       4      4       R# )z&
The agent object provides L{IAgent}.
N)r   r   rD   	makeAgentrr   s   &rY   r   AgentTestsMixin.test_interface  s     	VT^^-=>?r\   rb   N)r]   r^   r_   r`   rz   r   ra   rb   r\   rY   r  r    s    @r\   r  c                  X    ] tR tRtRtR tR tR tR tR ]	P                  R3R	 ltR
tR# )IntegrationTestingMixini&  z?
Transport-to-Agent integration tests for both HTTP and HTTPS.
c                <    V P                  R\        \        4       R# )z
L{Agent} works over IPv4.
rW  N)integrationTestr   r   rr   s   &rY   test_integrationTestIPv40IntegrationTestingMixin.test_integrationTestIPv4+  s     	^^[Ir\   c                4    V P                  RR\        4       R# )z<
L{Agent} works over IPv4 when hostname is an IPv4 address.
s	   127.0.0.7r   N)r  r   rr   s   &rY   test_integrationTestIPv4Address7IntegrationTestingMixin.test_integrationTestIPv4Address1  s     	\;Dr\   c                <    V P                  R\        \        4       R# )z
L{Agent} works over IPv6.
s   ipv6.example.comN)r  r   r   rr   s   &rY   test_integrationTestIPv60IntegrationTestingMixin.test_integrationTestIPv67  s     	02C[Qr\   c                4    V P                  RR\        4       R# )z<
L{Agent} works over IPv6 when hostname is an IPv6 address.
s   [::7]r   N)r  r   rr   s   &rY   test_integrationTestIPv6Address7IntegrationTestingMixin.test_integrationTestIPv6Address=  s     	Xuk:r\   c                	    V # r~   rb   )server_s   &&rY   r    IntegrationTestingMixin.<lambda>H  s    r\      httpc           	     "  aa V P                  4       o\        '       d   V P                  \        RV3R l4       V! S4      pVP	                  RVR,           V,           R,           4      pSP
                  ^ ,          w  rrpV P                  W4       V! RW4      pVP                  V4      p\        VRVR7      pVP                  V4       \        P                  V3R	 l4       oR
Sn        R
Sn        V! SS4      P                  R
4      p\        VR4      pVP                  V4       \        VVVVRSR7      pVP                  4        V P!                  V4       SP                  P"                  P%                  R4      pV P'                  V^ ,          P)                  R4      V^ ,          4       \+        VR,           Uu. uF  pV'       g   K  VP%                  R^4      NK!  	  up4      pV P                  VR,          V4       V P!                  V4       SP                  P,                  P/                  R4       VP                  4        V P1                  V4      pV P3                  VP4                  P7                  R4      ^ ,          R4       R
# u upi )a  
L{Agent} will make a TCP connection, send an HTTP request, and return a
L{Deferred} that fires when the response has been received.

@param hostName: The hostname to interpolate into the URL to be
    requested.
@type hostName: L{bytes}

@param expectedAddress: The expected address string.
@type expectedAddress: L{bytes}

@param addressType: The class to construct an address out of.
@type addressType: L{type}

@param serverWrapper: A callable that takes a protocol factory and a
    ``Clock`` and returns a protocol factory; used to wrap the server /
    responder side in a TLS server.
@type serverWrapper:
    serverWrapper(L{twisted.internet.interfaces.IProtocolFactory}) ->
    L{twisted.internet.interfaces.IProtocolFactory}

@param createAgent: A callable that takes a reactor and produces an
    L{IAgent}; used to construct an agent with an appropriate trust
    root for TLS.
@type createAgent: createAgent(reactor) -> L{IAgent}

@param scheme: The scheme to test, C{http} or C{https}
@type scheme: L{bytes}
_get_default_clockc                    < S # r~   rb   r#  s   rY   r   9IntegrationTestingMixin.integrationTest.<locals>.<lambda>m  s    'r\      GET   ://   /TCPF)peerAddressc                 *   < \        4       p V Sn        V # r~   )r"   currentProtocol)apaccumulators    rY   r  <IntegrationTestingMixin.integrationTest.<locals>.accumulatorw  s    %'B*,K'Ir\   NT)clocks   
s
   GET / HTTP   NNs   :    HostsL   HTTP/1.1 200 OK
X-An-Header: an-value

Content-length: 12

hello world!s   x-an-headers   an-value)r  
sslPresentpatchrO   rw   r   r   r  r*   r(  r   forProtocolr  protocolConnectionMader+   flushr   datasplitr   
startswithdictrZ  r   r   r  headersgetRawHeaders)rX   hostNameexpectedAddressaddressTypeserverWrappercreateAgentrm  r$  deferredrn  ro  r  timeoutbindr  clientProtocolclientTransportwrapperserverTransportpumplinesliner  responser  r#  s   &&&&&&&                 @@rY   r  'IntegrationTestingMixin.integrationTestC  s7   L $$&: JJs0/BG$==&8)Cd)JK-4-?-?-B*Gd/!%4 ..{;';W%%o6				 
	
 '+#-1*W5CCDI'6/
 	

H%++0066w?a++M:E!HErKd,

5!,KL)84H%##--33	
 	

''1**>:1={	
 Ls   <
JJrb   N)r]   r^   r_   r`   rz   r  r  r  r  r/   r!  r  ra   rb   r\   rY   r  r  &  s9    JER; /LLX
 X
r\   r  c                       ] tR tRtRtR tRtR# )StubEndpointFactoryi  z5
A stub L{IAgentEndpointFactory} for use in testing.
c                H    VP                   VP                  VP                  3# )z
Testing implementation.

@param uri: A L{URI}.

@return: C{(scheme, host, port)} of passed in URI; violation of
    interface but useful for testing.
@rtype: L{tuple}
)rm  rn  ro  rX   uris   &&rY   endpointForURI"StubEndpointFactory.endpointForURI  s     

CHHchh//r\   rb   N)r]   r^   r_   r`   rz   r  ra   rb   r\   rY   r  r    s    
0r\   r  c                     ] tR tRtRtR tR tR tR tR t	R t
R	 tR
 tR tR tR tR tR tR tR tR tR tR tR tR tR t]! ]'       * R4      R 4       tR t]! ]'       * R4      R 4       tR tR t R t!R t"R  t#R! t$R"t%R## )$
AgentTestsi  z9
Tests for the new HTTP client API provided by L{Agent}.
c                B    \         P                  ! V P                  4      # )z5
@return: a new L{twisted.web.client.Agent} instance
)r/   r!  r#  rr   s   &rY   r  AgentTests.makeAgent  s     ||DLL))r\   c                Z    V P                  4       V n        V P                  4       V n        R# 3
Create an L{Agent} wrapped around a fake reactor.
Nr  r#  r  r$  rr   s   &rY   r   AgentTests.setUp  s"     ))+^^%
r\   c                2   \         P                  ! V P                  4      pV P                  VP                  \
        4       V P                  VP                  P                  R4       V P                  VP                  VP                  P                  4       R# )zF
If no pool is passed in, the L{Agent} creates a non-persistent pool.
FN)
r/   r!  r#  rF  _poolr=   r   ru  rz  _reactorrX   r$  s   & rY   test_defaultPoolAgentTests.test_defaultPool  sc     T\\*ekk+=>//7U^^U[[-A-ABr\   c                ,  a  \        S P                  4      p\        P                  ! S P                  VR7      pV 3R lVn        VP                  RR4       S P                  S P                  P                  ^ ,          ^ ,          P                  R4       R# )z
If C{persistent} is set to C{True} on the L{HTTPConnectionPool} (the
default), C{Request}s are created with their C{persistent} flag set to
C{True}.
r@  c                    < S# r~   rb   r  rX   s   *rY   r   ,AgentTests.test_persistent.<locals>.<lambda>      4r\   r     http://127.0.0.1TN
r=   r#  r/   r!  r"  rw   r   r  rp   ru  rX   r@  r$  s   f  rY   test_persistentAgentTests.test_persistent  sh     "$,,/T\\5/f12//215@@$Gr\   c                0  a  \        S P                  RR7      p\        P                  ! S P                  VR7      pV 3R lVn        VP                  RR4       S P                  S P                  P                  ^ ,          ^ ,          P                  R4       R# )ag  
If C{persistent} is set to C{False} when creating the
L{HTTPConnectionPool}, C{Request}s are created with their
C{persistent} flag set to C{False}.

Elsewhere in the tests for the underlying HTTP code we ensure that
this will result in the disconnection of the HTTP protocol once the
request is done, so that the connection will not be returned to the
pool.
Fru  r  c                    < S# r~   rb   r  s   *rY   r   /AgentTests.test_nonPersistent.<locals>.<lambda>  r  r\   r  r  Nr  r  s   f  rY   test_nonPersistentAgentTests.test_nonPersistent  sj     "$,,5AT\\5/f12//215@@%Hr\   c                  a a \        4       o ! VV 3R lR\        P                  4      p ! VV 3R lR4      pV! 4       pV! S P                  VR7      pS P	                  W4P
                  4       \        P                  ! 4       pVP                  RR4       \        4       pVP                  RR	WeR
7       S P                  VP
                  P                  R4       R# )z
When a connection is made by the Agent, it uses its pool's
C{getConnection} method to do so, with the endpoint returned by
C{self._getEndpoint}. The key used is C{(scheme, host, port)}.
c                  &   < ] tR tRtV V3R ltRtR# ):AgentTests.test_connectUsesConnectionPool.<locals>.MyAgenti  c                	n   < SP                  VP                  VP                  VP                  3R4       S# )r  r     foorX  )r   rm  rn  ro  )thisr  r  rX   s   &&rY   r"  GAgentTests.test_connectUsesConnectionPool.<locals>.MyAgent._getEndpoint  s1      ZZ38846K  r\   rb   N)r]   r^   r_   r`   r"  ra   r  rX   s   rY   MyAgentr*    s       r\   r1  c                  .   < ] tR tRtRtRtV V3R ltRtR# )<AgentTests.test_connectUsesConnectionPool.<locals>.DummyPooli  Fc                	   < R V n         SP                  VS4       SP                  VR4       \        P                  ! \	        4       4      # )Tr,  )	connectedr   r   r   rd   r.  r  epr  rX   s   &&&rY   rN  JAgentTests.test_connectUsesConnectionPool.<locals>.DummyPool.getConnection  s@    !%  X.   &;<}}%5%788r\   rb   Nr]   r^   r_   r`   r5  ru  rN  ra   r0  s   rY   	DummyPoolr3    s    IJ9 9r\   r:  r     hostr-  r     http://foo/)bodyProducerr  TN)r,  r/   r!  r#  rz  r  r1   rB   addRawHeaderobjectrw   r   r5  )rX   r1  r:  r@  r$  r  r=  r  s   f      @rY   test_connectUsesConnectionPool)AgentTests.test_connectUsesConnectionPool  s     !?	  	 fll 	 
	9 
	9 {40T;;/&&(Wf-xN 	 	
 	..5r\   c                ^    V P                  \        V P                  P                  RR4       R# )zR
L{Agent.request} raises L{TypeError} when the C{method} argument isn't
L{bytes}.
GET   http://foo.example/NassertRaises	TypeErrorr$  rw   rr   s   &rY   test_nonBytesMethodAgentTests.test_nonBytesMethod  #    
 	)TZZ%7%7@VWr\   c                b    V P                  V P                  P                  RR4      \        4      # )z
L{Agent.request} returns a L{Deferred} which fails with
L{SchemeNotSupported} if the scheme of the URI passed to it is not
C{'http'}.
r  s   mailto:alice@example.com)assertFailurer$  rw   rA   rr   s   &rY   test_unsupportedScheme!AgentTests.test_unsupportedScheme  s/     !!JJv'BCEW
 	
r\   c                B   V P                   P                  RR4      pV P                  P                  P	                  4       R,          w  r#pVP                  R\        \        4       4      4       V P                  P                  ^
4       V P                  V\        4       R# )zk
The L{Deferred} returned by L{Agent.request} fires with a L{Failure} if
the TCP connection attempt fails.
r  r<  N   NN)
r$  rw   r#  r   r   clientConnectionFailedr)   r   r  r   )rX   rx   rn  ro  r  s   &    rY   test_connectionFailed AgentTests.test_connectionFailed#  sx    
 ##FN;"ll5599;B?G&&tW5K5M-NOR V%;<r\   c                   RpRpV P                   P                  \        P                  ! RW3,          4      4      pV P	                  VP
                  R4       V P	                  VP                  V4       V P                  V\        4       R# )zW
L{Agent._getEndpoint} return a C{HostnameEndpoint} when passed a scheme
of C{'http'}.
rW    s   http://%b:%dr   N)	r$  r"  r9   	fromBytesr   	_hostText_portrF  r   )rX   expectedHostexpectedPortr  s   &   rY   test_connectHTTPAgentTests.test_connectHTTP0  ss    
 &::**MM/\,HHI
 	++];6h(89r\   c                   \         P                  ! R4      pRP                  4       Vn        V P	                  \
        4      ;_uu_ 4       pV P                  P                  V4       RRR4       V P                  XP                  P                  ^ ,          RP                  \        VP                  4      R7      4       R#   + '       g   i     Lb; i)zd
L{Agent._getEndpoint} when given a non-ASCII decodable URI will raise a
L{ValueError} saying such.
s   http://example.com:80u   ☃.comNzaThe host of the provided URI ({reprout}) contains non-ASCII octets, it should be ASCII decodable.)reprout)r9   rW  encodern  rF  
ValueErrorr$  r"  r   	exceptionr  rj   r  )rX   r  es   &  rY   test_nonDecodableURIAgentTests.test_nonDecodableURI>  s    
 mm45&&(z**aJJ##C( + 	KKQ fT#((^f,	
 +*s   	B??C	c                  a  V 3R lS P                   n        S P                   P                  RR4       S P                  P                  P                  4       w  rS P                  VP                  P                  R4      R.4       R# )z
If L{None} is passed to L{Agent.request} for the C{headers} parameter,
a L{Headers} instance is created for the request and a I{Host} header
added to it.
c                    < S# r~   rb   r  s   *rY   r   .AgentTests.test_hostProvided.<locals>.<lambda>X      r\   r     http://example.com/foo?barr;  rW  N	r$  r"  rw   r  rp   r   r   r  r  rX   reqress   f  rY   test_hostProvidedAgentTests.test_hostProvidedR  sb     #5



6#@A==))--/227;n=MNr\   c                  a  V 3R lS P                   n        S P                   P                  RR4       S P                  P                  P                  4       w  rS P                  VP                  P                  R4      R.4       R# )zy
If an IPv6 address is used in the C{uri} passed to L{Agent.request},
the computed I{Host} header needs to be bracketed.
c                    < S# r~   rb   r  s   *rY   r   3AgentTests.test_hostIPv6Bracketed.<locals>.<lambda>c  ri  r\   r  s   http://[::1]/r;  s   [::1]Nrk  rl  s   f  rY   test_hostIPv6Bracketed!AgentTests.test_hostIPv6Bracketed^  sa    
 #5



6#34==))--/227;hZHr\   c                H  a  \         P                  ! RR.RR./4      pV 3R lS P                  n        S P                  P	                  RRV4       S P
                  P                  P                  4       w  r#S P                  VP                  P                  R4      R.4       R# )	z
If the headers passed to L{Agent.request} includes a value for the
I{Host} header, that value takes precedence over the one which would
otherwise be automatically provided.
r-     barr;  s   quuxc                    < S# r~   rb   r  s   *rY   r   .AgentTests.test_hostOverride.<locals>.<lambda>p  ri  r\   r  rj  N)r1   rB   r$  r"  rw   r  rp   r   r   r  r  )rX   r  rm  rn  s   f   rY   test_hostOverrideAgentTests.test_hostOverridei  s     &&'G9'MN"4



6#@'J==))--/227;gYGr\   c                B  a  \         P                  ! 4       pV 3R lS P                  n        S P                  P	                  RRV4       S P
                  pS P                  \        VP                  4      ^4       S P                  V\         P                  ! 4       4       R# )zw
If a I{Host} header must be added to the request, the L{Headers}
instance passed to L{Agent.request} is not modified.
c                    < S# r~   rb   r  s   *rY   r   3AgentTests.test_headersUnmodified.<locals>.<lambda>|  ri  r\   r     http://example.com/fooN)	r1   rB   r$  r"  rw   r  r   r   rp   )rX   r  r  s   f  rY   test_headersUnmodified!AgentTests.test_headersUnmodifiedv  su    
 &&("4



6#<gF== 	X../3,"6"6"89r\   c                `    V P                  V P                  P                  RR^P4      R4       R# )z
When passed a scheme of C{'http'} and a port of C{80},
L{Agent._computeHostValue} returns a string giving just
the host name passed to it.
r  rW  Nr   r$  _computeHostValuerr   s   &rY   test_hostValueStandardHTTP%AgentTests.test_hostValueStandardHTTP  s*     	JJ((."E~	
r\   c                `    V P                  V P                  P                  RRR4      R4       R# )z
When passed a scheme of C{'http'} and a port other than C{80},
L{Agent._computeHostValue} returns a string giving the
host passed to it joined together with the port number by C{":"}.
r  rW  1     example.com:54321Nr  rr   s   &rY   test_hostValueNonStandardHTTP(AgentTests.test_hostValueNonStandardHTTP  s+     	JJ((.%H 	
r\   c                `    V P                  V P                  P                  RRR4      R4       R# )z
When passed a scheme of C{'https'} and a port of C{443},
L{Agent._computeHostValue} returns a string giving just
the host name passed to it.
   httpsrW  rs  Nr  rr   s   &rY   test_hostValueStandardHTTPS&AgentTests.test_hostValueStandardHTTPS  s*     	JJ((>3G	
r\   c                `    V P                  V P                  P                  RRR4      R4       R# )z
When passed a scheme of C{'https'} and a port other than C{443},
L{Agent._computeHostValue} returns a string giving the
host passed to it joined together with the port number by C{":"}.
r  rW  r  r  Nr  rr   s   &rY   test_hostValueNonStandardHTTPS)AgentTests.test_hostValueNonStandardHTTPS  s+     	JJ((>5I 	
r\   c           	       a  V 3R lS P                   n        \        P                  ! RR./4      p\	        4       pS P                   P                  RRW4       S P                  pS P                  \        VP                  4      ^4       VP                  P                  4       w  rES P                  V\        4       S P                  VP                  R4       S P                  VP                  R4       S P                  VP                  \        P                  ! RR.RR./4      4       S P!                  VP"                  V4       R	# )
a/  
L{Agent.request} establishes a new connection to the host indicated by
the host part of the URI passed to it and issues a request using the
method, the path portion of the URI, the headers, and the body producer
passed to it.  It returns a L{Deferred} which fires with an
L{IResponse} from the server.
c                    < S# r~   rb   r  s   *rY   r   )AgentTests.test_request.<locals>.<lambda>  ri  r\   r-  rw  r     http://example.com:1234/foo?bars   /foo?barr;     example.com:1234N)r$  r"  r1   rB   r?  rw   r  r   r   rp   r   rF  r>   methodr  r  rz  r=  )rX   r  bodyr  rm  rn  s   f     rY   test_requestAgentTests.test_request  s    #5

&&'9: x

6#EwU== 	X../3$$((*c7+V,+.KK  &6(G>Q=R!ST	
 	S--t4r\   c                    \         P                  ! V P                  ^R7      pVP                  RR4       V P                  P                  P                  4       ^,          pV P                  ^V4       R# )zf
L{Agent} takes a C{connectTimeout} argument which is forwarded to the
following C{connectTCP} agent.
connectTimeoutr  r<  Nr/   r!  r#  rw   r   r   r   rX   r$  r  s   &  rY   test_connectTimeoutAgentTests.test_connectTimeout  sS    
 T\\!<fn-,,))--/2G$r\   &SSL not present, cannot run SSL tests.c                    \         P                  ! V P                  ^R7      pVP                  RR4       V P                  P                  P                  4       ^,          pV P                  ^V4       R# )ze
L{Agent} takes a C{connectTimeout} argument which is forwarded to the
following C{connectTCP} call.
r  r     https://foo/Nr  r  s   &  rY   test_connectTimeoutHTTPS#AgentTests.test_connectTimeoutHTTPS  sS     T\\!<fo.,,))--/2G$r\   c                    \         P                  ! V P                  RR7      pVP                  RR4       V P                  P                  P                  4       ^,          pV P                  RV4       R# )zb
L{Agent} takes a C{bindAddress} argument which is forwarded to the
following C{connectTCP} call.
192.168.0.1bindAddressr  r<  Nr      r  rX   r$  addresss   &  rY   test_bindAddressAgentTests.test_bindAddress  sT    
 T\\}Efn-,,))--/2+W5r\   c                    \         P                  ! V P                  RR7      pVP                  RR4       V P                  P                  P                  4       ^,          pV P                  RV4       R# )zb
L{Agent} takes a C{bindAddress} argument which is forwarded to the
following C{connectSSL} call.
r  r  r  r  Nr  r  r  s   &  rY   test_bindAddressSSLAgentTests.test_bindAddressSSL  sT     T\\}Efo.,,))--/2+W5r\   c                   RpV P                  V P                  4      pVP                  RV4      pV P                  \	        V P
                  P                  4      ^4       V P
                  P                  P                  4       w  rEV P                  V\        4       \        P                  P                  R^R\        / 4      RV4      pVP                  V4       V P                  V4      pV P                  VP                  P                   VP                  P"                  VP                  P$                  3VP                   VP"                  VP$                  34       R# )zj
L{Response}s returned by L{Agent.request} have a reference to the
L{Request} that was originally issued.
   http://example.com/r     OKN   HTTPr  r  )r%  r#  rw   r   r   r  rp   r   rF  r>   r/   r6   
_constructrB   callbackr   r  absoluteURIr  )rX   r  r$  rQ  rm  rn  respr  s   &       rY   test_responseIncludesRequest'AgentTests.test_responseIncludesRequest  s   
 %--dll;MM&#& 	T]]334a8==))--/c7+))S%dC
 	T''*  ''  ,,  ((
 ZZ#++6	
r\   c                r   RpV P                  V P                  4      pVP                  RV4       V P                  \	        V P
                  P                  4      ^4       V P
                  P                  P                  4       w  r4V P                  V\        4       V P                  VP                  V4       R# )z<
L{Request.absoluteURI} is the absolute URI of the request.
s$   http://example.com/foo;1234?bar#fragr  N)r%  r#  rw   r   r   r  rp   r   rF  r>   r  )rX   r  r$  rm  rn  s   &    rY   test_requestAbsoluteURI"AgentTests.test_requestAbsoluteURI  s     6--dll;fc" 	T]]334a8==))--/c7+#.r\   c                    \         P                  ! RR\        4       R4      pV P                  VP                  R4       R# )zH
L{Request.absoluteURI} is L{None} if L{Request._parsedURI} is L{None}.
   FOOr  N)r/   r>   rB   rz  r  )rX   rw   s   & rY   test_requestMissingAbsoluteURI)AgentTests.test_requestMissingAbsoluteURI#  s0     ..wy$?W00$7r\   c                    \        4       p\        P                  P                  RVR7      p\        P
                  ! R4      pVP                  V4      pV P                  VR4       R# )zd
L{Agent.usingEndpointFactory} creates an L{Agent} that uses the given
factory to create endpoints.
N)endpointFactoryr  )r  rW  rX  )r  r/   r!  usingEndpointFactoryr9   rW  r"  r   )rX   r  r$  r  returnedEndpoints   &    rY   test_endpointFactoryAgentTests.test_endpointFactory*  sW    
 &'11$1Pmm23 --c2)+HIr\   c                
   \         P                  P                  V P                  \	        4       4      pVP
                  pV P                  VP                  VP                  VP                  3\        RVP                  34       R# )zy
If no pool is passed in to L{Agent.usingEndpointFactory}, a default
pool is constructed with no persistent connections.
FN)r/   r!  r  r#  r  r  r   	__class__ru  r  r=   )rX   r$  r@  s   &  rY   test_endpointFactoryDefaultPool*AgentTests.test_endpointFactoryDefaultPool5  s]    
 11$,,@S@UV{{^^T__dmm<7	
r\   c                    \        4       p\        P                  P                  V P                  \        4       V4      pV P                  WP                  4       R# )zZ
If a pool is passed in to L{Agent.usingEndpointFactory} it is used as
the L{Agent} pool.
N)r?  r/   r!  r  r#  r  assertIsr  r  s   &  rY   test_endpointFactoryPool#AgentTests.test_endpointFactoryPoolA  s@    
 x11LL-/
 	dKK(r\   r$  r#  N)&r]   r^   r_   r`   rz   r  r   r  r   r&  r@  rH  rM  rS  r\  rd  ro  rt  rz  r  r  r  r  r  r  r  r   r  r  r  r  r  r  r  r  r  r  ra   rb   r\   rY   r	  r	    s    *&C
HI"%6NX
=:
(
O	IH: 
	

	
5<% 
NDE% F%6 
NDE6 F6
:/8	J

	)r\   r	  c                       ] tR tRtRtR tRtR# )AgentMethodInjectionTestsiM  z6
Test L{client.Agent} against HTTP method injections.
c                    \         P                  ! V P                  4       4      pRpVP                  W\	        4       R4       R# )^
Attempt a request with the provided method.

@param method: see L{MethodInjectionTestsMixin}
   http://twisted.invalidNr/   r!  r  rw   rB   )rX   r  r$  r  s   &&  rY   !attemptRequestWithMaliciousMethod;AgentMethodInjectionTests.attemptRequestWithMaliciousMethodV  s2     T//12'f79d3r\   rb   Nr]   r^   r_   r`   rz   r  ra   rb   r\   rY   r  r  M      
4r\   r  c                       ] tR tRtRtR tRtR# )AgentURIInjectionTestsia  z.
Test L{client.Agent} against URI injections.
c                    \         P                  ! V P                  4       4      pRpVP                  W1\	        4       R4       R# )zX
Attempt a request with the provided method.

@param uri: see L{URIInjectionTestsMixin}
r  Nr  )rX   r  r$  r  s   &&  rY   attemptRequestWithMaliciousURI5AgentURIInjectionTests.attemptRequestWithMaliciousURIj  s2     T//12f79d3r\   rb   Nr]   r^   r_   r`   rz   r  ra   rb   r\   rY   r  r  a  r  r\   r  r  c                  `   a  ] tR tRtRtRR ltR tR tR tR t	R t
R	 tR
 tV 3R ltRtV ;t# )AgentHTTPSTestsiu  z8
Tests for the new HTTP client API that depends on SSL.
c                    \         P                  ! V P                  4       4      P                  \        P
                  ! RW3,          4      4      # )aA  
Create an L{Agent} with an https scheme and return its endpoint
created according to the arguments.

@param host: The host for the endpoint.
@type host: L{bytes}

@param port: The port for the endpoint.
@type port: L{int}

@return: An endpoint of an L{Agent} constructed according to args.
@rtype: L{SSL4ClientEndpoint}
s   https://%b:%d/)r/   r!  r  r"  r9   rW  )rX   rn  ro  s   &&&rY   makeEndpointAgentHTTPSTests.makeEndpoint{  s=     ||D..01>>MM+tl:;
 	
r\   c                    ^ RI Hp V P                  4       pV P                  W!4       V P                  VP                  \
        4       R# )zZ
L{Agent._getEndpoint} return a L{SSL4ClientEndpoint} when passed a
scheme of C{'https'}.
)_WrapperEndpointN)twisted.internet.endpointsr  r  rF  _wrappedEndpointr   )rX   r  r  s   &  rY   test_endpointType!AgentHTTPSTests.test_endpointType  s;    
 	@$$&h9h779IJr\   c                v    V P                  RR7      pV P                  VP                  P                  R4       R# )z0
If a host is passed, the endpoint respects it.
rW  )rn  r   N)r  r   r  rX  )rX   r  s   & rY   test_hostArgumentIsRespected,AgentHTTPSTests.test_hostArgumentIsRespected  s3     $$.$922<<mLr\   c                z    RpV P                  VR7      pV P                  VP                  P                  V4       R# )z0
If a port is passed, the endpoint respects it.
  )ro  N)r  r   r  rY  )rX   r[  r  s   &  rY   test_portArgumentIsRespected,AgentHTTPSTests.test_portArgumentIsRespected  s8     $$,$72288,Gr\   c                    V P                  4       pVP                  R4      P                  pV P                  V\        4       V P                  VP                  R4       R# )zI
L{Agent} wraps its connection creator creator and uses modern TLS APIs.
Nr   )r  _wrapperFactory_connectionCreatorrF  rL   r   	_hostname)rX   r  contextFactorys   &  rY   test_contextFactoryType'AgentHTTPSTests.test_contextFactoryType  sO     $$&!11$7JJn.>?11=Ar\   c                @  aaa RpRp ! R R4      p. o\        \        4       ! VV3R lR4      4       oV! 4       o\        \        4       ! V3R lR4      4       pV! 4       pV P                  4       p\        P
                  ! We4      pVP                  \        P                  ! R	W3,          4      4      pVP                  \        P                  ! \        4      4       VP                  R,          ^,          p	V	P                  R
4      p
V
P                  \!        4       4       S^ ,          ^ ,          pV P#                  V\$        4       V P'                  S^ ,          R,          W34       V P)                  SP*                  4       V P)                  SP,                  4       R
# )a}  
If a custom L{WebClientConnectionCreator}-like object is passed to
L{Agent.__init__} it will be used to determine the SSL parameters for
HTTPS requests.  When an HTTPS request is made, the hostname and port
number of the request URL will be passed to the connection creator's
C{creatorForNetloc} method.  The resulting context object will be used
to establish the SSL connection.
s   example.orgiO  c                  *    ] tR tRtRtRtR tR tRtR# )VAgentHTTPSTests.test_connectHTTPSCustomConnectionCreator.<locals>.JustEnoughConnectioni  Fc                    RV n         R# )z+
The handshake started.  Record that fact.
TN)handshakeStartedrr   s   &rY   do_handshakecAgentHTTPSTests.test_connectHTTPSCustomConnectionCreator.<locals>.JustEnoughConnection.do_handshake  s     )-%r\   c                    RV n         R# )z,
The connection started.  Record that fact.
TN)connectStaterr   s   &rY   set_connect_statehAgentHTTPSTests.test_connectHTTPSCustomConnectionCreator.<locals>.JustEnoughConnection.set_connect_state  s     %)!r\   )r  r  N)	r]   r^   r_   r`   r  r  r  r  ra   rb   r\   rY   JustEnoughConnectionr    s    $ L-)r\   r
  c                  ,   < ] tR tRtR tV V3R ltRtR# )SAgentHTTPSTests.test_connectHTTPSCustomConnectionCreator.<locals>.JustEnoughCreatori  c                	    Wn         W n        R # r~   hostnamero  )rX   r  ro  s   &&&rY   rs   \AgentHTTPSTests.test_connectHTTPSCustomConnectionCreator.<locals>.JustEnoughCreator.__init__  s     ( 	r\   c                V   < SP                  WP                  V P                  34       S# )z
Implement L{IOpenSSLClientConnectionCreator}.

@param tlsProtocol: The TLS protocol.
@type tlsProtocol: L{TLSMemoryBIOProtocol}

@return: C{expectedConnection}
)rv   r  ro  )rX   tlsProtocolcontextArgsexpectedConnections   &&rY   clientConnectionForTLSjAgentHTTPSTests.test_connectHTTPSCustomConnectionCreator.<locals>.JustEnoughCreator.clientConnectionForTLS  s&     ""K		#JK))r\   r  N)r]   r^   r_   r`   rs   r  ra   )r  r  s   rY   JustEnoughCreatorr    s    !
* 
*r\   r  c                  $   < ] tR tRtV 3R ltRtR# )_AgentHTTPSTests.test_connectHTTPSCustomConnectionCreator.<locals>.StubBrowserLikePolicyForHTTPSi  c                   < S! W4      # )z
Emulate L{BrowserLikePolicyForHTTPS}.

@param hostname: The hostname to verify.
@type hostname: L{bytes}

@param port: The port number.
@type port: L{int}

@return: a stub L{IOpenSSLClientConnectionCreator}
@rtype: L{JustEnoughCreator}
rb   )rX   r  ro  r  s   &&&rY   creatorForNetlocpAgentHTTPSTests.test_connectHTTPSCustomConnectionCreator.<locals>.StubBrowserLikePolicyForHTTPS.creatorForNetloc  s     )88r\   rb   Nr]   r^   r_   r`   r  ra   )r  s   rY   StubBrowserLikePolicyForHTTPSr    s    9 9r\   r  s   https://%b:%dNr  )r   r   rG   r  r/   r!  r"  r9   rW  r  r   r  r   r   r  r(  r%   rF  rQ   r   r   r  r  )rX   rZ  r[  r
  r  expectedCreatorCreatorr#  r$  r  
tlsFactoryr  rO   r  r  r  s   &           @@@rY   (test_connectHTTPSCustomConnectionCreator8AgentHTTPSTests.test_connectHTTPSCustomConnectionCreator  sb    &	) 	)  	4	5	* 	* 
6	*" 23	_	%	9 	9 
&	9  "?!@$$&W=%%MM*l-IIJ
 	,,X67''+A.
 ..t4""?#45!nQc#78Q+l-IJ*;;<*778r\   c                    R pV! 4        V P                  V.4      pV P                  \        V4      ^4       Vw  pV P                  VR,          \        4       V P                  VR,          R4       R# )a   
Passing something that duck-types I{like} a L{web client context
factory <twisted.web.client.WebClientContextFactory>} - something that
does not provide L{IPolicyForHTTPS} - to L{Agent} emits a
L{DeprecationWarning} even if you don't actually C{import
WebClientContextFactory} to do it.
c                 V    \         P                  ! \        \        4       4      R 4       R# )z does-not-provide-IPolicyForHTTPSN)r/   r!  r!   r$   rb   r\   rY   warnMe9AgentHTTPSTests.test_deprecatedDuckPolicy.<locals>.warnMe  s    LL-.@.BC2r\   categorymessagez'does-not-provide-IPolicyForHTTPS' was passed as the HTTPS policy for an Agent, but it does not provide IPolicyForHTTPS.  Since Twisted 14.0, you must pass a provider of IPolicyForHTTPS.N)flushWarningsr   r   DeprecationWarning)rX   r&  warningswarnings   &   rY   test_deprecatedDuckPolicy)AgentHTTPSTests.test_deprecatedDuckPolicy  sm    	 	%%vh/X*	,.@AIO	
r\   c                   \        4       p\        VR7      pVP                  RR4      pV P                  VP                  4       VP                  R4      pV P                  VP                  VP                  4       4       R# )z
L{BrowserLikePolicyForHTTPS.creatorForNetloc} returns an
L{IOpenSSLClientConnectionCreator} provider which will add certificates
from the given trust root.
	trustRoots   thingyr  N)	rS   r:   r  r   rV   r  r  rW   get_context)rX   r2  policycreator
connections   &    rY   test_alternateTrustRoot'AgentHTTPSTests.test_alternateTrustRoot  sg     +,	*Y?)))T:	(()33D9
i'')?)?)ABr\   c           	        <aa VP                  R4      p\        VP                  R4      4      w  ooV3R lpV3R lp\        S	V `  VVVVVRR7       R# )z3
Wrap L{AgentTestsMixin.integrationTest} with TLS.
s   []asciic                :   < \        SP                  4       R W4      # )F)rP   options)serverFactoryr#  r  s   &&rY   tlsify/AgentHTTPSTests.integrationTest.<locals>.tlsify4  s    &v~~'7WWr\   c                   < ^ RI Hp ^ RIHp V! V4       ! V3R lR4      4       p\        P
                  ! W! 4       R7      # )r  r   )rG   c                  $   < ] tR tRtV 3R ltRtR# )AAgentHTTPSTests.integrationTest.<locals>.tlsagent.<locals>.Policyi<  c                	<   < \        VP                  R 4      SR7      # )r:  r1  )rN   decode)rX   r  ro  	authoritys   &&&rY   r  RAgentHTTPSTests.integrationTest.<locals>.tlsagent.<locals>.Policy.creatorForNetloc>  s    . 0I r\   rb   Nr  )rE  s   rY   PolicyrB  <  s     r\   rG  )r  )zope.interfacer   twisted.web.iwebrG   r/   r!  )r#  r   rG   rG  rE  s   &   rY   tlsagent1AgentHTTPSTests.integrationTest.<locals>.tlsagent7  s:    28)  * <<AAr\   r  )r  r  rm  N)stripr,   rD  superr  )
rX   r  r  r  certHostNamer>  rJ  rE  r  r  s
   &&&&   @@rY   r  AgentHTTPSTests.integrationTest+  sb      ~~e,=(
	6	X	B G#$$ $ r\   rb   )rW  rs  )r]   r^   r_   r`   rz   r  r  r  r  r  r"  r.  r7  r  ra   __classcell__)r  s   @rY   r  r  u  sA    
$	KMHBQ9f
6C#
 #
r\   r  c                      ] tR tRtRtR tR t]! ]R4      R 4       t	]! ]'       * R4      R 4       t
]! ]'       * R4      R	 4       tR
tR# )WebClientContextFactoryTestsiQ  zf
Tests for the context factory wrapper for web clients
L{twisted.web.client.WebClientContextFactory}.
c                h    ^ RI Hp V P                  \        P                  .4      V n        Wn        R# )zE
Get WebClientContextFactory while quashing its deprecation warning.
)WebClientContextFactoryN)twisted.web.clientrT  r*  rR  r   warnedwebClientContextFactory)rX   rT  s   & rY   r   "WebClientContextFactoryTests.setUpW  s)     	?((*F*L*L)MN'>$r\   c                D   V P                  \        V P                  4      ^4       V P                  w  pV P                  VR,          \        4       V P                  VR,          \	        V P
                  \        R^^ ^ 4      \        R7      P                  RR4      4       R# )z`
L{twisted.web.client.WebClientContextFactory} is deprecated.  Importing
it displays a warning.
r(  r)  Twisted)replacement;:N)	r   r   rV  r+  r(   rW  r   r:   replace)rX   r-  s   & rY   test_deprecated,WebClientContextFactoryTests.test_deprecated`  s    
 	T[[)1-KK	,.@AI',,	2q!,5 WS#		
r\   zSSL Present.c                f    V P                  \        V P                  4       P                  RR4       R# )zT
If C{getContext} is called and SSL is not available, raise
L{NotImplementedError}.
rW  rs  N)rF  NotImplementedErrorrW  
getContextrr   s   &rY   test_missingSSL,WebClientContextFactoryTests.test_missingSSLs  s-     	((*55		
r\   r  c                    V P                  4       P                  RR4      pV P                  V\        P                  P
                  4       R# )zD
If SSL is present, C{getContext} returns a L{OpenSSL.SSL.Context}.
r   rs  N)rW  rc  rF  rK   SSLContext)rX   ctxs   & rY   test_returnsContext0WebClientContextFactoryTests.test_returnsContext  s7    
 **,77sKc377??3r\   c                    V P                  4       pVP                  RR4      pV P                  VP                  \        P
                  4       R# )zL
The L{CertificateOptions} has C{trustRoot} set to the default trust
roots.
r   rs  N)rW  _getCertificateOptionsrF  r2  rK   OpenSSLDefaultPaths)rX   ri  certificateOptionss   &  rY   -test_setsTrustRootOnContextToDefaultTrustRootJWebClientContextFactoryTests.test_setsTrustRootOnContextToDefaultTrustRoot  sB     **, 77sK0::C<S<STr\   )rV  rW  N)r]   r^   r_   r`   rz   r   r_  r   r  rd  rj  rp  ra   rb   r\   rY   rR  rR  Q  sl    
?
& J'

 (

 
NDE4 F4 
NDEU FUr\   rR  c                  h    ] tR tRtRtR tR tR tR tR t	R t
R	 tR
 tR tR tR tR tR tRtR# )HTTPConnectionPoolRetryTestsi  z
L{client.HTTPConnectionPool}, by using
L{client._RetryingHTTP11ClientProtocol}, supports retrying requests done
against previously cached connections.
c                   \         P                  ! R4      p\         P                  ! RV4      pV P                  VP	                  R\        4       R4      4       V P                  VP	                  R\        4       R4      4       V P                  VP	                  R\        4       R4      4       V P                  VP	                  R\        4       R4      4       V P                  VP	                  R\        4       R4      4       V P                  VP	                  R\        4       R4      4       V P                  VP	                  R\        4       R4      4       R# )	z?
Only GET, HEAD, OPTIONS, TRACE, DELETE methods cause a retry.
Nr  s   HEADs   OPTIONSs   TRACEs   DELETE   POSTs   MYMETHOD)r/   r=   _RetryingHTTP11ClientProtocolr   _shouldRetryr4   assertFalserX   r@  r6  s   &  rY   test_onlyRetryIdempotentMethods<HTTPConnectionPoolRetryTests.test_onlyRetryIdempotentMethods  s     ((.99$E

//8H$OP
//9I4PQ
//
N<LdST
//.:JDQR
//	>;KTRS00.:JDQR00n>NPTUVr\   c                
   \         P                  ! R4      p\         P                  ! RV4      pV P                  VP	                  R\        4       R4      4       V P                  VP	                  R\        . 4      R4      4       V P                  VP	                  R\        . 4      R4      4       V P                  VP	                  R\        . 4      R4      4       V P                  VP	                  R\        4       R4      4       R# )zm
Only L{RequestNotSent}, L{RequestTransmissionFailed} and
L{ResponseNeverReceived} exceptions cause a retry.
Nr  )r/   r=   rv  r   rw  r4   r5   r8   rx  r7   r   ry  s   &  rY   "test_onlyRetryIfNoResponseReceived?HTTPConnectionPoolRetryTests.test_onlyRetryIfNoResponseReceived  s    
 ((.99$E

//8H$OP##F,Eb,I4P	
 	##F,A",EtL	
 	009KTRS##F,B,DdK	
r\   c                    \         P                  ! R4      p\         P                  ! RV4      p\        \	        \
        P                  ! 4       4      .4      pV P                  VP                  RVR4      4       R# )z
If a request failed due to the operation being cancelled,
C{_shouldRetry} returns C{False} to indicate the request should not be
retried.
Nr  )	r/   r=   rv  r8   r)   r   r   rx  rw  )rX   r@  r6  rb  s   &   rY   !test_dontRetryIfFailedDueToCancel>HTTPConnectionPoolRetryTests.test_dontRetryIfFailedDueToCancel  s^     ((.99$E
)753G3G3I+J*KL	00DIJr\   c                    \         P                  ! R4      p\         P                  ! RV4      pV P                  VP	                  R\        \        \        4       4      .4      R4      4       R# )z
If a request failed with L{ResponseNeverReceived} due to some
arbitrary exception, C{_shouldRetry} returns C{True} to indicate the
request should be retried.
Nr  )r/   r=   rv  r   rw  r8   r)   	Exceptionry  s   &  rY   )test_retryIfFailedDueToNonCancelExceptionFHTTPConnectionPoolRetryTests.test_retryIfFailedDueToNonCancelException  sW     ((.99$E
##-wy{/C.DEt	
r\   c                  a a \         P                  ! \        4       4      p\        4       oSP	                  \        4       4       VP                  ^{S4       VP                  ^{\        4       4      pVV 3R lpVP                  V4      # )z
If L{client.HTTPConnectionPool.getConnection} returns a previously
cached connection, it will get wrapped in a
L{client._RetryingHTTP11ClientProtocol}.
c                   < SP                  V \        P                  4       SP                  V P                  S4       R # r~   )rF  r/   rv  rz  _clientProtocolr6  r  rX   s   &rY   rK  THTTPConnectionPoolRetryTests.test_wrappedOnPersistentReturned.<locals>.gotConnection  s/    !!*f.R.RS  !;!;XFr\   )
r/   r=   r    rd   r(  r%   rY  rN  r,  rO  rX   r@  rQ  rK  r  s   f   @rY    test_wrappedOnPersistentReturned=HTTPConnectionPoolRetryTests.test_wrappedOnPersistentReturned  so     ((1 $% 12C* sMO4	G }}]++r\   c                   a  \         P                  ! R4      pVP                  ^{\        4       4      pV 3R lpVP	                  V4      # )zd
If L{client.HTTPConnectionPool.getConnection} returns a new
connection, it will be returned as is.
Nc                H   < SP                  V P                  \        4       R # r~   )rz  r  r2   )r6  rX   s   &rY   rK  PHTTPConnectionPoolRetryTests.test_notWrappedOnNewReturned.<locals>.gotConnection  s       !5!57KLr\   )r/   r=   rN  r,  rO  )rX   r@  rQ  rK  s   f   rY   test_notWrappedOnNewReturned9HTTPConnectionPoolRetryTests.test_notWrappedOnNewReturned  s@    
 ((.sMO4	M
 }}]++r\   c                  a aaa	 . o	V	3R lp\        4       o\        P                  ! RR\        4       SRR7      pV! 4        S	^ ,          p\        P                  ! WB4      pVV V3R lpWen        VP                  V4      pS P                  \        S	4      ^4       S P                  \        S	^ ,          P                  4      ^4       VP                  ^ ,          ^,          P                  \        4       4       VS	3# )z@
Fail a first request, possibly retrying depending on argument.
c                 f   < \        4       p SP                  V 4       \        P                  ! V 4      # r~   )rd   rv   r   r   )r  	protocolss    rY   rg  >HTTPConnectionPoolRetryTests.retryAttempt.<locals>.newProtocol  s(    ')HX&==**r\   r  r  Tr#  c                   < SP                  V R 4       SP                  VS4       SP                  V\        \        34       S# )r  )r   rz  rF  r4   r8   )mrc  bpr=  rX   willWeRetrys   &&&rY   rw  ?HTTPConnectionPoolRetryTests.retryAttempt.<locals>._shouldRetry  s?    Q'  \2!!!n6K%LMr\   )r?  r/   r>   rB   rv  rw  rw   r   r   rp   errbackr4   )
rX   r  rg  rw   r  retrierrw  rQ  r=  r  s
   ff      @@rY   retryAttempt)HTTPConnectionPoolRetryTests.retryAttempt  s     		+
 x..wy,SWXQ<66xM	  ,OOG$ 	Y+Yq\223Q7 	!Q''(89)|r\   c                
   V P                  R4      w  rV P                  \        V4      ^4       \        4       pV^,          P                  ^ ,          ^,          P                  V4       VP                  V P                  V4      # )z|
L{client._RetryingHTTP11ClientProtocol} retries when
L{client._RetryingHTTP11ClientProtocol._shouldRetry} returns C{True}.
T)r  r   r   r?  rp   r  rO  rz  )rX   rQ  r  r  s   &   rY   "test_retryIfShouldRetryReturnsTrue?HTTPConnectionPoolRetryTests.test_retryIfShouldRetryReturnsTrue   sj    
 ((.Y+8!a #,,X6}}T118<<r\   c                    V P                  R4      w  rV P                  \        V4      ^4       V P                  V\        4      # )z
L{client._RetryingHTTP11ClientProtocol} does not retry when
L{client._RetryingHTTP11ClientProtocol._shouldRetry} returns C{False}.
F)r  r   r   rL  r4   rX   rQ  r  s   &  rY   'test_dontRetryIfShouldRetryReturnsFalseDHTTPConnectionPoolRetryTests.test_dontRetryIfShouldRetryReturnsFalse,  s=    
 ((/Y+!!!^44r\   c                   \         P                  ! R4      p\         P                  ! RV4      pV P                  VP	                  R\        4       R4      4       V P                  VP	                  R\        4       \        4       4      4       R# )z
L{_RetryingHTTP11ClientProtocol} only retries queries that don't have
a body.

This is an implementation restriction; if the restriction is fixed,
this test should be removed and PUT added to list of methods that
support retries.
Nr  )r/   r=   rv  r   rw  r4   rx  r?  ry  s   &  rY   test_onlyRetryWithoutBody6HTTPConnectionPoolRetryTests.test_onlyRetryWithoutBody6  sf     ((.99$E

//8H$OP009I68TUr\   c                2   V P                  R4      w  rV P                  \        V4      ^4       V^,          P                  ^ ,          ^,          P	                  \        . 4      4       V P                  \        V4      ^4       V P                  V\
        4      # )z
If a L{client._RetryingHTTP11ClientProtocol} fails more than once on
an idempotent query before a response is received, it will not retry.
T)r  r   r   rp   r  r8   rL  r  s   &  rY   test_onlyRetryOnce/HTTPConnectionPoolRetryTests.test_onlyRetryOnceD  sz    
 ((.Y+!a #++,A",EFY+!!!%:;;r\   c                  a a \         P                  ! \        4       4      pRVn        \	        4       oSP                  \        4       4       VP                  ^{S4       VP                  ^{\        4       4      pVV 3R lpVP                  V4      # )zm
If L{HTTPConnectionPool.retryAutomatically} is set to C{False}, don't
wrap connections with retrying logic.
Fc                ,   < SP                  V S4       R # r~   )rz  r  s   &rY   rK  [HTTPConnectionPoolRetryTests.test_dontRetryIfRetryAutomaticallyFalse.<locals>.gotConnectiona  s      X6r\   )r/   r=   r    rB  rd   r(  r%   rY  rN  r,  rO  r  s   f   @rY   'test_dontRetryIfRetryAutomaticallyFalseDHTTPConnectionPoolRetryTests.test_dontRetryIfRetryAutomaticallyFalseQ  sv    
 ((1"' $% 12C* sMO4	7 }}]++r\   c                @  a aaaa \         P                  ! \        4       4      p^{o\        4       o. oV3R lpW!n        \        4       oSP                  \        4       4       VP                  SS4       VP                  SS4      pVVVVV 3R lpVP                  V4      # )z
L{client.HTTPConnectionPool} creates
{client._RetryingHTTP11ClientProtocol} with a new connection factory
method that creates a new connection using the same key and endpoint
as the wrapped connection.
c                ,   < SP                  W34       R # r~   )rv   )krc  newConnectionss   &&rY   r  OHTTPConnectionPoolRetryTests.test_retryWithNewConnection.<locals>.newConnections  s    !!1&)r\   c                z  < SP                  V \        P                  4       SP                  V P                  S4       SP                  S. 4       V P                  4        SP                  \        S4      ^4       SP                  S^ ,          ^ ,          S4       SP                  S^ ,          ^,          S4       R# r  N)rF  r/   rv  rz  r  r   r  r   )r6  r  r  r  r  rX   s   &rY   rK  OHTTPConnectionPoolRetryTests.test_retryWithNewConnection.<locals>.gotConnection  s    !!*f.R.RS  !;!;XF ^R0%%'S0!4^A.q137  !21!5x@r\   )r/   r=   r    r,  r  rd   r(  r%   rY  rN  rO  )	rX   r@  r  rQ  rK  r  r  r  r  s	   f    @@@@rY   test_retryWithNewConnection8HTTPConnectionPoolRetryTests.test_retryWithNewConnectionf  s     ((1 ?	* , $% 12C* sH-		A 		A }}]++r\   rb   N)r]   r^   r_   r`   rz   rz  r}  r  r  r  r  r  r  r  r  r  r  r  ra   rb   r\   rY   rs  rs    sL    W"
&	K
,.,!F
=5V<,*&,r\   rs  c                  &    ] tR tRtRtR R ltRtR# )CookieTestsMixini  z,
Mixin for unit tests dealing with cookies.
c               (    V ^8  d   QhRRRRRRRR/# )	rg   	cookieJarr   r  r   cookieszlist[bytes]rh   z<tuple[client._FakeStdlibRequest, client._FakeStdlibResponse]rb   )rj   s   "rY   rk   CookieTestsMixin.__annotate__  s,     ! !"!).!9D!	E!r\   c                    \         P                  ! \         P                  ! R^R\        RV/4      R4      4      p\         P                  ! V4      pVP                  WE4       WT3# )z
Add a cookie to a cookie jar.
r  
   Set-CookieNr  )r/   _FakeStdlibResponser6   rB   _FakeStdlibRequestextract_cookies)rX   r  r  r  r  rw   s   &&&&  rY   
addCookiesCookieTestsMixin.addCookies  sb     --OO01
 ++C0!!(4  r\   rb   N)r]   r^   r_   r`   rz   r  ra   rb   r\   rY   r  r    s    ! !r\   r  c                  >    ] tR tRtRtR R ltR R ltR R ltR	tR
# )CookieJarTestsi  z
Tests for L{twisted.web.client._FakeStdlibResponse} and
L{twisted.web.client._FakeStdlibRequest}'s interactions with L{CookieJar}
instances.
c                   V ^8  d   QhRR/# )rg   rh   zNtuple[CookieJar, tuple[client._FakeStdlibRequest, client._FakeStdlibResponse]]rb   )rj   s   "rY   rk   CookieJarTests.__annotate__  s     ! !	W!r\   c                F    \        4       pV P                  VRRR.4      pW3# )z2
@return: a L{CookieJar} with some sample cookies
r  s(   foo=1; cow=moo; Path=/foo; Comment=hellos   bar=2; Comment=goodbye)r   r  )rX   r  reqress   &  rY   makeCookieJarCookieJarTests.makeCookieJar  s3     K	.8:ST

   r\   c                   V ^8  d   QhRR/# rf   rb   )rj   s   "rY   rk   r    s     G GT Gr\   c                L   V P                  4       ^ ,          pV Uu/ uF  q"P                  VbK  	  ppVR,          pV P                  VP                  ^ 4       V P                  VP                  R4       V P                  VP                  R4       V P                  VP
                  R4       V P                  VP                  R4       V P                  VP                  R4      R4       VR,          pV P                  VP                  ^ 4       V P                  VP                  R4       V P                  VP                  R4       V P                  VP
                  R	4       V P                  VP                  R
4       V P                  VP                  R4      R4       R# u upi )z
L{CookieJar.extract_cookies} extracts cookie information from our
stdlib-compatibility wrappers, L{client._FakeStdlibRequest} and
L{client._FakeStdlibResponse}.
r   1z/foohellocowmoobar2/goodbyeN)	r  namer   versionr  pathcommentget_nonstandard_attrrz  )rX   jarcr  cookies   &    rY   test_extractCookies"CookieJarTests.test_extractCookies  sF      "1%&)*c6619c*+e,s+f-144U;UC+e,s+c*3V88?F! +s   F!c                   V ^8  d   QhRR/# rf   rb   )rj   s   "rY   rk   r    s     
 
 
r\   c                   V P                  4       w  pw  r#V P                  VP                  RR4      R4       VP                  V4       V P	                  \        VP                  P                  4       4      RR.3.4       R# )zx
L{CookieJar.add_cookie_header} adds a cookie header to a Twisted
request via our L{client._FakeStdlibRequest} wrapper.
CookieNs   Cookies   foo=1; bar=2)r  rz  
get_headeradd_cookie_headerr   list_twistedHeadersgetAllRawHeaders)rX   r  rw   r  s   &   rY   test_sendCookieCookieJarTests.test_sendCookie  sx    
 $(#5#5#7  gW//$?Fg&((99;</*+,	
r\   rb   N)	r]   r^   r_   r`   rz   r  r  r  ra   rb   r\   rY   r  r    s    !G2
 
r\   r  c                  x    ] tR tRtRtR tR tR tR R ltR t	]
! ]'       * R	4      R
 4       tR tR tR tRtR# )CookieAgentTestsi  z.
Tests for L{twisted.web.client.CookieAgent}.
c                r    \         P                  ! V P                  V P                  4      \	        4       4      # )z2
@return: a new L{twisted.web.client.CookieAgent}
)r/   CookieAgentr%  r#  r   rr   s   &rY   r  CookieAgentTests.makeAgent  s-     !!))$,,7
 	
r\   c                	0    V P                  4       V n        R # r~   )r  r#  rr   s   &rY   r   CookieAgentTests.setUp  s    ))+r\   c           	       a a \        4       oS P                  \        S4      . 4       S P                  S P                  4      p\
        P                  ! VS4      pVP                  RR4      pVV 3R lpVP                  V4       S P                  P                  P                  4       w  rVS P                  VP                  P                  R4      R4       \
        P                  ! R	^R\!        RR./4      R4      pVP#                  V4       V# )
z
L{CookieAgent.request} does not insert any C{'Cookie'} header into the
L{Request} object if there is no cookie in the cookie jar for the URI
being requested. Cookies are extracted from the response and stored in
the cookie jar.
r  r  c                   < \        S4      pSP                  \        V4      ^4       SP                  V^ ,          P                  R4       SP                  V^ ,          P                  R4       R# )r  r   r  N)r  r   r   r  r  )ignoredr  r  rX   s   & rY   _checkCookieACookieAgentTests.test_emptyCookieJarRequest.<locals>._checkCookie  sR    9oGS\1-WQZ__e4WQZ--s3r\      cookieNr  r     foo=1r  )r   r   r  r%  r#  r/   r  rw   rO  r  rp   r   rz  r  r  r6   rB   r  )	rX   r$  cookieAgentrQ  r  rm  rn  r  r  s	   f       @rY   test_emptyCookieJarRequest+CookieAgentTests.test_emptyCookieJarRequest  s     K	i"---dll;((	:(JK	4 	
l#==))--/S[[66yA4H! $ 
 	Tr\   c                   V ^8  d   QhRR/# rf   rb   )rj   s   "rY   rk   CookieAgentTests.__annotate__"  s     Q Q Qr\   c                   RpRp\        4       pV P                  W1V.4       V P                  \        \	        V4      4      ^4       V P                  V P                  4      p\        P                  ! WC4      pVP                  RV\        RR./4      4       V P                  P                  P                  4       w  rgV P                  VP                  P                  R4      R.4       R# )	z
L{CookieAgent.request} will not insert a C{'Cookie'} header into the
L{Request} object when there is already a C{'Cookie'} header in the
request headers parameter.
r  r  r  r  zalready-setr  s   already-setN)r   r  r   r   r  r%  r#  r/   r  rw   rB   r  rp   r   r  r  rX   r  r  r  r$  r  rm  rn  s   &       rY   test_leaveExistingCookieHeader/CookieAgentTests.test_leaveExistingCookieHeader"  s     1K		1T)_-q1--dll;((:FC(]O1L)MN==))--/229=?OPr\   c                   RpRp\        4       pV P                  W1V.4       V P                  \        \	        V4      4      ^4       V P                  V P                  4      p\        P                  ! WC4      pVP                  RV4       V P                  P                  P                  4       w  rgV P                  VP                  P                  R4      V.4       R# )z
L{CookieAgent.request} inserts a C{'Cookie'} header into the L{Request}
object when there is a cookie matching the request URI in the cookie
jar.
r  r  r  r  Nr   r  r   r   r  r%  r#  r/   r  rw   r  rp   r   r  r  r  s   &       rY   test_requestWithCookie'CookieAgentTests.test_requestWithCookie6  s     1K		1T)_-q1--dll;((:FC(==))--/229=xHr\   r  c                   RpRp\        4       pV P                  W1V.4       V P                  \        \	        V4      4      ^4       V P                  V P                  4      p\        P                  ! WC4      pVP                  RV4       V P                  P                  P                  4       w  rgV P                  VP                  P                  R4      R.4       R# )zf
L{CookieAgent} is able to handle secure cookies, ie cookies which
should only be handled over https.
s    https://example.com:1234/foo?bar   foo=1;securer  r  r  Nr  r  s   &       rY   test_secureCookie"CookieAgentTests.test_secureCookieJ  s     2 K		1T)_-q1--dll;((:FC(==))--/229=zJr\   c                   RpRp\        4       pV P                  W1V.4       V P                  \        \	        V4      4      ^4       V P                  V P                  4      p\        P                  ! WC4      pVP                  RV4       V P                  P                  P                  4       w  rgV P                  RVP                  P                  R4      4       R# )z[
If a cookie is setup as secure, it won't be sent with the request if
it's not over HTTPS.
rj  r  r  Nr  )r   r  r   r   r  r%  r#  r/   r  rw   r  rp   r   rz  r  r  r  s   &       rY   %test_secureCookieOnInsecureConnection6CookieAgentTests.test_secureCookieOnInsecureConnection^  s    
 , K		1T)_-q1--dll;((:FC(==))--/T3;;#<#<Y#GHr\   c                   RpRp\        4       pV P                  W1V.4       V P                  \        \	        V4      4      ^4       V P                  V P                  4      p\        P                  ! WC4      pVP                  RV4       V P                  P                  P                  4       w  rgV P                  VP                  P                  R4      R.4       R# )zb
L{CookieAgent} supports cookies which enforces the port number they
need to be transferred upon.
r     foo=1;port=1234r  r  r  Nr  r  s   &       rY   test_portCookie CookieAgentTests.test_portCookieq  s    
 1#K		1T)_-q1--dll;((:FC(==))--/229=zJr\   c                    RpRp\        4       pV P                  W1V.4       V P                  \        \	        V4      4      ^ 4       R# )z
When creating a cookie with a port directive, it won't be added to the
L{cookie.CookieJar} if the URI is on a different port.
s   http://example.com:4567/foo?barr  N)r   r  r   r   r  )rX   r  r  r  s   &   rY   test_portCookieOnWrongPort+CookieAgentTests.test_portCookieOnWrongPort  s>    
 1#K		1T)_-q1r\   r  N)r]   r^   r_   r`   rz   r  r   r  r  r  r   r  r  r  r  r  ra   rb   r\   rY   r  r    sU    
,(TQ(I( 
NDEK FK&I&K&
2r\   r  c                      ] tR tRtRtRtR# )Decoder1i  C
A test decoder to be used by L{client.ContentDecoderAgent} tests.
rb   Nr]   r^   r_   r`   rz   ra   rb   r\   rY   r  r        r\   r  c                      ] tR tRtRtRtR# )Decoder2i  r  rb   Nr  rb   r\   rY   r  r    r  r\   r  c                  D    ] tR tRtRtR tR tR tR tR t	R t
R	 tR
tR# )ContentDecoderAgentTestsi  z*
Tests for L{client.ContentDecoderAgent}.
c                D    \         P                  ! V P                  . 4      # )z:
@return: a new L{twisted.web.client.ContentDecoderAgent}
)r/   ContentDecoderAgentr$  rr   s   &rY   r  "ContentDecoderAgentTests.makeAgent  s     ))$**b99r\   c                p    V P                  4       V n        V P                  V P                  4      V n        R# r  )r  r#  r%  r$  rr   s   &rY   r   ContentDecoderAgentTests.setUp  s*     ))+224<<@
r\   c                z   \         P                  ! V P                  R\        3R\        3.4      pVP                  RR4       V P                  pV P                  \        VP                  4      ^4       VP                  P                  4       w  r4V P                  VP                  P                  R4      R.4       R# )zq
L{client.ContentDecoderAgent} sets the I{Accept-Encoding} header to the
names of the available decoder objects.
   decoder1   decoder2r  r     accept-encoding   decoder1,decoder2N)r/   r"  r$  r  r  rw   r  r   r   rp   r   r  r  )rX   r$  r  rm  rn  s   &    rY   test_acceptHeaders+ContentDecoderAgentTests.test_acceptHeaders  s    
 **JJ+x0;2IJ
 	f78==X../3$$((*KK%%&89<P;Q	
r\   c                   \         P                  ! RR.RR./4      p\        P                  ! V P                  R\
        3R\        3.4      pVP                  RRVR	7       V P                  pV P                  \        VP                  4      ^4       VP                  P                  4       w  rEV P                  \        \        VP                  P!                  4       4      4      R
RR.3RR.3RR.3.4       R# )z
If there are existing I{Accept-Encoding} fields,
L{client.ContentDecoderAgent} creates a new field for the decoders it
knows about.
r-  rw  r)     fizzr'  r(  r  r  r  s   Accept-Encodingr*     Foor  rW  N)r1   rB   r/   r"  r$  r  r  rw   r  r   r   rp   r   r  sortedr  r  )rX   r  r$  r  rm  rn  s   &     rY   test_existingHeaders-ContentDecoderAgentTests.test_existingHeaders  s     &&fX1G9=
 **JJ+x0;2IJ
 	f7I==X../3$$((*44678#g/C%DE&">*+	
r\   c                n   \         P                  ! V P                  R\        3R\        3.4      pVP                  RR4      pV P                  P                  P                  4       w  r4\        R^R\        P                  ! 4       R4      pVP                  V4       VP                  V P                  V4      # )z
If the response is not encoded despited the request I{Accept-Encoding}
headers, L{client.ContentDecoderAgent} simply forwards the response.
r'  r(  r  r  r  Nr  )r/   r"  r$  r  r  rw   r  rp   r   r6   r1   rB   r  rO  rz  )rX   r$  r  rm  rn  r  s   &     rY   test_plainEncodingResponse3ContentDecoderAgentTests.test_plainEncodingResponse  s    
 **JJ+x0;2IJ
 ==)BC==))--/OS%9M9M9OQUVX##D$8$8(CCr\   c                   \         P                  ! V P                  R\        3R\        3.4      pVP                  RR4      pV P                  P                  P                  4       w  r4\        P                  ! RR.RR./4      p\        R^R	VR
4      pVP                  V4       VP                  V P                  V4      # )zb
If an encoding unknown to the L{client.ContentDecoderAgent} is found,
the response is unchanged.
r'  r(  r  r  r-  rw     content-encodingr.  r  Nr  )r/   r"  r$  r  r  rw   r  rp   r   r1   rB   r6   r  rO  rz  )rX   r$  r  rm  rn  r  r  s   &      rY   test_unsupportedEncoding1ContentDecoderAgentTests.test_unsupportedEncoding  s    
 **JJ+x0;2IJ
 ==)BC==))--/&&fX2WI>
 OS%$GX##D$8$8(CCr\   c                |  a a \         P                  ! S P                  R\        3R\        3.4      pVP                  RR4      pS P                  P                  P                  4       w  r4\        P                  ! RR.RR./4      p\        R^R	VR
4      oVP                  S4       VV 3R lpVP                  V4      # )z
When L{client.ContentDecoderAgent} encounters a decoder it doesn't know
about, it stops decoding even if another encoding is known afterwards.
r'  r(  r  r  r-  rw  r8  s   decoder1,fizz,decoder2r  Nc                   < SP                  SV 4       SP                  V \        4       SP                  R .V P                  P                  R4      4       R# )s   decoder1,fizzr8  N)r  rF  r  r   r  r  )rx   r  rX   s   &rY   check<ContentDecoderAgentTests.test_unknownEncoding.<locals>.check	  sI    ##Hf5!!&(3!"FNN$@$@AT$Ur\   r  )r/   r"  r$  r  r  rw   r  rp   r   r1   rB   r6   r  rO  )rX   r$  r  rm  rn  r  r=  r  s   f      @rY   test_unknownEncoding-ContentDecoderAgentTests.test_unknownEncoding	  s    
 **JJ+x0;2IJ
 ==)BC==))--/&&fX25N4OP
 OS%$GX	 ##E**r\   r  N)r]   r^   r_   r`   rz   r  r   r+  r2  r5  r9  r?  ra   rb   r\   rY   r   r     s-    :A
&
6D"D(+r\   r   c                  2    ] tR tRtRtR tR tR tR tRt	R# )	SimpleAgentProtocoli	  z
A L{Protocol} to be used with an L{client.Agent} to receive data.

@ivar finished: L{Deferred} firing when C{connectionLost} is called.

@ivar made: L{Deferred} firing when C{connectionMade} is called.

@ivar received: C{list} of received data.
c                	P    \        4       V n        \        4       V n        . V n        R # r~   )r   madefinishedreceivedrr   s   &rY   rs   SimpleAgentProtocol.__init__)	  s    J	 
r\   c                	<    V P                   P                  R 4       R # r~   )rD  r  rr   s   &rY   connectionMade"SimpleAgentProtocol.connectionMade.	  s    		4 r\   c                	<    V P                   P                  R 4       R # r~   )rE  r  )rX   reasons   &&rY   r  "SimpleAgentProtocol.connectionLost1	  s    t$r\   c                	<    V P                   P                  V4       R # r~   )rF  rv   rX   r  s   &&rY   dataReceived SimpleAgentProtocol.dataReceived4	  s    T"r\   )rE  rD  rF  N)
r]   r^   r_   r`   rz   rs   rI  r  rP  ra   rb   r\   rY   rB  rB  	  s    
!%#r\   rB  c                  4    ] tR tRtR tR tR tR tR tRt	R# )	 ContentDecoderAgentWithGzipTestsi8	  c                    V P                  4       V n        V P                  V P                  4      p\        P                  ! VR\        P
                  3.4      V n        R# )r     gzipN)r  r#  r%  r/   r"  GzipDecoderr$  r  s   & rY   r   &ContentDecoderAgentWithGzipTests.setUp9	  sJ     ))+--dll;//&BTBT8U7VW
r\   c                H  a aa	 S P                   P                  RR4      pS P                  P                  P	                  4       w  r#\
        P                  ! RR.RR./4      p\        4       p\        R	^RWE4      o	^S	n	        VP                  S	4       \        P                  ! ^\        P                  ^\        P                  ,           4      pVP                  R
4      VP                  R4      ,           VP!                  4       ,           oVV	V 3R lpVP#                  V4       V# )z
If the response has a C{gzip} I{Content-Encoding} header,
L{GzipDecoder} wraps the response to return uncompressed data to the
user.
r  r  r-  rw  r8  rU  r  c                  < SP                  V S4       SP                  V P                  R4       SP                  V P                  ^4       SP                  V P                  R4       SP                  \        V P                  P                  4       4      RR.3.4       SP                  V P                  \        4       SP                  \        \        V R4       SP                  SR,          4       SP                  SR,          4       SP                  4        \        4       pV P!                  V4       SP                  VP"                  R.4       \$        P&                  ! VP(                  VP*                  .4      # )	r  r  r0  rw  unknownr   :r   NNr  s
   xxxxxxyyyy)r  r   r  codephraser  r  r  r   rC   rF  AttributeErrorgetattr_bodyDataReceived_bodyDataFinishedrB  deliverBodyrF  r   gatherResultsrD  rE  )rx   r  r  r  rX   s   & rY   checkResponseQContentDecoderAgentWithGzipTests.test_gzipEncodingResponse.<locals>.checkResponseZ	  s(   ##FH5V^^_=V[[#.V]]E2V^^44676F8:L9M V]]N;ngvyI&&tBx0&&tBx0&&(*,Hx(X..1D0EF&&x7H7H'IJJr\   r  s   xxxxxxs   yyyy)r$  rw   r  rp   r   r1   rB   r%   r6   r   r  zlibcompressobjDEFLATED	MAX_WBITScompressr  rO  )
rX   r  rm  rn  r  rZ  
compressorrc  r  r  s
   f       @@rY   test_gzipEncodingResponse:ContentDecoderAgentWithGzipTests.test_gzipEncodingResponseA	  s     ::%%f.GH==))--/&&fX2WI>
 $%	OS%LX%%aT^^8KL
)!!(+, ! 		K* 	]+r\   c                  a aa	 S P                   P                  RR4      pS P                  P                  P	                  4       w  r#\
        P                  ! RR.RR./4      p\        4       p\        R^RWE4      o	^S	n	        VP                  S	4       RoVV	3R	 lpVP                  V4       S P                  V\        P                  4       V 3R
 lpVP                  V4      # )z
If the data received by the L{GzipDecoder} isn't valid gzip-compressed
data, the call to C{deliverBody} fails with a C{zlib.error}.
r  r  r-  rw  r8  rU  r  s   not gzipped contentc                \   < SP                  S4       V P                  \        4       4       R # r~   )r_  ra  r   )rx   r  r  s   &rY   rc  JContentDecoderAgentWithGzipTests.test_brokenContent.<locals>.checkResponse	  s!    &&t,xz*r\   c                   < V P                   ^ ,          P                  \        P                  4       SP	                  V P
                  \        4       R# )r  Nreasonsr   re  r0   rF  r  r6   r0   rX   s   &rY   checkFailureIContentDecoderAgentWithGzipTests.test_brokenContent.<locals>.checkFailure	  2    MM!!!$**-!!%..(;r\   r  )r$  rw   r  rp   r   r1   rB   r%   r6   r   r  rO  rL  r/   r7   )
rX   r  rm  rn  r  rZ  rc  rt  r  r  s
   f       @@rY   test_brokenContent3ContentDecoderAgentWithGzipTests.test_brokenContents	  s    
 ::%%f.GH==))--/&&fX2WI>
 $%	OS%LX%	+
 	]+8V%:%:;	< ##L11r\   c                  a a	  ! R R4      p\         P                  pV\         n        S P                  \        \         RV4       S P                  P                  RR4      pS P                  P                  P                  4       w  rE\        P                  ! RR./4      p\        4       p\        R	^RWg4      o	VP                  S	4       V	V 3R lpVP                  V4       V# )
z
When the connection with the server is lost, the gzip protocol calls
C{flush} on the zlib decompressor object to get uncompressed data which
may have been buffered.
c                  (    ] tR tRtR tR tR tRtR# )FContentDecoderAgentWithGzipTests.test_flushData.<locals>.decompressobji	  c                	    R # r~   rb   rX   wbitss   &&rY   rs   OContentDecoderAgentWithGzipTests.test_flushData.<locals>.decompressobj.__init__	  r   r\   c                	    R #    xrb   rO  s   &&rY   
decompressQContentDecoderAgentWithGzipTests.test_flushData.<locals>.decompressobj.decompress	      r\   c                	    R # )   yrb   rr   s   &rY   r  LContentDecoderAgentWithGzipTests.test_flushData.<locals>.decompressobj.flush	  r  r\   rb   Nr]   r^   r_   r`   rs   r  r  ra   rb   r\   rY   decompressobjr{  	  s    r\   r  r  r  r8  rU  r  c                  < SP                  R 4       SP                  4        \        4       pV P                  V4       SP	                  VP
                  RR.4       \        P                  ! VP                  VP                  .4      # s   datar  r  
r_  r`  rB  ra  r   rF  r   rb  rD  rE  rx   r  r  rX   s   & rY   rc  FContentDecoderAgentWithGzipTests.test_flushData.<locals>.checkResponse	  m    &&w/&&(*,Hx(X..t=&&x7H7H'IJJr\   r  )re  r  
addCleanupsetattrr$  rw   r  rp   r   r1   rB   r%   r6   r  rO  )
rX   r  oldDecompressObjr  rm  rn  r  rZ  rc  r  s
   f        @rY   test_flushData/ContentDecoderAgentWithGzipTests.test_flushData	  s    	 	  --*8HI::%%f.GH==))--/&&(;gY'GH#%	OS%LX	K 	]+r\   c                .  a a
  ! R R4      p\         P                  pV\         n        S P                  \        \         RV4       S P                  P                  RR4      pS P                  P                  P                  4       w  rE\        P                  ! RR./4      p\        4       p\        R
^RWg4      o
VP                  S
4       V
V 3R lpVP                  V4       S P                  V\         P"                  4       V 3R	 lp	VP                  V	4      # )z}
If the C{flush} call in C{connectionLost} fails, the C{zlib.error}
exception is caught and turned into a L{ResponseFailed}.
c                  (    ] tR tRtR tR tR tRtR# )GContentDecoderAgentWithGzipTests.test_flushError.<locals>.decompressobji	  c                	    R # r~   rb   r}  s   &&rY   rs   PContentDecoderAgentWithGzipTests.test_flushError.<locals>.decompressobj.__init__	  r   r\   c                	    R # r  rb   rO  s   &&rY   r  RContentDecoderAgentWithGzipTests.test_flushError.<locals>.decompressobj.decompress	  r  r\   c                	,    \         P                  ! 4       hr~   )re  r0   rr   s   &rY   r  MContentDecoderAgentWithGzipTests.test_flushError.<locals>.decompressobj.flush	  s    jjl"r\   rb   Nr  rb   r\   rY   r  r  	  s    #r\   r  r  r  r8  rU  r  c                  < SP                  R 4       SP                  4        \        4       pV P                  V4       SP	                  VP
                  RR.4       \        P                  ! VP                  VP                  .4      # r  r  r  s   & rY   rc  GContentDecoderAgentWithGzipTests.test_flushError.<locals>.checkResponse	  r  r\   c                   < V P                   ^,          P                  \        P                  4       SP	                  V P
                  \        4       R# r  rq  rs  s   &rY   rt  FContentDecoderAgentWithGzipTests.test_flushError.<locals>.checkFailure	  rv  r\   r  )re  r  r  r  r$  rw   r  rp   r   r1   rB   r%   r6   r  rO  rL  r/   r7   )rX   r  r  r  rm  rn  r  rZ  rc  rt  r  s   f         @rY   test_flushError0ContentDecoderAgentWithGzipTests.test_flushError	  s    	# 	#  --*8HI::%%f.GH==))--/&&(;gY'GH#%	OS%LX	K 	]+8V%:%:;	< ##L11r\   r  N)
r]   r^   r_   r`   r   rk  rw  r  r  ra   rb   r\   rY   rS  rS  8	  s    X0d2B*X/2r\   rS  c                  >    ] tR tRtRtR tR tR tR tR t	R t
R	tR
# )ProxyAgentTestsi	  z!
Tests for L{client.ProxyAgent}.
c                n    \         P                  ! \        V P                  RR4      V P                  4      # )z1
@return: a new L{twisted.web.client.ProxyAgent}
z	127.0.0.1rV  )r/   
ProxyAgentr   r#  rr   s   &rY   r  ProxyAgentTests.makeAgent	  s-       t||[$?
 	
r\   c                	   V P                  4       V n        \        P                  ! \	        V P                  R R4      V P                  4      V n        V P
                  P                  pV P                  W4      V P
                  n        R# )r  .  N)r  r#  r/   r  r   r$  _proxyEndpointr  )rX   oldEndpoints   & rY   r   ProxyAgentTests.setUp	  sb    ))+&&t||UD94<<

 jj//$($5$5k$H

!r\   c                ^    V P                  \        V P                  P                  RR4       R# )zW
L{ProxyAgent.request} raises L{TypeError} when the C{method} argument
isn't L{bytes}.
rC  rD  NrE  rr   s   &rY   rH  #ProxyAgentTests.test_nonBytesMethod
  rJ  r\   c           	     X   \         P                  ! RR./4      p\        4       pV P                  P	                  RRW4       V P
                  P                  P                  4       R,          w  r4pV P                  VR4       V P                  VR4       V P                  VP                  \        P                  4       V P                  pV P                  \        VP                  4      ^4       VP                  P                  4       w  rxV P                  V\         4       V P                  VP"                  R4       V P                  VP$                  R4       V P                  VP&                  \         P                  ! RR.RR	./4      4       V P)                  VP*                  V4       R
# )zv
L{client.ProxyAgent} issues an HTTP request against the proxy, with the
full URI as path, when C{request} is called.
r-  rw  r  r  rP  r  r  r;  r  N)r1   rB   r?  r$  rw   r#  r   r   r   rF  _wrappedFactoryr/   r@   r  r   rp   r>   r  r  r  rz  r=  )	rX   r  r  rn  ro  r  r  rm  rn  s	   &        rY   test_proxyRequest!ProxyAgentTests.test_proxyRequest
  sX   
 &&'9: x

6#EwU"ll5599;B?Gu%t$g55v7R7RS== 	X../3$$((*c7+V,"DEKK  &6(G>Q=R!ST	
 	S--t4r\   c                f    V P                  V P                  P                  P                  R4       R# )z:
C{ProxyAgent} connections are not persistent by default.
FN)r   r$  r  ru  rr   s   &rY   r&  "ProxyAgentTests.test_nonPersistent-
  s$     	))44e<r\   c                4  a a \        4       o ! VV 3R lR4      pV! 4       p\        P                  ! SS P                  VR7      pS P	                  W#P
                  4       VP                  RR4       S P                  VP
                  P                  R4       R# )z
When a connection is made by the C{ProxyAgent}, it uses its pool's
C{getConnection} method to do so, with the endpoint it was constructed
with and a key of C{("http-proxy", endpoint)}.
c                  .   < ] tR tRtRtRtV V3R ltRtR# )AProxyAgentTests.test_connectUsesConnectionPool.<locals>.DummyPooli;
  Fc                	   < R V n         SP                  VS4       SP                  VRS34       \        P                  ! \        4       4      # )Tz
http-proxy)r5  rz  r   r   r   rd   r6  s   &&&rY   rN  OProxyAgentTests.test_connectUsesConnectionPool.<locals>.DummyPool.getConnection?
  sD    !%$$R2   |X&>?}}%5%788r\   rb   Nr9  r0  s   rY   r:  r  ;
  s    IJ9 9r\   r:  r  r  r<  TN)	r,  r/   r  r#  rz  r  rw   r   r5  )rX   r:  r@  r$  r  s   f   @rY   r@  .ProxyAgentTests.test_connectUsesConnectionPool3
  sq     !?	9 	9 {!!(DLLtDT;;/fn-..5r\   r  N)r]   r^   r_   r`   rz   r  r   rH  r  r&  r@  ra   rb   r\   rY   r  r  	  s'    
IX5>=6r\   r  c                      ] tR tRt$ RtR]R&   R]R&   R]R&   R	 tR&R R lltR tR t	R t
R tR tR'R R lltR R ltR R ltR R ltR tR tR tR tR tR tR  tR! tR" tR# tR$ tR%tR
# )(_RedirectAgentTestsMixiniY
  zR
Test cases mixin for L{RedirectAgentTests} and
L{BrowserLikeRedirectAgentTests}.
rD   r$  r$   r#  rd   r  c                   V P                   P                  RR4      pV P                  P                  P	                  4       w  r#\
        P                  ! 4       p\        R^RVR4      pVP                  V4       V P                  ^ \        V P                  P                  4      4       V P                  V4      pV P                  WV4       V P                  VP                  R4       R# )zb
L{client.RedirectAgent} behaves like L{client.Agent} if the response
doesn't contain a redirect.
r  r  r  Nr  )r$  rw   r  rp   r   r1   rB   r6   r  r   r   r   rz  previousResponse)rX   r  rm  rn  r  r  rx   s   &      rY   test_noRedirect(_RedirectAgentTestsMixin.test_noRedirectc
  s    
 ::%%f.GH==))--/&&(OS%$GXC 6 678%%h/X.V44d;r\   Nc               0    V ^8  d   QhRRRRRRRRRRR	R
/# )rg   r[  intcrossSchemeboolcrossDomain	crossPortrequestHeaderszOptional[Headers]rh   r>   rb   )rj   s   "rY   rk   %_RedirectAgentTestsMixin.__annotate__u
  sF     < << < 	<
 < *< 
<r\   c                d   Rp\         e   RMRpVR8X  d   ^PMRpV P                  P                  RVR,           V,           R,           VR	7       V P                  P                  P                  4       R
,          w  rV P                  \        V	4       V P                  W4       V P                  P                  P                  4       w  rTpTpTpV'       d*   \         f   \        R4      hVR8X  d   RMRpV^P8X  d   RM^PpRpV'       d   RpRpV'       d   RMTpVR,           V,           V,           R,           p\        P                  ! RV./4      p\        RVRVR4      pVP                  V4       V P                  P                  P                  4       w  ppV P                  RVP                  4       V P                  RVP                   4       V P                  P                  P                  4       R
,          w  rT P                  V'       d   \"        M\        V	4       V P                  W4       V# )z
When getting a redirect, L{client.RedirectAgent} follows the URL
specified in the L{Location} header field and make a new request.

@param code: HTTP status code.
rW  Nr  r  rs  r  r  s   /foor/  :Nrg   Nz;Cross-scheme redirects can't be tested without TLS support.r\   i   s   :8443   example.net   /bar   locationr  r  )rK   r$  rw   r#  r   r   r   r   r  rp   r   r1   rB   r6   r  r  r  r   )rX   r[  r  r  r  r  startDomainstartScheme	startPortrn  ro  rm  rn  targetSchemetargetDomain
targetPort
portSyntaxlocationValuer  r  req2res2s   &&&&&&                rY   _testRedirectDefault-_RedirectAgentTestsMixin._testRedirectDefaultu
  s    %"%/hw%0Bc	

K&(;6@. 	 	
 \\,,00226
.)==))--/ #"
{Q  (3g'=87L )RRJ
J!J)4~+$v-<zIGS&&m_'EFOT5'4HX]]++//1
d-$((+\\,,00226
;NDQ*r\   c                (    V P                  R4       R# )z?
L{client.RedirectAgent} follows redirects on status code 301.
-  Nr  rr   s   &rY   test_redirect301)_RedirectAgentTestsMixin.test_redirect301
       	!!#&r\   c                ,    V P                  RRR7       R# )z9
L{client.RedirectAgent} follows cross-scheme redirects.
r  Tr  Nr  rr   s   &rY   test_redirect301Scheme/_RedirectAgentTestsMixin.test_redirect301Scheme
  s     	!! 	" 	
r\   c                (    V P                  R4       R# )z?
L{client.RedirectAgent} follows redirects on status code 302.
.  Nr  rr   s   &rY   test_redirect302)_RedirectAgentTestsMixin.test_redirect302
  r  r\   c                (    V P                  R4       R# )z?
L{client.RedirectAgent} follows redirects on status code 307.
3  Nr  rr   s   &rY   test_redirect307)_RedirectAgentTestsMixin.test_redirect307
  r  r\   c                (    V P                  R4       R# )z?
L{client.RedirectAgent} follows redirects on status code 308.
i4  Nr  rr   s   &rY   test_redirect308)_RedirectAgentTestsMixin.test_redirect308
  r  r\   c               $    V ^8  d   QhRRRRRR/# )rg   expectedHostHeaderr   crossKwargsr  rh   ri   rb   )rj   s   "rY   rk   r  
  s$     +
 +
"'+
IM+
	+
r\   c                   RR.RR.RR.RR.R	R
.RR./pRR./p\        / VCVC4      pV P                  RVR7      pR R lpV! VP                  4      pV P                  VRR./V! V4      C4       V P                  ! R/ VBR\        / VCVC4      /B p	V! V	P                  4      p
V P                  V
RV./V! \        V4      4      C4       R# )z^
L{client.RedirectAgent} scrubs sensitive headers when redirecting
between differing origins.
   authorizations   sensitive-authnzr  s   sensitive-cookie-data   cookie2s   sensitive-cookie2-data   proxy-authorizations   sensitive-proxy-auths   wWw-auThentiCates   sensitive-authns   x-custom-sensitives   sensitive-customs   x-random-headers   x-random-valuer  )r  c                    V ^8  d   QhRRRR/# )rg   r  rB   rh   zDict[bytes, Sequence[bytes]]rb   )rj   s   "rY   rk   D_RedirectAgentTestsMixin._sensitiveHeadersTest.<locals>.__annotate__
  s     	K 	K 	K-I 	Kr\   c                t    V P                  4        UUu/ uF  w  rVP                  4       VbK  	  upp# u uppi r~   )r  lower)r  r  vs   &  rY   normHeadersC_RedirectAgentTestsMixin._sensitiveHeadersTest.<locals>.normHeaders
  s1    /6/G/G/IJ/IVaAGGIqL/IJJJs   4r;  rW  r  N)r  )rB   r  r  r  )rX   r  r  sensitiveHeaderValuesotherHeaderValues
allHeaders
redirectedr  sameOriginHeadersredirectedElsewhereotherOriginHeaderss   &&,        rY   _sensitiveHeadersTest._RedirectAgentTestsMixin._sensitiveHeadersTest
  s@    230123"%<$="4!5!$7#8!
 02C1DEK 5K9JKL
..s:.N
	K (
(:(:;.)j)	
 #77 

 ##Q&;#Q?P#QR

 ))<)D)DE,-g&789	
r\   c                   V ^8  d   QhRR/# rf   rb   )rj   s   "rY   rk   r    s     X X Xr\   c                ,    V P                  RRR7       R# )z^
L{client.RedirectAgent} scrubs sensitive headers when redirecting
between differing domains.
Tr  )r  r  Nr  rr   s   &rY   test_crossDomainHeaders0_RedirectAgentTestsMixin.test_crossDomainHeaders  s    
 	""t"Wr\   c                   V ^8  d   QhRR/# rf   rb   )rj   s   "rY   rk   r    s     
 
t 
r\   c                ,    V P                  RRR7       R# )z\
L{client.RedirectAgent} scrubs sensitive headers when redirecting
between differing ports.
Ts   example.com:8443)r  r  Nr	  rr   s   &rY   test_crossPortHeaders._RedirectAgentTestsMixin.test_crossPortHeaders  s    
 	""/B 	# 	
r\   c                   V ^8  d   QhRR/# rf   rb   )rj   s   "rY   rk   r    s     5 5 5r\   c                *    V P                  RR7       R# )z^
L{client.RedirectAgent} scrubs sensitive headers when redirecting
between differing schemes.
Tr  Nr	  rr   s   &rY   test_crossSchemeHeaders0_RedirectAgentTestsMixin.test_crossSchemeHeaders  s    
 	""t"4r\   c                   V P                   P                  VR4       V P                  P                  P	                  4       w  r4\
        P                  ! RR./4      p\        RVRVR4      pVP                  V4       V P                  P                  P	                  4       w  rxV P                  RVP                  4       V P                  RVP                  4       R# )	z
L{client.RedirectAgent} changes the method to I{GET} when getting
a redirect on a non-I{GET} request.

@param code: HTTP status code.

@param method: HTTP request method.
r  r     http://example.com/barr  Nr  r  r  )r$  rw   r  rp   r   r1   rB   r6   r  r   r  r  )	rX   r[  r  rm  rn  r  r  r  r  s	   &&&      rY   _testRedirectToGet+_RedirectAgentTestsMixin._testRedirectToGet  s     	

6#<===))--/&&6O5P'QROT5'4HX]]++//1
-$((+r\   c                *    V P                  RR4       R# )zh
L{client.RedirectAgent} changes the method to I{GET} when getting a 303
redirect on a I{POST} request.
i/  ru  Nr  rr   s   &rY   test_redirect303)_RedirectAgentTestsMixin.test_redirect303-      
 	W-r\   c                   V P                   P                  RR4      pV P                  P                  P	                  4       w  r#\
        P                  ! 4       p\        RRRVR4      pVP                  V4       V P                  V\        P                  4      pVP                  P                  ^ ,          P                  \        P                   4       V P#                  RVP                  P                  ^ ,          P                  P$                  4       V P#                  RVP                  P&                  P(                  4       R# )z
If no L{Location} header field is found when getting a redirect,
L{client.RedirectAgent} fails with a L{ResponseFailed} error wrapping a
L{error.RedirectWithNoLocation} exception.
r  r  r  r  Nr  )r$  rw   r  rp   r   r1   rB   r6   r  r   r/   r7   r  rr  r   r0   RedirectWithNoLocationr   r  r  r[  )rX   r  rm  rn  r  r  fails   &      rY   test_noLocationField-_RedirectAgentTestsMixin.test_noLocationField4  s     ::%%f.GH==))--/&&(OS%$GX##Hf.C.CD

1""5#?#?@2DJJ4F4Fq4I4O4O4S4STdjj11667r\   c                   V P                   P                  VR4      pV P                  P                  P	                  4       w  rE\
        P                  ! 4       p\        RVRVR4      pVP                  V4       V P                  V\        P                  4      pVP                  P                  ^ ,          P                  \        P                   4       V P#                  RVP                  P                  ^ ,          P                  P$                  4       V P#                  WP                  P&                  P(                  4       R# )z
When getting a redirect on an unsupported request method,
L{client.RedirectAgent} fails with a L{ResponseFailed} error wrapping
a L{error.PageRedirect} exception.

@param code: HTTP status code.

@param method: HTTP request method.
r  r  Nr  )r$  rw   r  rp   r   r1   rB   r6   r  r   r/   r7   r  rr  r   r0   PageRedirectr   locationr  r[  )	rX   r[  r  r  rm  rn  r  r  r  s	   &&&      rY   _testPageRedirectFailure1_RedirectAgentTestsMixin._testPageRedirectFailureG  s     ::%%f.GH==))--/&&(OT5'4HX##Hf.C.CD

1""5#5#56%tzz'9'9!'<'B'B'K'K	
 	zz22778r\   c                *    V P                  RR4       R# )z
When getting a 307 redirect on a I{POST} request,
L{client.RedirectAgent} fails with a L{ResponseFailed} error wrapping
a L{error.PageRedirect} exception.
r  ru  Nr%  rr   s   &rY   test_307OnPost'_RedirectAgentTestsMixin.test_307OnPost`       	%%c73r\   c                n   V P                  V P                  4      p\        P                  ! V^4      pVP	                  RR4      pV P
                  P                  P                  4       w  rE\        P                  ! RR./4      p\        RRRVR4      pVP                  V4       V P
                  P                  P                  4       w  r\        RRRVR4      p
V	P                  V
4       V P                  V\        P                  4      pVP                  P                  ^ ,          P!                  \"        P$                  4       V P'                  RVP                  P                  ^ ,          P                  P(                  4       V P'                  RVP                  P*                  P,                  4       R# )	z
If the limit of redirects specified to L{client.RedirectAgent} is
reached, the deferred fires with L{ResponseFailed} error wrapping
a L{InfiniteRedirection} exception.
r  r  r  r  r  r  Nr  )r%  r#  r/   RedirectAgentrw   r  rp   r   r1   rB   r6   r  r   r7   r  rr  r   r0   InfiniteRedirectionr   r$  r  r[  )rX   r$  redirectAgentr  rm  rn  r  r  r  r  	response2r  s   &           rY   test_redirectLimit+_RedirectAgentTestsMixin.test_redirectLimith  sQ    --dll;,,UA6 ((1JK==))--/&&6O5P'QROS%$GX]]++//1
_c5'4H	i ##Hf.C.CD

1""5#<#<=%tzz'9'9!'<'B'B'K'K	
 	djj11667r\   c                   V P                   P                  RV4       V P                  P                  P	                  4       w  rE\
        P                  ! RV./4      p\        RRRVR4      pVP                  V4       V P                  P                  P	                  4       w  rV P                  RVP                  4       V P                  W8P                  4       R# )a  
When L{client.RedirectAgent} encounters a relative redirect I{URI}, it
is resolved against the request I{URI} before following the redirect.

@param uri: Request URI.

@param location: I{Location} header redirect URI.

@param finalURI: Expected final URI.
r  r  r  r  Nr  )r$  rw   r  rp   r   r1   rB   r6   r  r   r  r  )
rX   r  r$  finalURIrm  rn  r  r  r  r  s
   &&&&      rY   _testRedirectURI)_RedirectAgentTestsMixin._testRedirectURI  s     	

63'==))--/&&hZ'@AOS%$GX]]++//1
-#3#34r\   c                x    V P                  RRR4       V P                  RRR4       V P                  RRR4       R# )	zg
L{client.RedirectAgent} resolves and follows relative I{URI}s in
redirects, preserving query strings.
   http://example.com/foo/bars   bazs   http://example.com/foo/bazs   /bazs   http://example.com/baz   /baz?as   http://example.com/baz?aNr5  rr   s   &rY   test_relativeURI)_RedirectAgentTestsMixin.test_relativeURI  sJ    
 	)63P	
 	)74M	
 	)96Q	
r\   c                R    V P                  RRR4       V P                  RRR4       R# )z
L{client.RedirectAgent} resolves and follows relative I{URI}s in
redirects, preserving fragments in way that complies with the HTTP 1.1
bis draft.

@see: U{https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-22#section-7.1.2}
s   http://example.com/foo/bar#fragr9  s   http://example.com/baz?a#fragr8  s   /baz?a#frag2s   http://example.com/baz?a#frag2Nr:  rr   s   &rY   !test_relativeURIPreserveFragments:_RedirectAgentTestsMixin.test_relativeURIPreserveFragments  s4     	.,	

 	)-	
r\   c                R    V P                  RRR4       V P                  RRR4       R# )z
L{client.RedirectAgent} resolves and follows scheme relative I{URI}s in
redirects, replacing the hostname and port when required.
r8  s   //foo.com/bazs   http://foo.com/bazs   //foo.com:81/bazs   http://foo.com:81/bazNr:  rr   s   &rY   test_relativeURISchemeRelative7_RedirectAgentTestsMixin.test_relativeURISchemeRelative  s4    
 	)+;=R	
 	)+>@X	
r\   c                h   V P                  V P                  4      p\        P                  ! V4      pVP	                  RR4      pV P
                  P                  P                  4       w  rE\        P                  ! RR./4      p\        RRRVR4      pVP                  V4       V P
                  P                  P                  4       w  r\        R^RVR4      p
V	P                  V
4       V P                  V4      pV P                  VP                  V4       V P                  VP                  R4       R# )	zy
L{Response.response} references the previous L{Response} from
a redirect, or L{None} if there was no previous response.
r  r  r  r  r  r  Nr  )r%  r#  r/   r-  rw   r  rp   r   r1   rB   r6   r  r   rz  r  )rX   r$  r/  r  redirectReqredirectResr  redirectResponserm  rn  r  finalResponses   &           rY   test_responseHistory-_RedirectAgentTestsMixin.test_responseHistory  s   
 --dll;,,U3 ((1JK#'==#9#9#=#=#? &&6O5P'QR#OS%$O-.==))--/OS%$GX,,X6];;=MN->>Er\   rb   )FFFN)rW  )r]   r^   r_   r`   rz   __annotations__r  r  r  r  r  r  r  r  r
  r  r  r  r  r   r%  r)  r1  r5  r;  r>  rA  rH  ra   rb   r\   rY   r  r  Y
  s    
 M<$<|'
'''+
ZX
5,*.8&9248<5.

&

Fr\   r  c                  2    ] tR tRtRtR tR tR tR tRt	R# )	RedirectAgentTestsi  z$
Tests for L{client.RedirectAgent}.
c                f    \         P                  ! V P                  V P                  4      R.R7      # )z4
@return: a new L{twisted.web.client.RedirectAgent}
s   X-Custom-sensitivesensitiveHeaderNames)r/   r-  r%  r#  rr   s   &rY   r  RedirectAgentTests.makeAgent  s/     ##))$,,7"7!8
 	
r\   c                	Z    V P                  4       V n        V P                  4       V n        R # r~   r  rr   s   &rY   r   RedirectAgentTests.setUp       ))+^^%
r\   c                *    V P                  RR4       R# )z
When getting a 301 redirect on a I{POST} request,
L{client.RedirectAgent} fails with a L{ResponseFailed} error wrapping
a L{error.PageRedirect} exception.
r  ru  Nr(  rr   s   &rY   test_301OnPost!RedirectAgentTests.test_301OnPost  r+  r\   c                *    V P                  RR4       R# )z
When getting a 302 redirect on a I{POST} request,
L{client.RedirectAgent} fails with a L{ResponseFailed} error wrapping
a L{error.PageRedirect} exception.
r  ru  Nr(  rr   s   &rY   test_302OnPost!RedirectAgentTests.test_302OnPost  r+  r\   r  N)
r]   r^   r_   r`   rz   r  r   rU  rX  ra   rb   r\   rY   rL  rL    s    
&44r\   rL  c                  2    ] tR tRtRtR tR tR tR tRt	R# )	BrowserLikeRedirectAgentTestsi  z/
Tests for L{client.BrowserLikeRedirectAgent}.
c                f    \         P                  ! V P                  V P                  4      R.R7      # )z?
@return: a new L{twisted.web.client.BrowserLikeRedirectAgent}
s   x-Custom-sensitiverN  )r/   BrowserLikeRedirectAgentr%  r#  rr   s   &rY   r  'BrowserLikeRedirectAgentTests.makeAgent  s/     ..))$,,7"7!8
 	
r\   c                	Z    V P                  4       V n        V P                  4       V n        R # r~   r  rr   s   &rY   r   #BrowserLikeRedirectAgentTests.setUp   rS  r\   c                *    V P                  RR4       R# )s
L{client.BrowserLikeRedirectAgent} changes the method to I{GET} when
getting a 302 redirect on a I{POST} request.
r  ru  Nr  rr   s   &rY   test_redirectToGet3013BrowserLikeRedirectAgentTests.test_redirectToGet301$  r  r\   c                *    V P                  RR4       R# )rb  r  ru  Nr  rr   s   &rY   test_redirectToGet3023BrowserLikeRedirectAgentTests.test_redirectToGet302+  r  r\   r  N)
r]   r^   r_   r`   rz   r  r   rc  rf  ra   rb   r\   rY   r[  r[    s    
&..r\   r[  c                  $    ] tR tRtRtRtR tRtR# )AbortableStringTransporti3  zC
A version of L{StringTransport} that supports C{abortConnection}.
Fc                4    RV n         V P                  4        R# )z
A testable version of the C{ITCPTransport.abortConnection} method.

Since this is a special case of closing the connection,
C{loseConnection} is also called.
TN)abortingloseConnectionrr   s   &rY   abortConnection(AbortableStringTransport.abortConnection;  s     r\   )rk  N)r]   r^   r_   r`   rz   rk  rm  ra   rb   r\   rY   ri  ri  3  s    
 Hr\   ri  c                  6    ] tR tRtRt^tRtR]3R ltR t	Rt
R# )DummyResponseiF  al  
Fake L{IResponse} for testing readBody that captures the protocol passed to
deliverBody and uses it to make a connection with a transport.

@ivar protocol: After C{deliverBody} is called, the protocol it was called
    with.

@ivar transport: An instance created by calling C{transportFactory} which
    is used by L{DummyResponse.protocol} to make a connection.
r  Nc                F    Vf   \        4       pWn        V! 4       V n        R# )z
@param headers: The headers for this response.  If L{None}, an empty
    L{Headers} instance will be used.
@type headers: L{Headers}

@param transportFactory: A callable used to construct the transport.
N)rB   r  rZ  )rX   r  transportFactorys   &&&rY   rs   DummyResponse.__init__U  s     ?iG)+r\   c                \    Wn         V P                   P                  V P                  4       R# )z\
Record the given protocol and use it to make a connection with
L{DummyResponse.transport}.
Nr  r(  rZ  r^  s   &&rY   ra  DummyResponse.deliverBodyb  s    
 !$$T^^4r\   )r  r  rZ  )r]   r^   r_   r`   rz   r[  r\  ri  rs   ra  ra   rb   r\   rY   rp  rp  F  s#    	 DF#6N ,5r\   rp  c                       ] tR tRtRtR tRtR# )AlreadyCompletedDummyResponseik  z=
A dummy response that has already had its transport closed.
c                ~    Wn         V P                   P                  V P                  4       RV P                   n        R# )z1
Make the connection, then remove the transport.
Nru  r^  s   &&rY   ra  )AlreadyCompletedDummyResponse.deliverBodyp  s+     !$$T^^4"&r\   r  N)r]   r^   r_   r`   rz   ra  ra   rb   r\   rY   rx  rx  k  s    'r\   rx  c                  >    ] tR tRtRtR tR tR tR tR t	R t
R	tR
# )ReadBodyTestsiy  z
Tests for L{client.readBody}
c                L   \        4       p\        P                  ! V4      pVP                  P	                  R4       VP                  P	                  R4       VP                  P                  \        \        4       4      4       V P                  V P                  V4      R4       R# )zx
L{client.readBody} returns a L{Deferred} which fires with the complete
body of the L{IResponse} provider passed to it.
   first   second   firstsecondN)
rp  r/   readBodyr  rP  r  r)   r?   r   r   )rX   r  rQ  s   &  rY   test_successReadBodyTests.test_success~  sw    
 !?OOH%&&x0&&y1(()@A--a0.Ar\   c                    \        4       p\        P                  ! V4      pVP                  4        V P	                  V\
        P                  4       V P                  VP                  P                  4       R# )zo
When cancelling the L{Deferred} returned by L{client.readBody}, the
connection to the server will be aborted.
N)
rp  r/   r  r   r   r   r   r   rZ  rk  )rX   r  r  s   &  rY   test_cancelReadBodyTests.test_cancel  sQ    
 !???8,Xu';';<**334r\   c           	        \        4       p\        P                  ! V4      pVP                  P	                  R4       VP                  P	                  R4       VP                  P                  \        \        4       4      4       V P                  V4      pVP                  \        P                  4       V P                  RVP                  P                  RVP                  P                  RVP                  P                  /RRRRRR/4       R	# )
z
If the full body of the L{IResponse} passed to L{client.readBody} is
not definitely received, the L{Deferred} returned by L{client.readBody}
fires with a L{Failure} wrapping L{client.PartialDownloadError} with
the content that was received.
r~  r  statusr)  r  s   200r  r  N)rp  r/   r  r  rP  r  r)   r3   r   r   PartialDownloadErrorr   r  r  r)  r  )rX   r  rQ  failures   &   rY   test_withPotentialDataLoss(ReadBodyTests.test_withPotentialDataLoss  s     !?OOH%&&x0&&y1((1B1D)EF&&q)V001'--..7==00.. &5	
r\   c                n   \        4       p\        P                  ! V4      pVP                  P	                  R4       VP                  P                  \        \        R4      4      4       V P                  V4      pVP                  \        4       V P                  VP                  P                  R4       R# )z
If there is an exception other than L{client.PotentialDataLoss} while
L{client.readBody} is collecting the response body, the L{Deferred}
returned by {client.readBody} fires with that exception.
r~  mystery problemN)r  )rp  r/   r  r  rP  r  r)   r   r   r   r   r  r  )rX   r  rQ  rL  s   &   rY   test_otherErrorsReadBodyTests.test_otherErrors  s     !?OOH%&&x0((@Q1R)ST%%a(N#**,@Ar\   c                   a \        \        R7      oRSP                  n        V P	                  \
        R\        V3R l4      pVP                  4        V P                  V\        P                  4       R# )z
Calling L{client.readBody} with a transport that does not implement
L{twisted.internet.interfaces.ITCPTransport} produces a deprecation
warning, but no exception when cancelling.
)rr  NzLUsing readBody with a transport that does not have an abortConnection methodc                 0   < \         P                  ! S 4      # r~   )r/   r  )r  s   rY   r   8ReadBodyTests.test_deprecatedTransport.<locals>.<lambda>  s    FOOH-r\   )rp  r%   rZ  rm  assertWarnsr+  __file__r   r   r   r   )rX   rQ  r  s   & @rY   test_deprecatedTransport&ReadBodyTests.test_deprecatedTransport  s\     !/B-1*%-
 	

Q 4 45r\   c                    \        4       p\        P                  ! V4       V P                  4       pV P	                  \        V4      ^ 4       R# )z
Calling L{client.readBody} with a response that has already had its
transport closed (eg. for a very small request) will not trigger a
deprecation warning.
N)rx  r/   r  r*  r   r   )rX   r  r,  s   &  rY   !test_deprecatedTransportNoWarning/ReadBodyTests.test_deprecatedTransportNoWarning  s:     12!%%'X*r\   rb   N)r]   r^   r_   r`   rz   r  r  r  r  r  r  ra   rb   r\   rY   r|  r|  y  s'    
B	5
6B6$
+r\   r|  c                  (    ] tR tRtR tR tR tRtR# )HostnameCachingHTTPSPolicyTestsi  c                   \        4       p\        VR7      p\        V4      pVP                  RR4      pV P	                  VP
                  4       RVn        V P                  ^\        VP                  4      4       VP                  R4      pV P                  VP                  VP                  4       4       VP                  RR4       V P                  VP
                  4       R# )z
Verify that the connection creator is added to the
policy's cache, and that it is reused on subsequent calls
to creatorForNetLoc.

r1  r-  i5  FN)rS   r:   r<   r  r   rV   r  r   _cacher  r  rW   r3  rx  )rX   r2  wrappedPolicyr4  r5  r6  s   &     rY   test_cacheIsUsed0HostnameCachingHTTPSPolicyTests.test_cacheIsUsed  s     +,	1IF+M:))&$7	(() 	!S/033D9
i'')?)?)AB-))*r\   c                   \        4       p\        VR7      p\        V4      p\        ^ ^4       F6  pR\	        V4      ,           pVP                  VP                  R4      R4       K8  	  RpVP                  VP                  R4      R4       V P                  WcP                  4       V P                  ^\        VP                  4      4       RpVP                  VP                  R4      R4       RpV P                  WP                  4       V P                  ^\        VP                  4      4       V P                  WsP                  4       V P                  WcP                  4       \        ^4       F$  p	VP                  VP                  R4      R4       K&  	  R	p
VP                  V
P                  R4      R
4       V P                  RVP                  4       V P                  ^\        VP                  4      4       V P                  WP                  4       V P                  WsP                  4       V P                  WcP                  4       R# )z\
Verify that when the cache is full, and a new entry is added,
the oldest entry is removed.
r1  rn  r:  !  host05  newhost1new1i   host2NrS   r:   r<   r   strr  r`  r\  r  r  r   rG  )rX   r2  r  r4  r   r  r  hostnr  r  
hostNPlus1s   &          rY   test_cacheRemovesOldest7HostnameCachingHTTPSPolicyTests.test_cacheRemovesOldest  s   
 +,	1IF+M:q"AAH##HOOG$<dC 
 W 5s;e]]+"c&--01W 5s;."c&--01e]]+e]]+ rA##ELL$94@  

 1 1' :C@&--0"c&--01j--0e]]+e]]+r\   c                X   \        4       p\        VR7      p\        V^R7      p\        ^ ^4       F6  pR\	        V4      ,           pVP                  VP                  R4      R4       K8  	  RpV P                  WcP                  4       V P                  ^\        VP                  4      4       RpVP                  VP                  R4      R4       V P                  WcP                  4       V P                  ^\        VP                  4      4       V P                  WsP                  4       R	# )
zp
Verify that changing the cache size results in a policy that
respects the new cache size and not the default.

r1  )	cacheSizern  r:  r  r  r  r  Nr  )rX   r2  r  r4  r   r  firstr  s   &       rY   test_changeCacheSize4HostnameCachingHTTPSPolicyTests.test_changeCacheSize  s     +,	1IF+MQGq!AAH##HOOG$<dC  e]]+!S/0W 5s;.!S/0e]]+r\   rb   N)r]   r^   r_   r`   r  r  r  ra   rb   r\   rY   r  r    s    +(),V,r\   r  c                       ] tR tRtRtR tRtR# )RequestMethodInjectionTestsi7  z8
Test L{client.Request} against HTTP method injections.
c                `    \         P                  ! VR\        P                  ! 4       RR7       R# )r  r  Nr  r  r  r=  r/   r>   r1   rB   )rX   r  s   &&rY   r  =RequestMethodInjectionTests.attemptRequestWithMaliciousMethod?  s%     	) ((*		
r\   rb   Nr  rb   r\   rY   r  r  7      
r\   r  c                       ] tR tRtRtR tRtR# )"RequestWriteToMethodInjectionTestsiM  @
Test L{client.Request.writeTo} against HTTP method injections.
c                    \         P                  ! RR./4      p\        P                  ! RRVRR7      pWn        VP                  \        4       4       R# )r  r     twisted.invalidr  r  Nr  )r1   rB   r/   r>   r  writeTor%   )rX   r  r  rm  s   &&  rY   r  DRequestWriteToMethodInjectionTests.attemptRequestWithMaliciousMethodU  sM     &&2D1E'FGnn)	
 
O%&r\   rb   Nr  rb   r\   rY   r  r  M      'r\   r  c                       ] tR tRtRtR tRtR# )RequestURIInjectionTestsif  z5
Test L{client.Request} against HTTP URI injections.
c                `    \         P                  ! RV\        P                  ! 4       RR7       R# )zX
Attempt a request with the provided URI.

@param method: see L{URIInjectionTestsMixin}
r  Nr  r  r  s   &&rY   r  7RequestURIInjectionTests.attemptRequestWithMaliciousURIn  s%     	 ((*		
r\   rb   Nr  rb   r\   rY   r  r  f  r  r\   r  c                       ] tR tRtRtR tRtR# )RequestWriteToURIInjectionTestsi|  r  c                    \         P                  ! RR./4      p\        P                  ! RRVRR7      pWn        VP                  \        4       4       R# )z[
Attempt a request with the provided method.

@param method: see L{URIInjectionTestsMixin}
r  r  r  r  Nr  )r1   rB   r/   r>   r  r  r%   )rX   r  r  rm  s   &&  rY   r  >RequestWriteToURIInjectionTests.attemptRequestWithMaliciousURI  sM     &&2D1E'FGnn)	
 O%&r\   rb   Nr  rb   r\   rY   r  r  |  r  r\   r  )r  r  r  r  s   www-authenticate)rz   
__future__r   re  http.cookiejarr   ior   typingr   r   r   r   r	   r
   unittestr   r   zope.interface.declarationsr   zope.interface.verifyr   incrementalr   twisted.internetr   r   twisted.internet.addressr   r   twisted.internet.deferr   r   r   r  r   r   twisted.internet.errorr   r   r   twisted.internet.interfacesr   twisted.internet.protocolr   r   twisted.internet.taskr    $twisted.internet.test.test_endpointsr!   twisted.internet.testingr"   r#   r$   r%   twisted.loggerr&   twisted.python.componentsr'   twisted.python.deprecater(   twisted.python.failurer)   twisted.test.iosimr*   r+   twisted.test.test_sslverifyr,   twisted.trial.unittestr-   r.   twisted.webr/   r0   r1   twisted.web._newclientr2   r3   r4   r5   r6   r7   r8   rU  r9   r:   r;   r<   r=   r>   r?   r@   twisted.web.errorrA   twisted.web.http_headersrB   rI  rC   rD   rE   rF   rG   rH   !twisted.web.test.injectionhelpersrI   rJ   testMixinClassr?  runtimeTestCaserK   _sslr  twisted.internet._sslverifyrL   rM   twisted.internet.sslrN   twisted.protocolsrO   twisted.protocols.tlsrP   rQ   rS   ImportErrorrd   r|   r   r   r   r   r   r   r   r   r,  r2  r7  r=  r  r  r  r	  r  r  r  rR  rs  r  r  r  r  r  r   rB  rS  r  SENSITIVE_HEADERSr  rL  r[  ri  rp  rx  r|  r  r  r  r  r  rb   r\   rY   <module>r     s   #  $  G G % 3 .  ( = D D K 
 H 7 ' N  . 7 @ * 4 I @ 3 3  	 	 	 1 ,  NONO#,
 CJO8%O"## # $#x 2% %]&H ]&@  
P! P!f! !G G 7  jVh(B jVZ		@ 	@u
 u
p "#0 0 $0$Y)(/;RY)x44(44( J@AX
h :<S X
 BX
v?U8 ?UDy,8-G y,x! !2;
X/ ;
|h2 :Oh2V + x ~+x)C_ ~+B#( #4w2x1K w2t[6h :O [6| IF~ IFX%4	%4P#.	#.L &"5 "5J'M 'a+H a+H J@AV,h V, BV,r

,''2

,''h  
CJs   )M   M/.M/