ϪfC<dZddlmZddgZddlmZddlmZmZm Z ddl m Z m Z ddl mZdd lmZmZdd lmZdd lmZmZdd lmZdd lmZddlmZddlmZddlm Z ddl!m"Z"ddl#m$Z$m%Z%m&Z&dDcgc]}d|d c}Z'dZ(e'Dcgc]}|jSdc}Z*e(jSdZ+e eGddZ,GddZ-GddZ.Gddej^Z0ycc}wcc}w)z2 Helpers related to HTTP requests, used by tests. ) annotations DummyChannel DummyRequest)BytesIO)DictListOptional) implementerverify)Version) IPv4Address IPv6Address)Deferred)IAddress ISSLTransport)Clock) deprecated)unittest)FOUND)Headers)Resource) NOT_DONE_YETSessionSite)  z FoobarzFoo barasciiceZdZdZy) NullAddressz/ A null implementation of L{IAddress}. N)__name__ __module__ __qualname____doc__@/usr/lib/python3/dist-packages/twisted/web/test/requesthelper.pyr!r!'sr'r!ceZdZGddZeeGddeZeeZ ddZ dZ dZ d Z d Zd Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZy)rcFeZdZdZdZd dZdZdZdZdZ d Z d Z d Z y) DummyChannel.TCPPFNc\| tddd}||_t|_g|_y)NTCPz 192.168.1.1i80)r _peerrwritten producersselfpeers r(__init__zDummyChannel.TCP.__init__3s,|"5-?DJ"9DLDNr'c|jSN)r/r3s r(getPeerzDummyChannel.TCP.getPeer:s :: r'cvt|tstd||jj |y)Nz)Can only write bytes to a transport, not ) isinstancebytes TypeErrorr0writer3datas r(r>zDummyChannel.TCP.write=s1dE*"KD8 TUU LL  t $r'c4|D]}|j|yr7)r>)r3iovecr@s r( writeSequencezDummyChannel.TCP.writeSequenceBs ! 4  !r'c0tdd|jS)Nr.z10.0.0.1)r portr8s r(getHostzDummyChannel.TCP.getHostFsuj$))< |jj||fyr7)r1appendr3producer streamings r(registerProducerz!DummyChannel.TCP.registerProducerIs NN ! !8Y"7 8r'cyr7r&r8s r(unregisterProducerz#DummyChannel.TCP.unregisterProducerLs r'cd|_y)NT) disconnectedr8s r(loseConnectionzDummyChannel.TCP.loseConnectionOs $D r'r7) r"r#r$rErPr5r9r>rCrFrLrNrQr&r'r(r.r+/s4    %  ! = 9  %r'r.c6eZdZdZdZdZdZdZdZdZ y) DummyChannel.SSLcyr7r&r8s r(abortConnectionz DummyChannel.SSL.abortConnectionT r'cyr7r&r8s r(getTcpKeepAlivez DummyChannel.SSL.getTcpKeepAliveXrVr'cyr7r&r8s r( getTcpNoDelayzDummyChannel.SSL.getTcpNoDelay\rVr'cyr7r&r8s r(loseWriteConnectionz$DummyChannel.SSL.loseWriteConnection`rVr'cyr7r&r3enableds r(setTcpKeepAlivez DummyChannel.SSL.setTcpKeepAlivedrVr'cyr7r&r^s r( setTcpNoDelayzDummyChannel.SSL.setTcpNoDelayhrVr'cyr7r&r8s r(getPeerCertificatez#DummyChannel.SSL.getPeerCertificatelrVr'N) r"r#r$rUrXrZr\r`rbrdr&r'r(SSLrSRs%       r'reNc0|j||_yr7)r. transportr2s r(r5zDummyChannel.__init__rs$r'cyr7r&)r3requests r( requestDonezDummyChannel.requestDoneu r'c|dz|zdz|zdz}|g}|jd|D|jd|jj|y)N  c38K|]\}}|dz|zdzyw)s: rnNr&).0namevalues r( z,DummyChannel.writeHeaders..{s"XudUlU2W<Xs)extendrHrgrC)r3versioncodereasonheaders response_lineheaderSequences r( writeHeaderszDummyChannel.writeHeadersxs[$-4v=G 'XPWXXg& $$^4r'c6|jjSr7)rgr9r8s r(r9zDummyChannel.getPeer~~%%''r'c6|jjSr7)rgrFr8s r(rFzDummyChannel.getHostr}r'c<|jj||yr7)rgrLrIs r(rLzDummyChannel.registerProducers '')r?s r(r>zDummyChannel.writes T"r'c:|jj|yr7)rgrC)r3rBs r(rCzDummyChannel.writeSequences $$U+r'c8|jjyr7)rgrQr8s r(rQzDummyChannel.loseConnections %%'r'cyr7r&r8s r( endRequestzDummyChannel.endRequestrkr'cBt|j|jSr7)r;rgrer8s r(isSecurezDummyChannel.isSecures$..$((33r'cyr7r&r8s r(rUzDummyChannel.abortConnection r'cyr7r&r8s r(rXzDummyChannel.getTcpKeepAliverr'cyr7r&r8s r(rZzDummyChannel.getTcpNoDelayrr'cyr7r&r8s r(r\z DummyChannel.loseWriteConnectionrr'cyr7r&r8s r(r`zDummyChannel.setTcpKeepAliverr'cyr7r&r8s r(rbzDummyChannel.setTcpNoDelayrr'cyr7r&r8s r(rdzDummyChannel.getPeerCertificaterr'r7)r"r#r$r.r rrerrsiter5rjr{r9rFrLrNr>rCrQrrrUrXrZr\r`rbrdr&r'r(rr.s!%!%Fc :  D( 5((=,#,( 4       r'c(eZdZUdZdZdZdZded<ded<ded <ded <d ed <d ed<dZdZ d+ d,dZ dZ dZ dZ d-dZdZdZd.dZdZdZdZd-dZdZdZeedd d!d"d#$d%Zd&Zd'Zd(Zd/d)Zd*Zy)0ra Represents a dummy or fake request. See L{twisted.web.server.Request}. @ivar _finishedDeferreds: L{None} or a C{list} of L{Deferreds} which will be called back with L{None} when C{finish} is called or which will be errbacked if C{processingFailed} is called. @type requestheaders: C{Headers} @ivar requestheaders: A Headers instance that stores values for all request headers. @type responseHeaders: C{Headers} @ivar responseHeaders: A Headers instance that stores values for all response headers. @type responseCode: C{int} @ivar responseCode: The response code which was passed to C{setResponseCode}. @type written: C{list} of C{bytes} @ivar written: The bytes which have been written to the request. s http://dummy/sGETNOptional[IAddress]clientz List[bytes]sitepathr0prepathzDict[bytes, List[bytes]]argszList[Deferred[None]]_finishedDeferredscfd|_|jr|j|jryy)z Call an L{IPullProducer}'s C{resumeProducing} method in a loop until it unregisters itself. @param prod: The producer. @type prod: L{IPullProducer} @param s: Whether or not the producer is streaming. N)goresumeProducing)r3prodss r(rLzDummyRequest.registerProducers'gg  "ggr'cd|_y)Nr)rr8s r(rNzDummyRequest.unregisterProducers r'cg|_g|_d|_||_g|_d|_|xst ddt|_i|_ t|_ t|_ d|_ g|_d|_d|_y)Nr0)ruidreactorsdummysHTTP/1.0)rr0finishedpostpathrsessionrr protoSessionrrrequestHeadersresponseHeaders responseCoder _serverName clientproto)r3rrrs r(r5zDummyRequest.__init__s        #TwDdEG'T %i&y "$#&r'czi}|jjD]\}}|d||j<|S)ah Return dictionary mapping the names of all received headers to the last value received for each. Since this method does not return all header information, C{self.requestHeaders.getAllRawHeaders()} may be preferred. NOTE: This function is a direct copy of C{twisted.web.http.Request.getAllRawHeaders}. )rgetAllRawHeaderslower)r3rxkvs r( getAllHeaderszDummyRequest.getAllHeaderssD''88: 'DAq!"2GAGGI  'r'c^|jj|jdgdS)aH Retrieve the value of a request header. @type name: C{bytes} @param name: The name of the request header for which to retrieve the value. Header names are compared case-insensitively. @rtype: C{bytes} or L{None} @return: The value of the specified request header. Nr)r getRawHeadersr)r3rqs r( getHeaderzDummyRequest.getHeaders*""00vFqIIr'c<|jj||y)zATODO: make this assert on write() if the header is content-lengthN)r addRawHeaderr3rqrrs r( setHeaderzDummyRequest.setHeaders ))$6r'c|jr |jS|jrJd|j|_|jS)Nz8Session cannot be requested after data has been written.)rr0r)r3sessionInterfaces r( getSessionzDummyRequest.getSession sC <<<<   F E F (( ||r'cz|j|}|tury|j||jy)a Render the given resource as a response to this request. This implementation only handles a few of the most common behaviors of resources. It can handle a render method that returns a string or C{NOT_DONE_YET}. It doesn't know anything about the semantics of request methods (eg HEAD) nor how to set any particular headers. Basically, it's largely broken, but sufficient for some tests at least. It should B{not} be expanded to do all the same stuff L{Request} does. Instead, L{DummyRequest} should be phased out and L{Request} (or some other real code factored in a different way) used. N)renderrr>finish)r3resourceresults r(rzDummyRequest.render)s2& \ !  6 r'cpt|ts td|jj |y)Nzwrite() only accepts bytes)r;r<r=r0rHr?s r(r>zDummyRequest.write<s*$&89 9 D!r'cPt}|jj||S)z Return a L{Deferred} which is called back with L{None} when the request is finished. This will probably only work if you haven't called C{finish} yet. )rrrH)r3rs r( notifyFinishzDummyRequest.notifyFinishAs$ $,: &&x0r'c|jdz|_|j,|j}d|_|D]}|jdyy)z} Record that the request is finished and callback and L{Deferred}s waiting for notification of this. rN)rrcallback)r3 observersobss r(rzDummyRequest.finishKsS  )  " " .//I&*D #  # T" # /r'ct|j,|j}d|_|D]}|j|yy)zK Errback and L{Deferreds} waiting for finish notification. N)rerrback)r3rwrrs r(processingFailedzDummyRequest.processingFailedWsC  " " .//I&*D #  $ F# $ /r'c$|g|j|<yr7)rrs r(addArgzDummyRequest.addArgas ' $r'c|jr/Jdjdj|j||_||_y)z{ Set the HTTP status response code, but takes care that this is called before any data is written. z;Response code cannot be set after data hasbeen written: {}.@@@@N)r0formatjoinrresponseMessage)r3rvmessages r(setResponseCodezDummyRequest.setResponseCodedsH   K R R KK %  !&r'cz|jr/Jdjdj|jy)Nz;;## #r'cF|j tS|jS)z Return the L{IAddress} of the client that made this request. @return: an address. @rtype: an L{IAddress} provider. )rr!r8s r(rzDummyRequest.getClientAddresss  ;; = {{r'c|jS)z Get a dummy hostname associated to the HTTP request. @rtype: C{bytes} @returns: a dummy hostname )rr8s r(getRequestHostnamezDummyRequest.getRequestHostnamesr'ctdddS)zz Get a dummy transport's host. @rtype: C{IPv4Address} @returns: a dummy transport's host r. 127.0.0.1r,)r r8s r(rFzDummyRequest.getHosts5+r22r'c||_|jrd}nd}||k(r|}nd||fz}|jjd|y)a_ Change the host and port the request thinks it's using. @type host: C{bytes} @param host: The value to which to change the host header. @type ssl: C{bool} @param ssl: A flag which, if C{True}, indicates that the request is considered secure (if C{True}, L{isSecure} will return C{True}). ir,s%b:%dshostN) _forceSSLrrr)r3rrEssldefault hostHeaders r(setHostzDummyRequest.setHostsN ==?GG 7?J!T4L0J ((*=r'cR|jt|jd|y)zu Utility function that does a redirect. The request should have finish() called after this. slocationN)rrr)r3urls r(redirectzDummyRequest.redirects U# {C(r')NN)rz list[bytes]rzOptional[Session]rrreturnNoner7)rzDeferred[None])r) r"r#r$r%urimethodr__annotations__rLrNr5rrrrrr>rrrrrrrrr rrrrFrrr&r'r(rrs. C F!%F %   "",, # &*%) ''#'# '  '* J7&"  #$" '   2q!,:LMN  3>,)r'c(eZdZdZdZdZdZdZy)DummyRequestTestsz$ Tests for L{DummyRequest}. c>tg}|j|j|jg}|j dt ||\}|j |j dt|j |j ddy)zp L{DummyRequest.getClientIP} is deprecated in favor of L{DummyRequest.getClientAddress} )offendingFunctionsrcategoryrz}twisted.web.test.requesthelper.DummyRequest.getClientIP was deprecated in Twisted 18.4.0; please use getClientAddress insteadN)rr flushWarningstest_getClientIPDeprecated assertEquallengetDeprecationWarning)r3riwarningswarnings r(rz,DummyRequestTests.test_getClientIPDeprecateds r"%% $ ? ?@&  CM*  Z02DE  KK "6 r'ctg}tddd}||_|jd|j y)z L{DummyRequest.getClientIP} supports IPv6 addresses, just like L{twisted.web.http.Request.getClientIP}. r.z::190N)rrrrr)r3rirs r(test_getClientIPSupportsIPv6z.DummyRequestTests.test_getClientIPSupportsIPv6s< r"UE51  3 3 56r'cntg}|j}tjt|y)zu L{DummyRequest.getClientAddress} returns an L{IAddress} provider no C{client} has been set. N)rrr verifyObjectr)r3rinulls r("test_getClientAddressWithoutClientz4DummyRequestTests.test_getClientAddressWithoutClients, r"'')Hd+r'ctg}tddd}||_|j}|j ||y)zI L{DummyRequest.getClientAddress} returns the C{client}. r.rrN)rr rrassertIs)r3riraddresss r(test_getClientAddressz'DummyRequestTests.test_getClientAddresss?r"UK7**, gv&r'N)r"r#r$r%rrr rr&r'r(rrs 2 7,'r'rN)1r% __future__r__all__iortypingrrr zope.interfacer r incrementalr twisted.internet.addressr rtwisted.internet.deferrtwisted.internet.interfacesrrtwisted.internet.taskrtwisted.python.deprecater twisted.trialrtwisted.web._responsesrtwisted.web.http_headersrtwisted.web.resourcertwisted.web.serverrrrtextLinearWhitespaceComponents sanitizedTextencodebytesLinearWhitespaceComponentssanitizedBytesr!rrSynchronousTestCaser)lw components00r(r's# > *''.=+?'/"(,):::N!OBCt3-!O /M#"+IW#%%g. X F F RL)L)^:'44:'Q "P#s 3 C4 C9