ϪfdZddlmZddlZddlmZddlmZddlm Z m Z m Z m Z m Z mZddlmZmZddlmZdd lmZdd lmZdd lmZmZdd lmZmZdd lmZm Z m!Z!ddl"m#Z#m$Z$ddl%m&Z&m'Z'm(Z(ddl)m*Z*ddl+m,Z,m-Z-ddl.m/Z/ddl0m1Z1ddl2m3Z3m4Z4m5Z5m6Z6ddl7m8Z8ddl9m:Z:ddl;mZ>ddl?m@Z@mAZAddlBmCZCddlDmEZEmFZFddlGmHZHmIZImJZJddlKmLZLmMZMmNZNmOZOmPZPmQZQmRZRddlSmTZTmUZUmVZVmWZWmXZXmYZYmZZZm[Z[ddl\m]Z]dd l^m_Z_dd!l`maZambZbmcZcmdZdmeZemfZfdd"lgmhZhmiZie reFZjekZlnekZjeFZl dd#lmmZnenZmd$Zodd%lpmqZqmrZrdd&lsmtZtdd'lumvZvdd(lwmxZxmyZyeerGd)d*ZzGd,d-e-Z|Gd.d/Z}Gd0d1eFZ~d2Zd3Zd4Zd5Zd6Zd7ZGd8d9ZGd:d;ZGd<d=ZGd>d?e,ZGd@dAeFeZGdBdCZGdDdEZeecGdFdGZGdHdIeFeeeZGdJdKeeheEZGdLdMeeieEZeeo dNGdOdPeFeeZGdQdReFZGdSdTeFeZGdUdVZGdWdXeFeZGdYdZeFeeeZGd[d\e:efZGd]d^eZGd_d`eFeeZGdadbe-ZGdcddeFeZGdedfeFeeZgdgZGdhdiejZGdjdkeeeelZGdldmeeeelZGdndoe6ZGdpdqZGdrdseZGdtdueFZeeo dNGdvdweFZGdxdyeheEZGdzd{eheEZGd|d}eieEZGd~deieEZy#e{$rdZmd+ZoYwxYw)zD Tests for L{twisted.web.client.Agent} and related new client APIs. ) annotationsN) CookieJar)BytesIO) TYPE_CHECKINGDictListOptionalSequenceTuple)SkipTestskipIf implementer) verifyObject)Version)defertask) IPv4Address IPv6Address)CancelledErrorDeferredsucceed)HostnameEndpointTCP4ClientEndpoint)ConnectionDoneConnectionLostConnectionRefusedError)IOpenSSLClientConnectionCreator)FactoryProtocol)Clock)deterministicResolvingReactor)AccumulatingProtocolEventLoggingObserverMemoryReactorClockStringTransport)globalLogPublisher)proxyForInterface)getDeprecationWarningString)Failure) FakeTransportIOPump)!certificatesForAuthorityAndServer)SynchronousTestCaseTestCase)clienterror http_headers)HTTP11ClientProtocolPotentialDataLossRequestNotSentRequestTransmissionFailedResponseResponseFailedResponseNeverReceived)URIBrowserLikePolicyForHTTPSFileBodyProducerHostnameCachingHTTPSPolicyHTTPConnectionPoolRequest ResponseDone_HTTP11ClientFactory)SchemeNotSupported)Headers)UNKNOWN_LENGTHIAgentIAgentEndpointFactory IBodyProducerIPolicyForHTTPS IResponse)MethodInjectionTestsMixinURIInjectionTestsMixin)sslT)ClientTLSOptionsIOpenSSLTrustRoot)optionsForClientTLS)tls)TLSMemoryBIOFactoryTLSMemoryBIOProtocolceZdZdZdZdZy)CustomOpenSSLTrustRootFNc d|_||_yNT)calledcontext)selfrXs =/usr/lib/python3/dist-packages/twisted/web/test/test_agent.py_addCACertsToContextz+CustomOpenSSLTrustRoot._addCACertsToContextmsDK"DL)__name__ __module__ __qualname__rWrXr[r\rZrTrThs #r\rTFceZdZdZddZdZy)StubHTTPProtocolaR 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 g|_d|_y)N QUIESCENT)requestsstaterYs rZ__init__zStubHTTPProtocol.__init__|sCE   r\cTt}|jj||f|S)z Capture the given request for later inspection. @return: A L{Deferred} which this code will never fire. )rreappend)rYrequestresults rZrkzStubHTTPProtocol.requests'  gv./ r\NreturnNone)r]r^r___doc__rhrkr`r\rZrbrbrs!r\rbceZdZdZdZy) FileConsumerc||_yN) outputFile)rYrus rZrhzFileConsumer.__init__s $r\c:|jj|yrt)ruwrite)rYbytess rZrwzFileConsumer.writes e$r\N)r]r^r_rhrwr`r\rZrrrrs %%r\rrcdeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZy)FileBodyProducerTestszq Tests for the L{FileBodyProducer} which reads bytes from a file and writes them to an L{IConsumer}. cdS)al 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. cyrVr`r`r\rZz4FileBodyProducerTests._termination..r\r`rgs rZ _terminationz"FileBodyProducerTests._terminations r\cg|_tj|j|jj|_y)z Create a L{Cooperator} hooked up to an easily controlled, deterministic scheduler to use with L{FileBodyProducer}. N) _scheduledr Cooperatorrrj cooperatorrgs rZsetUpzFileBodyProducerTests.setUps- //$*;*;T__=S=STr\c f|jtttt dy)zI L{FileBodyProducer} instances provide L{IBodyProducer}. r\N) assertTruerrGr<rrgs rZtest_interfacez$FileBodyProducerTests.test_interfaces!  ]4DWS\4RSTr\cGdd}Gdd}t|}|jt|jt|}|jt|jy)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}. ceZdZdZy)9FileBodyProducerTests.test_unknownLength..HasSeekcyrtr`)rYoffsetwhences rZseekz>FileBodyProducerTests.test_unknownLength..HasSeek.seekr\N)r]r^r_rr`r\rZHasSeekr r\rceZdZdZy)9FileBodyProducerTests.test_unknownLength..HasTellcyrtr`rgs rZtellz>FileBodyProducerTests.test_unknownLength..HasTell.tellrr\N)r]r^r_rr`r\rZHasTellrrr\rN)r< assertEqualrDlength)rYrrproducers rZtest_unknownLengthz(FileBodyProducerTests.test_unknownLengthsX    $GI. 9#GI. 9r\cd}t|}|jdt|}|jt |dz |j |j|j dy)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. shere are some bytesN)rrr<rlenrr)rY inputBytes inputFilers rZtest_knownLengthz&FileBodyProducerTests.test_knownLengths] , J' q#I. Z1,hoo> )1-r\cttd}|jtj|j y)zw If no L{Cooperator} instance is passed to L{FileBodyProducer}, the global cooperator is used. r\N)r<rrr cooperate _cooperate)rYrs rZtest_defaultCooperatorz,FileBodyProducerTests.test_defaultCooperators, $GCL1 )<)<=r\cd}d}t}t|}tt||j|}|j |}t t ||zdzD]"}|jjd$|jg|j|j||j|jd|j|y)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, worldrN) rrrr<rstartProducingrangerrpoprgetvaluesuccessResultOf)rYexpectedResultreadSizeoutputconsumerrcompleteis rZtest_startProducingz)FileBodyProducerTests.test_startProducings )'#GN$;T__hW**84s>*h6:; %A "DOO   " $ % T__- ):; t33H=>r\cLd}d}t|}t||j|}tt}|j |t t ||zdzD]"}|jjd$|j|jy)z When L{FileBodyProducer} reaches end-of-file on the input file given to it, the input file is closed. ssome friendly bytesrN) rr<rrrrrrrrrclosed)rYrrrrrrs rZtest_inputClosedAtEOFz+FileBodyProducerTests.test_inputClosedAtEOFs + J' #ItI *)s:(2Q67 %A "DOO   " $ %  (()r\cGdd}t||j}|jtt }|j j d|j|jty)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. ceZdZdZy)GFileBodyProducerTests.test_failedReadWhileProducing..BrokenFilectd)NzSimulated bad thing)OSError)rYcounts rZreadzLFileBodyProducerTests.test_failedReadWhileProducing..BrokenFile.reads344r\N)r]r^r_rr`r\rZ BrokenFilers 5r\rrN) r<rrrrrrrfailureResultOftrapIOError)rYrrrs rZtest_failedReadWhileProducingz3FileBodyProducerTests.test_failedReadWhileProducingsg 5 5$JL$//B**< +BCA  X&++G4r\cd}d}t}t|}t|}t||j|}|j |}|j |j |j|jjd|jd|j|j|y)z When the L{Deferred} returned by L{FileBodyProducer.startProducing} is cancelled, the input file is closed and the task is stopped. rrrr\N) rrrr<rrcancelrrrrrrassertNoResultrYrrrrrrrs rZtest_cancelWhileProducingz/FileBodyProducerTests.test_cancelWhileProducing s )'N+ #ItI**84  (()A  foo/0 H%r\cd}d}t}t|}t|}t||j|}|j |}|j |j |j|jjd|jd|j|j|y)a 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. rrrr\N rrrr<rr stopProducingrrrrrrrrs rZtest_stopProducingz(FileBodyProducerTests.test_stopProducings)'N+ #ItI**84   (()A  foo/0 H%r\cd}d}t}t|}tt||j|}|j |}|j j d|j|j|dd|j|j j d|j|j|dd|jg|j |j|y)z L{FileBodyProducer.pauseProducing} temporarily suspends writing bytes from the input file to the given L{IConsumer}. rrrN) rrrr<rrrrrrpauseProducingr)rYrrrrrrs rZtest_pauseProducingz)FileBodyProducerTests.test_pauseProducing2s )'#GN$;T__hW**84A  *N2A,>?! A  *N2A,>? T__- H%r\cd}d}t}t|}tt||j|}|j ||j j d|j|d||j|j|j|j j d|j|d|dz|jy)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}. rrrNr) rrrr<rrrrrrrresumeProducing)rYrrrrrs rZtest_resumeProducingz*FileBodyProducerTests.test_resumeProducingLs )'#GN$;T__hW)A   2FOO4EF!  "A  (Q,79JKr\cd}d}t}t|}t|}t||j|}|j |}|j |j |j |j|jjd|jd|j|j|y)zv L{FileBodyProducer.stopProducing} can be called more than once without raising an exception. stestrrr\Nrrs rZtest_multipleStopz'FileBodyProducerTests.test_multipleStop_s !'N+ #ItI**84    (()A  foo/0 H%r\N)r]r^r_rprrrrrrrrrrrrrrr`r\rZrzrzsP UU :( .>?$ *5"&$&(&4L&&r\rz 127.0.0.7::7z 127.0.0.8z 127.0.0.9z 127.0.0.10z 127.0.0.11c6eZdZdZdZGddZdZdZy)FakeReactorAndConnectMixinz A test mixin providing a testable C{Reactor} class and a dummy C{connect} method which allows instances to pretend to be endpoints. c t}t|tgtgtgt gt gtgdgdgd}|j|_|j|_ |S)af 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. rr) example.comzipv6.example.comz example.netz example.orgfoozfoo.comrr)hostMap) r%r"EXAMPLE_COM_IPEXAMPLE_COM_V6_IPEXAMPLE_NET_IPEXAMPLE_ORG_IP FOO_LOCAL_IP FOO_COM_IP tcpClientsadvance)rYmrcdrrs rZ createReactorz(FakeReactorAndConnectMixin.createReactorsg!"+  ./%6$7 ./ ./$~&<)]w    kk  r\ceZdZdZdZdZy)'FakeReactorAndConnectMixin.StubEndpointz Endpoint that wraps existing endpoint, substitutes StubHTTPProtocol, and resulting protocol instances are attached to the given test case. c|_|_d}t|tj_t _fdj_y)Ncy)zthis function does nothingNr`r`r\rZnothingzAFakeReactorAndConnectMixin.StubEndpoint.__init__..nothingr~r\cjSrt)protocol)addrrYs rZr}zBFakeReactorAndConnectMixin.StubEndpoint.__init__..s dmmr\)endpointtestCaserAreprfactoryrbr buildProtocol)rYrrrs` rZrhz0FakeReactorAndConnectMixin.StubEndpoint.__init__sE$DM$DM 10dmm9LMDL,.DM)CDLL &r\c|j|j_|jj|jt |jSrt)rrrconnectrr)rYignoredFactorys rZrz/FakeReactorAndConnectMixin.StubEndpoint.connects7%)]]DMM " MM ! !$,, /4==) )r\N)r]r^r_rprhrr`r\rZ StubEndpointrs D *r\rcbtj|}|jfd|_|S)z Return an Agent suitable for use in tests that wrap the Agent and want both a fake reactor and StubHTTPProtocol. c.j|Srt)r)args_oldGetEndpointrYs rZr}zEFakeReactorAndConnectMixin.buildAgentForWrapperTest..s   ot4d ;r\)r0Agent _getEndpoint)rYreactoragentrs` @rZbuildAgentForWrapperTestz3FakeReactorAndConnectMixin.buildAgentForWrapperTests/  W%,,  r\c\t}|jd||_t|S)z Fake implementation of an endpoint which synchronously succeeds with an instance of L{StubHTTPProtocol} for ease of testing. N)rbmakeConnectionrrrYrrs rZrz"FakeReactorAndConnectMixin.connects, $%%  x  r\N)r]r^r_rprrrrr`r\rZrr{s  >**,  !r\rceZdZdZdZy) DummyEndpointz1 An endpoint that uses a fake transport. cl|jd}|jtt|Srtrrr&rrs rZrzDummyEndpoint.connects.((. 12x  r\Nr]r^r_rprr`r\rZrrs !r\rceZdZdZdZy) BadEndpointz/ An endpoint that shouldn't be called. ctd)Nz(This endpoint should not have been used.) RuntimeError)rYrs rZrzBadEndpoint.connectsEFFr\Nr r`r\rZr r s Gr\r ceZdZdZdZeZy) DummyFactoryz/ Create C{StubHTTPProtocol} instances. cyrtr`)rYquiescentCallbackmetadatas rZrhzDummyFactory.__init__s r\N)r]r^r_rprhrbrr`r\rZrrs  Hr\rcXeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd Zy)HTTPConnectionPoolTestsz4 Tests for the L{HTTPConnectionPool} class. c|j|_t|j|_t|j_d|j_yNF)r fakeReactorr>poolr_factoryretryAutomaticallyrgs rZrzHTTPConnectionPoolTests.setUps=--/&t'7'78 ) ', $r\cjjjifd}d}jj|t }|j |S)z{ If there are no cached connections, L{HTTPConnectionPool.getConnection} returns a new connection. cj|tj|jjj yrt)assertIsInstancerb assertNotInr _connectionsvalues)connrYs rZ gotConnectionzMHTTPConnectionPoolTests.test_getReturnsNewIfCacheEmpty..gotConnections7  ! !$(8 9   T499#9#9#@#@#B Cr\/)rrr! getConnectionr addCallback)rYr$ unknownKeyds` rZtest_getReturnsNewIfCacheEmptyz6HTTPConnectionPoolTests.test_getReturnsNewIfCacheEmptysS //4 D  II # #J  @}}]++r\c`t}|jt|jj d||j |j jd|j||jjd|jjd|j |j jd|j||jjd|j||jj|jjd|j |j jd|j||jjd|j||jjy)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. http example.comPFg?TN)rbrr&r_putConnectionr transport disconnectingassertInr!rr _timeoutsr rYrs rZtest_putStartsTimeoutz-HTTPConnectionPoolTests.test_putStartsTimeout sB$% 12   !=xH ++995A h 6 67S TU   % ++995A h 6 67S TU h 3 34   % ++994@ 499#9#9:V#WX 499#6#67r\cN|j}ttg}|D]-}|jt|j d|/|j |j d||jj}t}|jt|j d||j d}|j t|d|j ||d|g|j |Dcgc]}|jjc}ddg|j |djjd|j||dj|j|d|jycc}w)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. r,rrFrTN)rrbrr&r1rr!r5copyrr2r3r cancelledr )rYr origCachedptimeouts newProtocol newCacheds rZtest_putExceedsMaxPersistentz4HTTPConnectionPoolTests.test_putExceedsMaxPersistent%sr yy'(*:*<=  AA  _. /    >&&('( ""?#45 8+F%%&BC  Y+ Z]K$@A YG!++33G%QVX A00>>E A/99: A7HsF"cfd}g}|j|ddd|j|ddd|ddd|dddjjjd|jt jjd d jt jjd d y ) z C{maxPersistentPerHost} is enforced per C{(scheme, host, port)}: different keys have different max connections. ct}|jtjj |||f||Srt)rbrr&rr1)schemehostportr<rYs rZ addProtocolzFHTTPConnectionPoolTests.test_maxPersistentPerHost..addProtocolIs< "A  _. / II $ $fdD%91 =Hr\r-r.r/httpswww2.example.comr,)rGr.rHr)r-rIr/N)rjrrr!r)rYrF persistents` rZtest_maxPersistentPerHostz1HTTPConnectionPoolTests.test_maxPersistentPerHostCs    +fnbAB+fnbABG^S1F/4  II " "#? @*  TYY334RSTVWX   &&'HI JA r\ctjtjj dfd}jj dt j|S)z Getting an address which has a cached connection returns the cached connection, removes it from the cache and cancels its timeout. r,cJj|j|jjdjj dj |jjdj|jjy)Nr,F) assertIdenticalr rr!rrrr2r3r5)r#rrYs rZr$zGHTTPConnectionPoolTests.test_getCachedConnection..gotConnectiongs{  4 0   T499#9#9:V#W X    $ $S )   T^^995 A   T499#6#6 7r\)rbrr&rr1r&r r')rYr$rs` @rZtest_getCachedConnectionz0HTTPConnectionPoolTests.test_getCachedConnection]se $% 12   !=xH 8yy&& ( M  +m $ %r\ctjtdjj fd}jj t }|j|S)zR The pool's C{_newConnection} method constructs a new connection. r%cj|jjjj |jjj yrt)assertNotIdenticalr4rr!r r") newConnectionkeyrrYs rZr$zAHTTPConnectionPoolTests.test_newConnection..gotConnectionsS  # #Hm < MM(DII$:$:3$? @   ]DII,B,B,I,I,K Lr\)rbrr&rr1_newConnectionrr')rYr$r)rUrs` @@rZtest_newConnectionz*HTTPConnectionPoolTests.test_newConnectionusf $% 12   h/ M II $ $S-/ :}}]++r\c"|j}d}ttg}|D]-}|jt|j ||/|j |j ||d|d_g}|jj|tj|j|j|d|d|j |j |g|j |jiy)z{ When getting connections out of the cache, disconnected connections are removed and not returned. r, DISCONNECTEDrrN)rrbrr&r1rr!rfr&r r'rjrOr5)rYrrUr;r<rls rZtest_getSkipsDisconnectedz1HTTPConnectionPoolTests.test_getSkipsDisconnecteds yy*'(*:*<=  (A  _. /   Q ' ( **3/<- 1  []3?? N VAY 1 6 **3/4 ,r\c(t}|j|jdtj|t }d|_|j jd||jdt||d}|d}|j|jt|j|jd|jd|j jj!d|j#ty) ze If a non-quiescent connection is put back in the cache, an error is logged. rd NOTQUIESCENTr,rr log_failurez5BUG: Non-quiescent protocol added to connection pool.N)rbrrfr$createWithCleanupr'rr1 assertEqualsrrvaluergetErrorMessagerOr!getflushLoggedErrors)rYr logObservereventfs rZtest_putNotQuiescentz,HTTPConnectionPoolTests.test_putNotQuiescents $% 5*<.StringEndpointcl|jd}|jtt|Srtr )rYrr<s rZrzUHTTPConnectionPoolTests.test_getUsesQuiescentCallback..StringEndpoint.connects-))$/  !23qz!r\Nr]r^r_rr`r\rZStringEndpointrjs "r\rmTFza keyrrdN) r>rrr&r'rjrr3_state_quiescentCallbackrO)rYrmrrlrUrresult2s rZtest_getUsesQuiescentCallbackz5HTTPConnectionPoolTests.test_getUsesQuiescentCallbacks " " "$"2"2D9"' 3 01==fmmL!9 h(<=&##H-  3 01==gnnM WQZ2r\cgfd}|ddd|dddjj}D](}j|jjd*jjj ij jD]}j|jd jjjig}|j|jj|gdjttj|gdjttj|d gy ) 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. ct}|jtjj |||f|j |yrt)r3rr&rr1rj)rCrDrEr<rJrYs rZrFzHHTTPConnectionPoolTests.test_closeCachedConnections..addProtocolsE$&A  _. / II $ $fdD%91 =   a r\r-r.r/rITrrN)rcloseCachedConnectionsrr2r3r!rgetDelayedCallsr:r5r'rjconnectionLostr*r)rYrF doneDeferredr<dcrlrJs` @rZtest_closeCachedConnectionsz3HTTPConnectionPoolTests.test_closeCachedConnectionssL   ! FNB/F/4yy779  >A   Q[[66 = > //4""224 1B   R\\4 0 1 ,,b1  / $1 $$W^-=%>? $1 $$W^-=%>? $(r\c>|j|jjitGfdd}|jj d|}|j |j|j jty)z Cancelling the C{Deferred} returned from L{HTTPConnectionPool.getConnection} cancels the C{Deferred} returned by opening a new connection with the given endpoint. ceZdZfdZy)XHTTPConnectionPoolTests.test_cancelGetConnectionCancelsEndpointConnect..EndpointcSrtr`)rYrconnectionResults rZrz`HTTPConnectionPoolTests.test_cancelGetConnectionCancelsEndpointConnect..Endpoint.connects ''r\Nrl)r~srZEndpointr|s (r\ri90N) rrr!rr&rrtyper)rYrr)r~s @rZ.test_cancelGetConnectionCancelsEndpointConnectzFHTTPConnectionPoolTests.test_cancelGetConnectionCancelsEndpointConnectsv //4#: ( ( II # #E8: 6   --.>?DDnUr\N)r]r^r_rprr*r7r@rKrPrWrZrgrqryrr`r\rZrrsF-, 888< 4%0,*-8-6!3F")HVr\rceZdZdZdZy)AgentTestsMixinz1 Tests for any L{IAgent} implementation. c^|jtt|jy)z6 The agent object provides L{IAgent}. N)rrrE makeAgentrgs rZrzAgentTestsMixin.test_interfaces  VT^^-=>?r\N)r]r^r_rprr`r\rZrrs @r\rcLeZdZdZdZdZdZdZdejdfdZ y ) IntegrationTestingMixinzG Transport-to-Agent integration tests for both HTTP and HTTPS. c:|jdtty)z+ L{Agent} works over IPv4. r.N)integrationTestrrrgs rZtest_integrationTestIPv4z0IntegrationTestingMixin.test_integrationTestIPv4+s ^^[Ir\c2|jddty)zL L{Agent} works over IPv4 when hostname is an IPv4 address. s 127.0.0.7rN)rrrgs rZtest_integrationTestIPv4Addressz7IntegrationTestingMixin.test_integrationTestIPv4Address1s \; Dr\c:|jdtty)z+ L{Agent} works over IPv6. sipv6.example.comN)rrrrgs rZtest_integrationTestIPv6z0IntegrationTestingMixin.test_integrationTestIPv67s 02C[Qr\c2|jddty)zL L{Agent} works over IPv6 when hostname is an IPv6 address. s[::7]rN)rrrgs rZtest_integrationTestIPv6Addressz7IntegrationTestingMixin.test_integrationTestIPv6Address=s Xuk:r\c|Srtr`)server_s rZr}z IntegrationTestingMixin.Hsr\httpc |jtr|jtdfd|}|j d|dz|zdz}j d\} } } } } |j | ||d| | }| j|}t|d| }|j|tjfd d _ d _ |jd }t|d }|j|t||||d }|j|j!|jj"j%d}|j'|dj)d|dt+|dd Dcgc]}|s|j%ddc}}|j |d||j!|jj,j/d|j|j1|}|j3|j4j7dddy cc}w)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_clockcSrtr`)rsrZr}z9IntegrationTestingMixin.integrationTest..ms'r\GET:///rTCPF) peerAddressc*t}|_|Srt)r#currentProtocol)ap accumulators rZrz.accumulatorws%'B*,K 'Ir\NT)clocks s GET / HTTPrs: HostsLHTTP/1.1 200 OK X-An-Header: an-value Content-length: 12 hello world!s x-an-headersan-value)r sslPresentpatchrPrkrrrr+rr forProtocolrprotocolConnectionMader,flushrdatasplitr startswithdictr2rwrr_headers getRawHeaders)rYhostNameexpectedAddress addressType serverWrapper createAgentrCrdeferredrDrErtimeoutbindrclientProtocolclientTransportwrapperserverTransportpumplineslinerresponserrs @@rZrz'IntegrationTestingMixin.integrationTestCs8L$$&  JJs0/ BG$==&8)Cd)JK-4-?-?-B*dGWd /!%t4  ..{;';W%%o6       '+ #-1 * W5CCDI'6/         H%++0066w? a++M:E!HEqrKd 5!,KL )84 H%##--33  ''1     * *> :1 ={ Ls I$IN) r]r^r_rprrrrr0rrr`r\rZrr&s3J E R ;/LLX r\rceZdZdZdZy)StubEndpointFactoryz= A stub L{IAgentEndpointFactory} for use in testing. cH|j|j|jfS)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} )rCrDrErYuris rZendpointForURIz"StubEndpointFactory.endpointForURIs CHHchh//r\N)r]r^r_rprr`r\rZrrs  0r\rceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZee ddZdZee ddZdZdZdZ dZ!dZ"d Z#y!)" AgentTestszA Tests for the new HTTP client API provided by L{Agent}. c@tj|jS)zE @return: a new L{twisted.web.client.Agent} instance )r0rrrgs rZrzAgentTests.makeAgents||DLL))r\cX|j|_|j|_yC Create an L{Agent} wrapped around a fake reactor. Nrrrrrgs rZrzAgentTests.setUps"))+ ^^% r\c.tj|j}|j|jt |j |jjd|j|j|jjy)zV If no pool is passed in, the L{Agent} creates a non-persistent pool. FN) r0rrr_poolr>rrJrO_reactorrYrs rZtest_defaultPoolzAgentTests.test_defaultPoolsc T\\* ekk+=> //7 U^^U[[-A-ABr\ctj}tjj|}fd|_|j ddj jjddjdy)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}. rcSrtr`rrYs rZr}z,AgentTests.test_persistent..4r\rhttp://127.0.0.1rTN r>rr0rrrkrrrerJrYrrs` rZtest_persistentzAgentTests.test_persistentsh "$,,/ T\\5/ f12 //215@@$Gr\ctjd}tjj|}fd|_|j ddj jjddjdy) a 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. FrJrcSrtr`rs rZr}z/AgentTests.test_nonPersistent..rr\rrrNrrs` rZtest_nonPersistentzAgentTests.test_nonPersistentsj"$,,5A T\\5/ f12 //215@@%Hr\ctGfddtj}Gfdd}|}|j|}j ||j t j}|jddt}|jdd || j|j jd y ) 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)}. ceZdZfdZy):AgentTests.test_connectUsesConnectionPool..MyAgentcnj|j|j|jfdS)Nrfoor/)rrCrDrE)thisrrrYs rZrzGAgentTests.test_connectUsesConnectionPool..MyAgent._getEndpoints1  ZZ38846K r\N)r]r^r_rrrYsrZMyAgentrs r\rc"eZdZdZdZfdZy).DummyPoolFcd|_j|j|dtjt S)NTr) connectedrrrrbrrUeprrYs rZr&zJAgentTests.test_connectUsesConnectionPool..DummyPool.getConnections@!%  X.  &;<}}%5%788r\Nr]r^r_rrJr&rsrZ DummyPoolrsIJ 9r\rrhostrr http://foo/) bodyProducerrTN) rr0rrrOrr2rC addRawHeaderobjectrkrr)rYrrrrrrrs` @rZtest_connectUsesConnectionPoolz)AgentTests.test_connectUsesConnectionPools !? fll  9 9{ 40 T5;;/&&(Wf-x  Nw   ..5r\c\|jt|jjddy)zj L{Agent.request} raises L{TypeError} when the C{method} argument isn't L{bytes}. GEThttp://foo.example/N assertRaises TypeErrorrrkrgs rZtest_nonBytesMethodzAgentTests.test_nonBytesMethod# )TZZ%7%7@VWr\cb|j|jjddtS)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'}. rsmailto:alice@example.com) assertFailurerrkrBrgs rZtest_unsupportedSchemez!AgentTests.test_unsupportedSchemes/ !! JJ  v'B CEW  r\c:|jjdd}|jjj dd\}}}|j dt t|jjd|j|ty)z The L{Deferred} returned by L{Agent.request} fires with a L{Failure} if the TCP connection attempt fails. rrNr ) rrkrrrclientConnectionFailedr*rrr)rYrlrDrErs rZtest_connectionFailedz AgentTests.test_connectionFailed#s| ##FN;"ll5599;BQ?dG&&tW5K5M-NO R  V%;s mm45&&(   z * )a JJ # #C ( )  KK  Q fT#((^f,   ) )s B11B:c fdj_jjddjjj \}}j |jjddgy)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. cSrtr`rs rZr}z.AgentTests.test_hostProvided..Xr\rhttp://example.com/foo?barrr.N rrrkrrerrrrrYreqress` rZtest_hostProvidedzAgentTests.test_hostProvidedRsd #5  6#@A==))--/S 227;n=MNr\c fdj_jjddjjj \}}j |jjddgy)z If an IPv6 address is used in the C{uri} passed to L{Agent.request}, the computed I{Host} header needs to be bracketed. cSrtr`rs rZr}z3AgentTests.test_hostIPv6Bracketed..crr\rs http://[::1]/rs[::1]Nrrs` rZtest_hostIPv6Bracketedz!AgentTests.test_hostIPv6Bracketed^sc #5  6#34==))--/S 227;hZHr\cBtjdgdgd}fdj_jj dd|j j j\}}j|jjddgy) 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. barsquuxrrcSrtr`rs rZr}z.AgentTests.test_hostOverride..prr\rrrN) r2rCrrrkrrerrrr)rYrrrs` rZtest_hostOverridezAgentTests.test_hostOverrideis~ &&G9'MN"4  6#@'J==))--/S 227;gYGr\c:tj}fdj_jj dd|j }j t|jdj |tjy)z If a I{Host} header must be added to the request, the L{Headers} instance passed to L{Agent.request} is not modified. cSrtr`rs rZr}z3AgentTests.test_headersUnmodified..|rr\rhttp://example.com/foorN) r2rCrrrkrrrre)rYrrs` rZtest_headersUnmodifiedz!AgentTests.test_headersUnmodifiedvsu &&("4  6#3 G r\c^|j|jjddddy)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{":"}. r1r.r-r.Nr)rgs rZtest_hostValueNonStandardHTTPSz)AgentTests.test_hostValueNonStandardHTTPSs+  JJ ( (>5 I  r\cfdj_tjddgi}t }jj dd||j }jt|jd|jj\}}j|tj|jdj|jdj|jtjdgdgd j!|j"|y ) 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. cSrtr`rs rZr}z)AgentTests.test_request..rr\rr rhttp://example.com:1234/foo?barrs/foo?barexample.com:1234r!N)rrr2rCrrkrrrrerrr?methodrrrOr)rYrbodyrrrs` rZ test_requestzAgentTests.test_requests#5 &&'9:x 6#EwPTU== X../3$$((*S c7+ V, +.  KK  6(>Q=R!S T  S--t4r\ctj|jd}|jdd|jjj d}|j d|y)z~ L{Agent} takes a C{connectTimeout} argument which is forwarded to the following C{connectTCP} agent. rconnectTimeoutrrrNr0rrrkrrrrYrrs rZtest_connectTimeoutzAgentTests.test_connectTimeoutsS  T\\!< fn-,,))--/2 G$r\&SSL not present, cannot run SSL tests.ctj|jd}|jdd|jjj d}|j d|y)z} L{Agent} takes a C{connectTimeout} argument which is forwarded to the following C{connectTCP} call. rr=r https://foo/rNr?r@s rZtest_connectTimeoutHTTPSz#AgentTests.test_connectTimeoutHTTPSsS  T\\!< fo.,,))--/2 G$r\ctj|jd}|jdd|jjj d}|j d|y)zz L{Agent} takes a C{bindAddress} argument which is forwarded to the following C{connectTCP} call. 192.168.0.1 bindAddressrrrNr?rYraddresss rZtest_bindAddresszAgentTests.test_bindAddresssS  T\\}E fn-,,))--/2 0r\ctj|jd}|jdd|jjj d}|j d|y)zz L{Agent} takes a C{bindAddress} argument which is forwarded to the following C{connectSSL} call. rGrHrrDrNr?rJs rZtest_bindAddressSSLzAgentTests.test_bindAddressSSLsS  T\\}E fo.,,))--/2 0r\cd}|j|j}|jd|}|jt |j j d|j j j\}}|j|ttjjdddtid|}|j||j|}|j|jj |jj"|jj$f|j |j"|j$fy)z L{Response}s returned by L{Agent.request} have a reference to the L{Request} that was originally issued. http://example.com/rrsHTTPrrOKN)rrrkrrrrerrr?r0r7 _constructrCcallbackrr9 absoluteURIr)rYrrr)rrresprs rZtest_responseIncludesRequestz'AgentTests.test_responseIncludesRequests %--dll; MM&# & T]]334a8==))--/S c7+)) S%dC  T''*   ''  ,,  ((  ZZ#++ 6  r\crd}|j|j}|jd||jt |j j d|j j j\}}|j|t|j|j|y)zL L{Request.absoluteURI} is the absolute URI of the request. s$http://example.com/foo;1234?bar#fragrrN) rrrkrrrrerrr?rV)rYrrrrs rZtest_requestAbsoluteURIz"AgentTests.test_requestAbsoluteURIs6--dll; fc" T]]334a8==))--/S c7+ #.r\c|tjddtd}|j|jdy)zX L{Request.absoluteURI} is L{None} if L{Request._parsedURI} is L{None}. FOOrN)r0r?rCrOrV)rYrks rZtest_requestMissingAbsoluteURIz)AgentTests.test_requestMissingAbsoluteURI#s0..wy$? W00$7r\ct}tjjd|}t j d}|j |}|j|dy)z| L{Agent.usingEndpointFactory} creates an L{Agent} that uses the given factory to create endpoints. N)endpointFactoryrP)rr.r/)rr0rusingEndpointFactoryr:rrr)rYrrrreturnedEndpoints rZtest_endpointFactoryzAgentTests.test_endpointFactory*sW &' 11$1Pmm23 --c2 )+HIr\ctjj|jt }|j }|j |j|j|jftd|jfy)z If no pool is passed in to L{Agent.usingEndpointFactory}, a default pool is constructed with no persistent connections. FN) r0rr`rrrr __class__rJrr>)rYrrs rZtest_endpointFactoryDefaultPoolz*AgentTests.test_endpointFactoryDefaultPool5s]  11$,,@S@UV{{  ^^T__dmm <  7 r\ct}tjj|jt |}|j ||jy)zr If a pool is passed in to L{Agent.usingEndpointFactory} it is used as the L{Agent} pool. N)rr0rr`rrassertIsrrs rZtest_endpointFactoryPoolz#AgentTests.test_endpointFactoryPoolAsB x 11 LL-/  dEKK(r\N)$r]r^r_rprrrrrrrrrr rrrr#r'r+r/r2r4r;rAr rrErLrNrXrZr]rbrerhr`r\rZrrs* &C HI"%6NX  = : ( O I H:       5<% NDE%F%1 NDE1F1 : /8 J   )r\rceZdZdZdZy)AgentMethodInjectionTestsz> Test L{client.Agent} against HTTP method injections. ctj|j}d}|j||t dy)v Attempt a request with the provided method. @param method: see L{MethodInjectionTestsMixin} http://twisted.invalidNr0rrrkrC)rYr9rrs rZ!attemptRequestWithMaliciousMethodz;AgentMethodInjectionTests.attemptRequestWithMaliciousMethodVs4  T//12' fc79d3r\Nr]r^r_rpror`r\rZrjrjM 4r\rjceZdZdZdZy)AgentURIInjectionTestsz6 Test L{client.Agent} against URI injections. ctj|j}d}|j||t dy)zp Attempt a request with the provided method. @param uri: see L{URIInjectionTestsMixin} rNrn)rYrrr9s rZattemptRequestWithMaliciousURIz5AgentURIInjectionTests.attemptRequestWithMaliciousURIjs4  T//12 fc79d3r\Nr]r^r_rprur`r\rZrsrsarqr\rsrBcTeZdZdZd dZdZdZdZdZdZ dZ d Z fd Z xZ S) AgentHTTPSTestsz@ Tests for the new HTTP client API that depends on SSL. ctj|jjt j d||fzS)a 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} shttps://%b:%d/)r0rrrr:r)rYrDrEs rZ makeEndpointzAgentHTTPSTests.makeEndpoint{s?||D..01>> MM+tTl: ;  r\cddlm}|j}|j|||j|jt y)zr L{Agent._getEndpoint} return a L{SSL4ClientEndpoint} when passed a scheme of C{'https'}. r)_WrapperEndpointN)twisted.internet.endpointsr|rzr_wrappedEndpointr)rYr|rs rZtest_endpointTypez!AgentHTTPSTests.test_endpointTypes> @$$& h(89 h779IJr\ct|jd}|j|jjdy)z@ If a host is passed, the endpoint respects it. r.)rDrN)rzrr~r)rYrs rZtest_hostArgumentIsRespectedz,AgentHTTPSTests.test_hostArgumentIsRespecteds3$$.$9 22;;]Kr\cxd}|j|}|j|jj|y)z@ If a port is passed, the endpoint respects it. )rEN)rzrr~r)rYr rs rZtest_portArgumentIsRespectedz,AgentHTTPSTests.test_portArgumentIsRespecteds8 $$,$7 2288,Gr\c|j}|jdj}|j|t|j |j dy)zY L{Agent} wraps its connection creator creator and uses modern TLS APIs. Nr)rz_wrapperFactory_connectionCreatorrrMr _hostname)rYrcontextFactorys rZtest_contextFactoryTypez'AgentHTTPSTests.test_contextFactoryTypesO$$&!11$7JJ n.>? 11=Ar\c d}d}Gdd}g ttG fdd |ttG fdd}|}|j}t j ||}|j tjd ||fz}|jtjt|jd d } | jd } | jt! d d } |j#| t$|j' d dd ||f|j)j*|j)j,y )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.orgiOc eZdZdZdZdZdZy)VAgentHTTPSTests.test_connectHTTPSCustomConnectionCreator..JustEnoughConnectionFcd|_y)zK The handshake started. Record that fact. TN)handshakeStartedrgs rZ do_handshakezcAgentHTTPSTests.test_connectHTTPSCustomConnectionCreator..JustEnoughConnection.do_handshakes )-%r\cd|_y)zL The connection started. Record that fact. TN) connectStatergs rZset_connect_statezhAgentHTTPSTests.test_connectHTTPSCustomConnectionCreator..JustEnoughConnection.set_connect_states %)!r\N)r]r^r_rrrrr`r\rZJustEnoughConnectionrs$  L -  )r\rc eZdZdZfdZy)SAgentHTTPSTests.test_connectHTTPSCustomConnectionCreator..JustEnoughCreatorc ||_||_yrt)hostnamerE)rYrrEs rZrhz\AgentHTTPSTests.test_connectHTTPSCustomConnectionCreator..JustEnoughCreator.__init__s (   r\cXj||j|jfS)z Implement L{IOpenSSLClientConnectionCreator}. @param tlsProtocol: The TLS protocol. @type tlsProtocol: L{TLSMemoryBIOProtocol} @return: C{expectedConnection} )rjrrE)rY tlsProtocol contextArgsexpectedConnections rZclientConnectionForTLSzjAgentHTTPSTests.test_connectHTTPSCustomConnectionCreator..JustEnoughCreator.clientConnectionForTLSs(""K #JK))r\N)r]r^r_rhr)rrsrZJustEnoughCreatorrs  ! *r\rceZdZfdZy)_AgentHTTPSTests.test_connectHTTPSCustomConnectionCreator..StubBrowserLikePolicyForHTTPSc||S)am 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} r`)rYrrErs rZcreatorForNetloczpAgentHTTPSTests.test_connectHTTPSCustomConnectionCreator..StubBrowserLikePolicyForHTTPS.creatorForNetlocs)488r\Nr]r^r_r)rsrZStubBrowserLikePolicyForHTTPSrs 9r\rs https://%b:%drNrr)rrrHrr0rrr:rrrrr rrrr&rrRrrrr)rYrr rrexpectedCreatorCreatorrrr tlsFactoryrrPrrrs @@@rZ(test_connectHTTPSCustomConnectionCreatorz8AgentHTTPSTests.test_connectHTTPSCustomConnectionCreatorsk&   ) )  4 5 * * 6 *"23 _ % 9 9 & 9 "?!@$$& W&<=%% MM*lL-II J  ,,X67''+A.  ..t4 ""?#45!nQ c#78 Q+lL-IJ *;;< *778r\cd}||j|g}|jt|d|\}|j|dt|j|ddy)aP Passing something that duck-types I{like} a L{web client context factory } - 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. cRtjttdy)Nz does-not-provide-IPolicyForHTTPS)r0rr"r%r`r\rZwarnMez9AgentHTTPSTests.test_deprecatedDuckPolicy..warnMe s LL-.@.BC2 r\rcategorymessagez'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) flushWarningsrrDeprecationWarning)rYrwarningswarnings rZtest_deprecatedDuckPolicyz)AgentHTTPSTests.test_deprecatedDuckPolicysm  %%vh/ X*  ,.@A  I  O r\ct}t|}|jdd}|j|j|j d}|j |j|jy)z L{BrowserLikePolicyForHTTPS.creatorForNetloc} returns an L{IOpenSSLClientConnectionCreator} provider which will add certificates from the given trust root.  trustRootsthingyrN) rTr;rrrWrrgrX get_context)rYrpolicycreator connections rZtest_alternateTrustRootz'AgentHTTPSTests.test_alternateTrustRootsg +, *Y?)))T:  (()33D9  i'')?)?)ABr\c|jd}t|jd\fd}fd}t ||||||dy)zC Wrap L{AgentTestsMixin.integrationTest} with TLS. s[]asciic<tjd||Sr)rQoptions) serverFactoryrrs rZtlsifyz/AgentHTTPSTests.integrationTest..tlsify4s&v~~'7 wW Wr\cddlm}ddlm}||Gfdd}t j ||S)Nrr)rHceZdZfdZy)AAgentHTTPSTests.integrationTest..tlsagent..Policyc<t|jdS)Nrr)rOdecode)rYrrE authoritys rZrzRAgentHTTPSTests.integrationTest..tlsagent..Policy.creatorForNetloc>s. 0Ir\Nr)rsrZPolicyr<sr\r)r)zope.interfacertwisted.web.iwebrHr0r)rrrHrrs rZtlsagentz1AgentHTTPSTests.integrationTest..tlsagent7s: 2 8  )  *  <<A Ar\r1)rrrCN)stripr-rsuperr) rYrrr certHostNamerrrrrds @@rZrzAgentHTTPSTests.integrationTest+sb ~~e, =    (  6 X B G #$$ $ r\)r.rH)r]r^r_rprzrrrrrrrr __classcell__)rds@rZrxrxusA $ KLHBQ9f 6 C# # r\rxczeZdZdZdZdZeeddZee ddZ ee ddZ y ) WebClientContextFactoryTestszr Tests for the context factory wrapper for web clients L{twisted.web.client.WebClientContextFactory}. chddlm}|jtjg|_||_y)zU Get WebClientContextFactory while quashing its deprecation warning. r)WebClientContextFactoryN)twisted.web.clientrrrrwarnedwebClientContextFactory)rYrs rZrz"WebClientContextFactoryTests.setUpWs+ ?((*F*L*L)MN '>$r\c 2|jt|jd|j\}|j|dt|j|dt |j t ddddtjdd y ) zx L{twisted.web.client.WebClientContextFactory} is deprecated. Importing it displays a warning. rrrTwistedr) replacement;:N) rrrrr)rrr;replace)rYrs rZtest_deprecatedz,WebClientContextFactoryTests.test_deprecated`s T[[)1-KK  ,.@A  I  ',, 2q!,5  WS#  r\z SSL Present.cd|jt|jjddy)zl If C{getContext} is called and SSL is not available, raise L{NotImplementedError}. r.rHN)rNotImplementedErrorr getContextrgs rZtest_missingSSLz,WebClientContextFactoryTests.test_missingSSLss-    ( ( * 5 5    r\rBc|jjdd}|j|tjj y)zT If SSL is present, C{getContext} returns a L{OpenSSL.SSL.Context}. rrHN)rrrrLSSLContext)rYctxs rZtest_returnsContextz0WebClientContextFactoryTests.test_returnsContexts7 **,77 sK c377??3r\c|j}|jdd}|j|jtj y)zd The L{CertificateOptions} has C{trustRoot} set to the default trust roots. rrHN)r_getCertificateOptionsrrrLOpenSSLDefaultPaths)rYrcertificateOptionss rZ-test_setsTrustRootOnContextToDefaultTrustRootzJWebClientContextFactoryTests.test_setsTrustRootOnContextToDefaultTrustRootsB **, 77 sK 0::C_RetryingHTTP11ClientProtocolr _shouldRetryr5 assertFalserYrrs rZtest_onlyRetryIdempotentMethodsz;KTRS 00.:JDQR 00n>NPTUVr\ctjd}tjd|}|j|j dt d|j|j dt gd|j|j dtgd|j|j dtgd|j|j dtdy)z Only L{RequestNotSent}, L{RequestTransmissionFailed} and L{ResponseNeverReceived} exceptions cause a retry. Nr) r0r>rrrr5r6r9rr8rrs rZ"test_onlyRetryIfNoResponseReceivedz?HTTPConnectionPoolRetryTests.test_onlyRetryIfNoResponseReceiveds ((.99$E   //8H$OP   # #F,Eb,I4 P    # #F,A",Et L  009KTRS   # #F,B,Dd K r\ctjd}tjd|}tt t j g}|j|jd|dy)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) r0r>rr9r*rrrr)rYrrrs rZ!test_dontRetryIfFailedDueToCancelz>HTTPConnectionPoolRetryTests.test_dontRetryIfFailedDueToCancels^ ((.99$E )753G3G3I+J*KL  00DIJr\c tjd}tjd|}|j|j dt t tgdy)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)r0r>rrrr9r* Exceptionrs rZ)test_retryIfFailedDueToNonCancelExceptionzFHTTPConnectionPoolRetryTests.test_retryIfFailedDueToNonCancelExceptionsW ((.99$E    # #-wy{/C.DEt  r\c tjt}tj t |j d|jdt}fd}|j|S)z If L{client.HTTPConnectionPool.getConnection} returns a previously cached connection, it will get wrapped in a L{client._RetryingHTTP11ClientProtocol}. {c~j|tjj|jyrt)rr0rrO_clientProtocolrrrYs rZr$zTHTTPConnectionPoolRetryTests.test_wrappedOnPersistentReturned..gotConnections/  ! !*f.R.R S  !;!;X Fr\) r0r>r!rbrr&r1r&rr'rYrr)r$rs` @rZ test_wrappedOnPersistentReturnedz=HTTPConnectionPoolRetryTests.test_wrappedOnPersistentReturnedso ((1$% 12 C*   sMO 4 G}}]++r\ctjd}|jdt}fd}|j |S)z| If L{client.HTTPConnectionPool.getConnection} returns a new connection, it will be returned as is. NrcFj|jtyrt)rOrdr3)rrYs rZr$zPHTTPConnectionPoolRetryTests.test_notWrappedOnNewReturned..gotConnections  !5!57K Lr\)r0r>r&rr')rYrr)r$s` rZtest_notWrappedOnNewReturnedz9HTTPConnectionPoolRetryTests.test_notWrappedOnNewReturneds@ ((.   sMO 4 M }}]++r\c g fd}ttjddtd}| d}tj||}fd}||_|j |}jt djt djd|jddjt| fS) zP Fail a first request, possibly retrying depending on argument. cdt}j|tj|Srt)rbrjrr)r protocolss rZr>z>HTTPConnectionPoolRetryTests.retryAttempt..newProtocols(')H   X &==* *r\r\rTrrcj|dj|j|ttfS)Nr\)rrOrr5r9)mrbprrY willWeRetrys rZrz?HTTPConnectionPoolRetryTests.retryAttempt.._shouldRetrys?   Q '  \ 2  ! !!n6K%L M r\r) rr0r?rCrrrkrrreerrbackr5) rYr r>rkrretrierrr)rrs `` @@rZ retryAttemptz)HTTPConnectionPoolRetryTests.retryAttempts  + x ..wy,SWX Q<66xM  , OOG $ Y+ Yq\223Q7 !Q''(89)|r\c|jd\}}|jt|dt}|djddj ||j |j|S)z L{client._RetryingHTTP11ClientProtocol} retries when L{client._RetryingHTTP11ClientProtocol._shouldRetry} returns C{True}. Trrr)rrrrrerUr'rO)rYr)rrs rZ"test_retryIfShouldRetryReturnsTruez?HTTPConnectionPoolRetryTests.test_retryIfShouldRetryReturnsTrue sl ((. 9 Y+8! a #,,X6}}T118<rrrr5rrrs rZtest_onlyRetryWithoutBodyz6HTTPConnectionPoolRetryTests.test_onlyRetryWithoutBody6sf((.99$E   //8H$OP 009I68TUr\c|jd\}}|jt|d|djddj t g|jt|d|j |t S)z If a L{client._RetryingHTTP11ClientProtocol} fails more than once on an idempotent query before a response is received, it will not retry. Trrr)rrrrer r9rrs rZtest_onlyRetryOncez/HTTPConnectionPoolRetryTests.test_onlyRetryOnceDs| ((. 9 Y+! a #++,A",EF Y+!!!%:;;r\ctjt}d|_t j t |jd|jdt}fd}|j|S)z If L{HTTPConnectionPool.retryAutomatically} is set to C{False}, don't wrap connections with retrying logic. Frc*j|yrt)rOrs rZr$z[HTTPConnectionPoolRetryTests.test_dontRetryIfRetryAutomaticallyFalse..gotConnectionas  X 6r\) r0r>r!rrbrr&r1r&rr'rs` @rZ'test_dontRetryIfRetryAutomaticallyFalsezDHTTPConnectionPoolRetryTests.test_dontRetryIfRetryAutomaticallyFalseQsv ((1"'$% 12 C*   sMO 4 7}}]++r\c<tjt}dtgfd}||_t j t|j|j}fd}|j|S)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. rc,j||fyrt)rj)krnewConnectionss rZrTzOHTTPConnectionPoolRetryTests.test_retryWithNewConnection..newConnectionss  ! !1a& )r\cXj|tjj|jj g|j j tdj ddjddy)Nrr)rr0rrOrrrVr)rrrUrrrYs rZr$zOHTTPConnectionPoolRetryTests.test_retryWithNewConnection..gotConnections  ! !*f.R.R S  !;!;X F   ^R 0  % % '   S0! 4   ^A.q13 7  !21!5x @r\) r0r>r!rrVrbrr&r1r&r') rYrrTr)r$rrUrrs ` @@@@rZtest_retryWithNewConnectionz8HTTPConnectionPoolRetryTests.test_retryWithNewConnectionfs((1 ? *,$% 12 C*   sH - A A}}]++r\N)r]r^r_rprrrrrrrrrrrrr!r`r\rZrrsL W" & K  ,. ,!F =5 V <,*&,r\rc(eZdZdZ ddZy)CookieTestsMixinz4 Mixin for unit tests dealing with cookies. c tjtjdddtd|id}tj|}|j ||||fS)z/ Add a cookie to a cookie jar. rQrRrS Set-CookieN)r0_FakeStdlibResponser7rC_FakeStdlibRequestextract_cookies)rY cookieJarrcookiesrrks rZ addCookieszCookieTestsMixin.addCookiessf -- OO01   ++C0!!(G4  r\N)r)rrrxr*z list[bytes]rnz._checkCookiesR9oG   S\1 -   WQZ__e 4   WQZ--s 3r\cookieNrQrRrSr%foo=1)rrrGrrr0rNrkr'rrerrOrrr7rCrU) rYr cookieAgentr)rSrrrWr)s ` @rZtest_emptyCookieJarRequestz+CookieAgentTests.test_emptyCookieJarRequestsK  i"---dll;(( :   (J K 4 l#==))--/S S[[66yA4H    ! $     Tr\cd}d}t}|j|||g|jtt |d|j |j }tj||}|jd|tddgi|jjj\}}|j|jjddgy ) 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. r7rUrrrAz already-setrTs already-setN)rr+rrrGrrr0rNrkrCrrerrrrYrrAr)rrVrrs rZtest_leaveExistingCookieHeaderz/CookieAgentTests.test_leaveExistingCookieHeader"s 1K   31 T)_-q1--dll;(( : FC(]O1L)MN==))--/S 229=?OPr\cd}d}t}|j|||g|jtt |d|j |j }tj||}|jd||jjj\}}|j|jjd|gy)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. r7rUrrrTNrr+rrrGrrr0rNrkrrerrrrYs rZtest_requestWithCookiez'CookieAgentTests.test_requestWithCookie6s 1K   31 T)_-q1--dll;(( : FC(==))--/S 229=xHr\rBcd}d}t}|j|||g|jtt |d|j |j }tj||}|jd||jjj\}}|j|jjddgy)z~ 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;securerrrTrUNr\rYs rZtest_secureCookiez"CookieAgentTests.test_secureCookieJs 2 K   31 T)_-q1--dll;(( : FC(==))--/S 229=zJr\cd}d}t}|j|||g|jtt |d|j |j }tj||}|jd||jjj\}}|jd|jjdy)zs If a cookie is setup as secure, it won't be sent with the request if it's not over HTTPS. rr_rrNrT)rr+rrrGrrr0rNrkrrerrOrrrYs rZ%test_secureCookieOnInsecureConnectionz6CookieAgentTests.test_secureCookieOnInsecureConnection^s , K   31 T)_-q1--dll;(( : FC(==))--/S T3;;#<#*+  r\cltj|jdtfdtfg}|j dd}|j jj\}}tdddtjd}|j||j|j|S) z If the response is not encoded despited the request I{Accept-Encoding} headers, L{client.ContentDecoderAgent} simply forwards the response. rurvrr&rQrRrSN)r0rrrrirnrkrrerr7r2rCrUr'rO)rYrrrrrs rZtest_plainEncodingResponsez3ContentDecoderAgentTests.test_plainEncodingResponses ** JJ+x0;2IJ ==)BC==))--/SOS%9M9M9OQUV X##D$8$8(CCr\c|tj|jdtfdtfg}|j dd}|j jj\}}tjdgdgd}tdd d |d }|j||j|j|S) zz If an encoding unknown to the L{client.ContentDecoderAgent} is found, the response is unchanged. rurvrr&r r{rcontent-encodingrQrRrSN)r0rrrrirnrkrrerr2rCr7rUr'rO)rYrrrrrrs rZtest_unsupportedEncodingz1ContentDecoderAgentTests.test_unsupportedEncodings ** JJ+x0;2IJ ==)BC==))--/S&&XWI > OS%$G X##D$8$8(CCr\cvtjjdtfdtfg}|j dd}j jj\}}tjdgdgd}tdd d |d |jfd }|j|S) z When L{client.ContentDecoderAgent} encounters a decoder it doesn't know about, it stops decoding even if another encoding is known afterwards. rurvrr&r sdecoder1,fizz,decoder2rrQrRrSNcj|j|tjdg|jj dy)Ns decoder1,fizzr)rSrrnrrr)rlrrYs rZcheckz.check sI  # #Hf 5  ! !&( 3   !"FNN$@$@AT$U r\)r0rrrrirnrkrrerr2rCr7rUr')rYrrrrrrrs` @rZtest_unknownEncodingz-ContentDecoderAgentTests.test_unknownEncoding s ** JJ+x0;2IJ ==)BC==))--/S&&X5N4O P OS%$G X ##E**r\N) r]r^r_rprrryrrrrr`r\rZrprps-: A & 6D"D(+r\rpc(eZdZdZdZdZdZdZy)SimpleAgentProtocola  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. cNt|_t|_g|_yrt)rmadefinishedreceivedrgs rZrhzSimpleAgentProtocol.__init__) sJ    r\c:|jjdyrt)rrUrgs rZconnectionMadez"SimpleAgentProtocol.connectionMade. s 4 r\c:|jjdyrt)rrU)rYreasons rZrvz"SimpleAgentProtocol.connectionLost1 s t$r\c:|jj|yrt)rrjrYrs rZ dataReceivedz SimpleAgentProtocol.dataReceived4 s T"r\N)r]r^r_rprhrrvrr`r\rZrr s !%#r\rc*eZdZdZdZdZdZdZy) ContentDecoderAgentWithGzipTestsc|j|_|j|j}tj|dtj fg|_y)rgzipN)rrrr0rr GzipDecoderrrs rZrz&ContentDecoderAgentWithGzipTests.setUp9 sJ))+ --dll;//&BTBT8U7VW r\c, jjdd}jjj \}}t j dgdgd}t}tddd|| d _ |j tjd tjd tjz}|jd |jd z|j!z fd}|j#||S)z If the response has a C{gzip} I{Content-Encoding} header, L{GzipDecoder} wraps the response to return uncompressed data to the user. rr&r rrrQrRrS rsxxxxxxsyyyycj|j|jdj|jdj|jdjt |j jddgfgj|jtjtt|djddjddjt}|j!|j|j"dgt%j&|j(|j*gS) NrQrRrSr}r unknownrs xxxxxxyyyy)rSrr;codephraserGrrIrrDrAttributeErrorgetattr_bodyDataReceived_bodyDataFinishedr deliverBodyrr gatherResultsrr)rlrrrrYs rZ checkResponsezQContentDecoderAgentWithGzipTests.test_gzipEncodingResponse..checkResponseZ s,  # #FH 5   V^^_ =   V[[# .   V]]E 2   V^^44676F8:L9M    V]]N ;   ngvy I  & &tBQx 0  & &tABx 0  & & (*,H   x (   X..1D0E F&& x7H7H'IJ Jr\)rrkrrerr2rCr&r7rrUzlib compressobjDEFLATED MAX_WBITScompressrr') rYrrrrr2 compressorrrrs ` @@rZtest_gzipEncodingResponsez:ContentDecoderAgentWithGzipTests.test_gzipEncodingResponseA s ::%%f.GH==))--/S&&XWI > $% OS%)L X%%aT^^8KL    )!!(+ ,  !  K* ]+r\c jjdd}jjj \}}t j dgdgd}t}tddd|| d _ |j d  fd }|j|j|tjfd }|j|S) 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}. rr&r rrrQrRrSrsnot gzipped contentcZj|jtyrt)rrr )rlrrs rZrzJContentDecoderAgentWithGzipTests.test_brokenContent..checkResponse s!  & &t ,   xz *r\c|jdjtjj |j t y)Nrreasonsrrr1rrr7r1rYs rZ checkFailurezIContentDecoderAgentWithGzipTests.test_brokenContent..checkFailure 2 MM!  ! !$** -  ! !%..( ;r\)rrkrrerr2rCr&r7rrUr'rr0r8) rYrrrrr2rrrrs ` @@rZtest_brokenContentz3ContentDecoderAgentWithGzipTests.test_brokenContents s ::%%f.GH==))--/S&&XWI > $% OS%)L X% + ]+ 8V%:%:; <##L11r\c Gdd}tj}|t_jttd|jj dd}j jj\}}tjddgi}t}tddd || |j  fd }|j||S) 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. ceZdZdZdZdZy)FContentDecoderAgentWithGzipTests.test_flushData..decompressobjcyrtr`rYwbitss rZrhzOContentDecoderAgentWithGzipTests.test_flushData..decompressobj.__init__ rr\cyNxr`rs rZ decompresszQContentDecoderAgentWithGzipTests.test_flushData..decompressobj.decompress r\cy)Nyr`rgs rZrzLContentDecoderAgentWithGzipTests.test_flushData..decompressobj.flush rr\Nr]r^r_rhrrr`r\rZ decompressobjr s   r\rrr&rrrQrRrScjdjt}|j|j |j ddgt j|j|jgSNsdatarr rrrrrrrrrrrlrrrYs rZrzFContentDecoderAgentWithGzipTests.test_flushData..checkResponse m  & &w /  & & (*,H   x (   X..t =&& x7H7H'IJ Jr\)rr addCleanupsetattrrrkrrerr2rCr&r7rUr') rYroldDecompressObjrrrrr2rrs ` @rZtest_flushDataz/ContentDecoderAgentWithGzipTests.test_flushData s   --* 8HI::%%f.GH==))--/S&&(;gY'GH#% OS%)L X K ]+r\c, Gdd}tj}|t_jttd|jj dd}j jj\}}tjddgi}t}tddd || |j  fd }|j|j|t j"fd } |j| S) z If the C{flush} call in C{connectionLost} fails, the C{zlib.error} exception is caught and turned into a L{ResponseFailed}. ceZdZdZdZdZy)GContentDecoderAgentWithGzipTests.test_flushError..decompressobjcyrtr`rs rZrhzPContentDecoderAgentWithGzipTests.test_flushError..decompressobj.__init__ rr\cyrr`rs rZrzRContentDecoderAgentWithGzipTests.test_flushError..decompressobj.decompress rr\c*tjrt)rr1rgs rZrzMContentDecoderAgentWithGzipTests.test_flushError..decompressobj.flush sjjl"r\Nrr`r\rZrr s   #r\rrr&rrrQrRrScjdjt}|j|j |j ddgt j|j|jgSrrrs rZrzGContentDecoderAgentWithGzipTests.test_flushError..checkResponse rr\c|jdjtjj |j t y)Nrrrs rZrzFContentDecoderAgentWithGzipTests.test_flushError..checkFailure rr\)rrrrrrkrrerr2rCr&r7rUr'rr0r8) rYrrrrrrr2rrrs ` @rZtest_flushErrorz0ContentDecoderAgentWithGzipTests.test_flushError s  # # --* 8HI::%%f.GH==))--/S&&(;gY'GH#% OS%)L X K ]+ 8V%:%:; <##L11r\N)r]r^r_rrrrrr`r\rZrr8 sX0d2B*X/2r\rc4eZdZdZdZdZdZdZdZdZ y) ProxyAgentTestsz) Tests for L{client.ProxyAgent}. cltjt|jdd|jS)zA @return: a new L{twisted.web.client.ProxyAgent} z 127.0.0.1r)r0 ProxyAgentrrrgs rZrzProxyAgentTests.makeAgent s-  t||[$ ?  r\c|j|_tjt |jdd|j|_|j j }|j|||j _y)Nr6.)rrr0rrr_proxyEndpointr)rY oldEndpoints rZrzProxyAgentTests.setUp sd))+ && t||UD 94<<  jj// $($5$5k4$H !r\c\|jt|jjddy)zo L{ProxyAgent.request} raises L{TypeError} when the C{method} argument isn't L{bytes}. rrNrrgs rZrz#ProxyAgentTests.test_nonBytesMethod rr\cNtjddgi}t}|jj dd|||j j jdd\}}}|j|d|j|d|j|jtj|j}|jt|jd |jj\}}|j|t |j|j"d|j|j$d|j|j&tjdgd gd |j)|j*|y) z L{client.ProxyAgent} issues an HTTP request against the proxy, with the full URI as path, when C{request} is called. rr rr7Nrr6rrr8r!)r2rCrrrkrrrrr_wrappedFactoryr0rArrrer?r9rrrOr) rYrr:rDrErrrrs rZtest_proxyRequestz!ProxyAgentTests.test_proxyRequest s] &&'9:x 6#EwPTU"ll5599;BQ?dG u% t$ g55v7R7RS== X../3$$((*S c7+ V, "DE  KK  6(>Q=R!S T  S--t4r\cd|j|jjjdy)zJ C{ProxyAgent} connections are not persistent by default. FN)rrrrJrgs rZrz"ProxyAgentTests.test_nonPersistent- s$ ))44e.DummyPoolFcd|_j|j|dftjt S)NTz http-proxy)rrOrrrrbrs rZr&zOProxyAgentTests.test_connectUsesConnectionPool..DummyPool.getConnection? sD!%$$R2  |X&>?}}%5%788r\NrrsrZrr; sIJ 9r\rrrrTN) rr0rrrOrrkrr)rYrrrrs` @rZrz.ProxyAgentTests.test_connectUsesConnectionPool3 ss !? 9 9{!!(DLLtD T5;;/ fn- ..5r\N) r]r^r_rprrrrrrr`r\rZrr s' IX5>= 6r\r) authorizationrTcookie2proxy-authorizationswww-authenticateceZdZUdZded<ded<ded<dZ d d d Zd Zd Zd Z dZ dZ d! d"dZ d#dZ d#dZd#dZdZdZdZdZdZdZdZdZdZdZdZy )$_RedirectAgentTestsMixinz^ Test cases mixin for L{RedirectAgentTests} and L{BrowserLikeRedirectAgentTests}. rErr%rrbrc|jjdd}|jjj \}}t j }tddd|d}|j||jdt|jj|j|}|j|||j|jdy)zz L{client.RedirectAgent} behaves like L{client.Agent} if the response doesn't contain a redirect. rr&rQrRrSNr)rrkrrerr2rCr7rUrrrrOpreviousResponse)rYrrrrrrls rZtest_noRedirectz(_RedirectAgentTestsMixin.test_noRedirectc s ::%%f.GH==))--/S&&(OS%$G X C 6 678%%h/ Xv. V44d;r\Ncd}tdnd}|dk(rdnd}|jjd|dz|zd z| |jjj dd \} } |j t| |j || |jjj \} } |} |}|}|r#t td |dk(rdnd} |dk(rdnd}d }|rd}d}|rdn|}| dz|z|zdz}tjd|gi}td|d|d}| j||jjj \}}|j d|j|j d|j |jjj dd \} } |j |rt"nt| |j || |S)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. r.Nr1rr/rHrrs/foor|rz;Cross-scheme redirects can't be tested without TLS support.r\i s:8443 example.net/barlocationrQrS)rLrrkrrrrrrrer r2rCr7rUr9rr)rYr crossScheme crossDomain crossPortrequestHeaders startDomain startScheme startPortrDrErr targetScheme targetDomain targetPort portSyntax locationValuerrreq2res2s rZ_testRedirectDefaultz-_RedirectAgentTestsMixin._testRedirectDefaultu s% "%/hw %0Bc   K&(;6@.  \\,,0022A6 d . D)==))--/S # "  {Q(3g'=87L )RRJ J!J)4~+ $v- .normHeaders s-/6/G/G/IJVaAGGIqLJ JJs3rr.rN)rrCrnzDict[bytes, Sequence[bytes]])r)rCrrr_) rYexpectedHostHeader crossKwargssensitiveHeaderValuesotherHeaderValues allHeaders redirectedrsameOriginHeadersredirectedElsewhereotherOriginHeaderss rZ_sensitiveHeadersTestz._RedirectAgentTestsMixin._sensitiveHeadersTest s3 330123%<$="4!5$7#8 ! 02C1DEK 5K9JKL ..s:.N  K( (:(:;  .) j)  8d77   ##Q&;#Q?P#QR  ))<)D)DE  ,- g&789  r\c*|jddy)zv L{client.RedirectAgent} scrubs sensitive headers when redirecting between differing domains. Tr)rrNr%rgs rZtest_crossDomainHeadersz0_RedirectAgentTestsMixin.test_crossDomainHeaders s ""t"Wr\c*|jddy)zt L{client.RedirectAgent} scrubs sensitive headers when redirecting between differing ports. Tsexample.com:8443)rrNr'rgs rZtest_crossPortHeadersz._RedirectAgentTestsMixin.test_crossPortHeaders s ""/B # r\c(|jdy)zv L{client.RedirectAgent} scrubs sensitive headers when redirecting between differing schemes. Tr Nr'rgs rZtest_crossSchemeHeadersz0_RedirectAgentTestsMixin.test_crossSchemeHeaders s ""t"4r\c|jj|d|jjj \}}t j ddgi}td|d|d}|j||jjj \}}|jd|j|jd|jy) 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&rhttp://example.com/barrQrSNrr) rrkrrerr2rCr7rUrr9r) rYrr9rrrrrrs rZ_testRedirectToGetz+_RedirectAgentTestsMixin._testRedirectToGet s 6#<===))--/S&& 6O5P'QROT5'4H X]]++//1 d - $((+r\c(|jddy)z L{client.RedirectAgent} changes the method to I{GET} when getting a 303 redirect on a I{POST} request. i/rNr/rgs rZtest_redirect303z)_RedirectAgentTestsMixin.test_redirect303-  W-r\cx|jjdd}|jjj \}}t j }tddd|d}|j||j|tj}|jjdjtj |j#d|jjdjj$|j#d|jj&j(y)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. rr&rQrrSNr)rrkrrerr2rCr7rUrr0r8r`rrr1RedirectWithNoLocationrrrr)rYrrrrrfails rZtest_noLocationFieldz-_RedirectAgentTestsMixin.test_noLocationField4 s ::%%f.GH==))--/S&&(OS%$G X##Hf.C.CD 1""5#?#?@ 2DJJ4F4Fq4I4O4O4S4ST djj11667r\cx|jj|d}|jjj \}}t j }td|d|d}|j||j|tj}|jjdjtj |j#d|jjdjj$|j#||jj&j(y)a 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&rQrSNr)rrkrrerr2rCr7rUrr0r8r`rrr1 PageRedirectrlocationrr) rYrr9rrrrrr6s rZ_testPageRedirectFailurez1_RedirectAgentTestsMixin._testPageRedirectFailureG s::%%f.GH==))--/S&&(OT5'4H X##Hf.C.CD 1""5#5#56  %tzz'9'9!'<'B'B'K'K  tzz22778r\c(|jddy)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. rrNr;rgs rZtest_307OnPostz'_RedirectAgentTestsMixin.test_307OnPost`  %%c73r\c\|j|j}tj|d}|j dd}|j j j\}}tjddgi}tddd|d }|j||j j j\}} tddd|d } | j| |j|tj} | jjd j!t"j$|j'd| jjd jj(|j'd| jj*j,y ) 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. rrr&rr.rQrrSNr)rrr0 RedirectAgentrkrrerr2rCr7rUrr8r`rrr1InfiniteRedirectionrr:rr) rYr redirectAgentrrrrrrr response2r6s rZtest_redirectLimitz+_RedirectAgentTestsMixin.test_redirectLimith sU --dll;,,UA6  ((1JK==))--/S&& 6O5P'QROS%$G X]]++//1 d_c5'4H  i ##Hf.C.CD 1""5#<#<=  %tzz'9'9!'<'B'B'K'K  djj11667r\c|jjd||jjj \}}t j d|gi}tddd|d}|j||jjj \}} |jd|j|j||jy)a1 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. rrrQrrSN) rrkrrerr2rCr7rUrr9rV) rYrr:finalURIrrrrrrs rZ_testRedirectURIz)_RedirectAgentTestsMixin._testRedirectURI s 63'==))--/S&& hZ'@AOS%$G X]]++//1 d - 4#3#34r\cv|jddd|jddd|jdddy) z L{client.RedirectAgent} resolves and follows relative I{URI}s in redirects, preserving query strings. http://example.com/foo/barsbazshttp://example.com/foo/bazs/bazshttp://example.com/baz/baz?ashttp://example.com/baz?aNrHrgs rZtest_relativeURIz)_RedirectAgentTestsMixin.test_relativeURI sJ  )63P   )74M   )96Q r\cP|jddd|jdddy)a 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} shttp://example.com/foo/bar#fragrKshttp://example.com/baz?a#fragrJs /baz?a#frag2shttp://example.com/baz?a#frag2NrLrgs rZ!test_relativeURIPreserveFragmentsz:_RedirectAgentTestsMixin.test_relativeURIPreserveFragments s4  .  ,  )  - r\cP|jddd|jdddy)z L{client.RedirectAgent} resolves and follows scheme relative I{URI}s in redirects, replacing the hostname and port when required. rJs //foo.com/bazshttp://foo.com/bazs//foo.com:81/bazshttp://foo.com:81/bazNrLrgs rZtest_relativeURISchemeRelativez7_RedirectAgentTestsMixin.test_relativeURISchemeRelative s4  )+;=R   )+>@X r\cf|j|j}tj|}|j dd}|j j j\}}tjddgi}tddd|d}|j||j j j\}} tdd d|d} | j| |j|} |j| j||j|jdy) z L{Response.response} references the previous L{Response} from a redirect, or L{None} if there was no previous response. rr&rr.rQrrSNrR)rrr0rArkrrerr2rCr7rUrrOr) rYrrCr redirectReq redirectResrredirectResponserrr finalResponses rZtest_responseHistoryz-_RedirectAgentTestsMixin.test_responseHistory s  --dll;,,U3  ((1JK#'==#9#9#=#=#? [&& 6O5P'QR#OS%$O-.==))--/SOS%$G X,,X6  ];;=MN ->>Er\)FFFN) rintrboolrrYrrYrzOptional[Headers]rnr?)r.)rrxrrYrnrorm)r]r^r_rp__annotations__rrr rrrrr%r(r*r,r/r2r7r;r>rErHrMrOrQrWr`r\rZrrY s M <*"!,0 <<< <  < * < <|'  ' ' '+9+ "'+ IM+ + ZX 5,*.8&9248<5.   &  Fr\rc(eZdZdZdZdZdZdZy)RedirectAgentTestsz, Tests for L{client.RedirectAgent}. cdtj|j|jdgS)zD @return: a new L{twisted.web.client.RedirectAgent} sX-Custom-sensitivesensitiveHeaderNames)r0rArrrgs rZrzRedirectAgentTests.makeAgent s/##  ) )$,, 7"7!8  r\cX|j|_|j|_yrtrrgs rZrzRedirectAgentTests.setUp ))+ ^^% r\c(|jddy)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. rrNr=rgs rZtest_301OnPostz!RedirectAgentTests.test_301OnPost r?r\c(|jddy)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. rrNr=rgs rZtest_302OnPostz!RedirectAgentTests.test_302OnPost r?r\N)r]r^r_rprrrcrer`r\rZr\r\ s  &44r\r\c(eZdZdZdZdZdZdZy)BrowserLikeRedirectAgentTestsz7 Tests for L{client.BrowserLikeRedirectAgent}. cdtj|j|jdgS)zO @return: a new L{twisted.web.client.BrowserLikeRedirectAgent} sx-Custom-sensitiver^)r0BrowserLikeRedirectAgentrrrgs rZrz'BrowserLikeRedirectAgentTests.makeAgent s/..  ) )$,, 7"7!8  r\cX|j|_|j|_yrtrrgs rZrz#BrowserLikeRedirectAgentTests.setUp rar\c(|jddy) L{client.BrowserLikeRedirectAgent} changes the method to I{GET} when getting a 302 redirect on a I{POST} request. rrNr1rgs rZtest_redirectToGet301z3BrowserLikeRedirectAgentTests.test_redirectToGet301$ r3r\c(|jddy)rlrrNr1rgs rZtest_redirectToGet302z3BrowserLikeRedirectAgentTests.test_redirectToGet302+ r3r\N)r]r^r_rprrrmror`r\rZrgrg s  &..r\rgceZdZdZdZdZy)AbortableStringTransportzK A version of L{StringTransport} that supports C{abortConnection}. Fc2d|_|jy)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)abortingloseConnectionrgs rZabortConnectionz(AbortableStringTransport.abortConnection; s  r\N)r]r^r_rprsrur`r\rZrqrq3 s Hr\rqc*eZdZdZdZdZdefdZdZy) DummyResponsea 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. rRrSNcB| t}||_||_y)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)rCrr2)rYrtransportFactorys rZrhzDummyResponse.__init__U s! ?iG )+r\c\||_|jj|jy)zt Record the given protocol and use it to make a connection with L{DummyResponse.transport}. Nrrr2r6s rZrzDummyResponse.deliverBodyb s! !  $$T^^4r\) r]r^r_rprrrqrhrr`r\rZrwrwF s#  D F#6N ,5r\rwceZdZdZdZy)AlreadyCompletedDummyResponsezE A dummy response that has already had its transport closed. c~||_|jj|jd|j_y)zA Make the connection, then remove the transport. Nr{r6s rZrz)AlreadyCompletedDummyResponse.deliverBodyp s-!  $$T^^4"& r\N)r]r^r_rprr`r\rZr}r}k s 'r\r}c4eZdZdZdZdZdZdZdZdZ y) ReadBodyTestsz& Tests for L{client.readBody} cHt}tj|}|jj d|jj d|jj t t|j|j|dy)z L{client.readBody} returns a L{Deferred} which fires with the complete body of the L{IResponse} provider passed to it. firstsecond firstsecondN) rwr0readBodyrrrvr*r@rr)rYrr)s rZ test_successzReadBodyTests.test_success~ sw !? OOH %&&x0&&y1(()@A --a0.Ar\ct}tj|}|j|j |t j |j|jjy)z When cancelling the L{Deferred} returned by L{client.readBody}, the connection to the server will be aborted. N) rwr0rrrrrrr2rs)rYrrs rZ test_cancelzReadBodyTests.test_cancel sQ !???8, Xu';';< **334r\ct}tj|}|jj d|jj d|jj t t|j|}|jtj|j|jj|jj|jjdddddy)a 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. rr)statusrr:s200rSrN)rwr0rrrrvr*r4rrPartialDownloadErrorrr`rrr)rYrr)failures rZtest_withPotentialDataLossz(ReadBodyTests.test_withPotentialDataLoss s!? OOH %&&x0&&y1((1B1D)EF&&q) V001 !--.."==00 ..  ! &  r\cjt}tj|}|jj d|jj t td|j|}|jt|j|jjdy)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. rmystery problem)rN) rwr0rrrrvr*rrrrr`r)rYrr)rs rZtest_otherErrorszReadBodyTests.test_otherErrors s !? OOH %&&x0((@Q1R)ST%%a( N# **,@Ar\cttdj_|j t dt fd}|j|j|tjy)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. )ryNzLUsing readBody with a transport that does not have an abortConnection methodc.tjSrt)r0r)rsrZr}z8ReadBodyTests.test_deprecatedTransport.. sFOOH-r\) rwr&r2ru assertWarnsr__file__rrrr)rYr)rs @rZtest_deprecatedTransportz&ReadBodyTests.test_deprecatedTransport s\ !/B-1*     %  -     Q 4 45r\ct}tj||j}|j t |dy)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. rN)r}r0rrrr)rYrrs rZ!test_deprecatedTransportNoWarningz/ReadBodyTests.test_deprecatedTransportNoWarning s: 12!%%' X*r\N) r]r^r_rprrrrrrr`r\rZrry s' B 5 6 B6$ +r\rceZdZdZdZdZy)HostnameCachingHTTPSPolicyTestsct}t|}t|}|jdd}|j |j d|_|j dt|j|jd}|j|j|j|jdd|j|j y)z Verify that the connection creator is added to the policy's cache, and that it is reused on subsequent calls to creatorForNetLoc. rri5FrN)rTr;r=rrrWr_r_cacherrgrXrr)rYr wrappedPolicyrrrs rZtest_cacheIsUsedz0HostnameCachingHTTPSPolicyTests.test_cacheIsUsed s+, 1IF +M:))&$7  (()  !S/033D9  i'')?)?)AB- ))*r\ct}t|}t|}tddD]1}dt |z}|j |j dd3d}|j |j dd|j||j|jdt|jd }|j |j ddd }|j||j|jdt|j|j||j|j||jtdD]#} |j |j dd%d } |j | j dd |jd |j|jdt|j|j| |j|j||j|j||jy)zt Verify that when the cache is full, and a new entry is added, the oldest entry is removed. rrrDr!host05newhost1new1i host2N rTr;r=rstrrr r4rr_rr ) rYrrrrrrhostnrr hostNPlus1s rZtest_cacheRemovesOldestz7HostnameCachingHTTPSPolicyTests.test_cacheRemovesOldest s +, 1IF +M:q" DAAH  # #HOOG$RequestWriteToURIInjectionTests.attemptRequestWithMaliciousURI sO &&2D1E'FGnn)    O%&r\Nrvr`r\rZrr| rr\r)rp __future__rrhttp.cookiejarriortypingrrrr r r unittestr r zope.interface.declarationsrzope.interface.verifyr incrementalrtwisted.internetrrtwisted.internet.addressrrtwisted.internet.deferrrrr}rrtwisted.internet.errorrrrtwisted.internet.interfacesrtwisted.internet.protocolrr 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.webr0r1r2twisted.web._newclientr3r4r5r6r7r8r9rr:r;r<r=r>r?r@rAtwisted.web.errorrBtwisted.web.http_headersrCrrDrErFrGrHrI!twisted.web.test.injectionhelpersrJrKtestMixinClassrruntimeTestCaserL_sslrtwisted.internet._sslverifyrMrNtwisted.internet.sslrOtwisted.protocolsrPtwisted.protocols.tlsrQrRrT ImportErrorrbrrrzrrrrrrrrr rrrrrrrjrsrxrrr#r-rLrirnrprrrSENSITIVE_HEADERSrr\rgrqrwr}rrrrrrr`r\rZrs# $GG%3.(=DDK H7'N .7@*4I@33   1,NONO#, CJO8%O"###$#x2%%]&H]&@  P!P!f!!GG 7 jVh(BjVZ @ @u u p "#00$0$Y) (/;RY)x 44(44(J@AX h :