+
    Dfj;                        R t ^ RIt^ RIt^ RIt^ RIHt ^ RIHtHtH	t	H
t
 ^ RIHt ^ RIHtHt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 H!t! Rt"Rt#Rt$Rt%Rt&Rt'Rt(Rt)Rt* ! R R]PV                  4      t, ! R R4      t- ! R R]-]P\                  4      t/ ! R R]-]P\                  4      t0 ! R R]P\                  4      t1 ! R R]P\                  4      t2R  t3R# )!z!
Tests for L{twisted.web.twcgi}.
N)BytesIO)addresserror
interfacesreactor)ConnectionLost)failurelogutil)unittest)clienthttphttp_headersresourceservertwcgi)INTERNAL_SERVER_ERROR	NOT_FOUND)_render)DummyChannelDummyRequestz2print("Header: OK")
print("")
print("cgi output")
zJprint("Header: spam")
print("Header: eggs")
print("")
print("cgi output")
z+print("XYZ")
print("")
print("cgi output")
zPprint("Server: monkeys")
print("Date: last year")
print("")
print("cgi output")
a&  # This is an example of a correctly-written CGI script which reads a body
# from stdin, which only reads env['CONTENT_LENGTH'] bytes.

import os, sys

body_length = int(os.environ.get('CONTENT_LENGTH',0))
indata = sys.stdin.read(body_length)
print("Header: OK")
print("")
print("readinput ok")
a+  # This is an example of the typical (incorrect) CGI script which expects
# the server to close stdin when the body of the request is complete.
# A correct CGI should only read env['CONTENT_LENGTH'] bytes.

import sys

indata = sys.stdin.read()
print("Header: OK")
print("")
print("readallinput ok")
zMprint("content-type: text/cgi-duplicate-test")
print("")
print("cgi output")
zimport json
import os
print("")
print("")
vals = {x:y for x,y in os.environ.items() if x.startswith("HTTP_")}
print(json.dumps(vals))
z]import os
param = str(os.environ['QUERY_STRING'])
print("Header: OK")
print("")
print(param)
c                   .    ] tR t^bt]P
                  tRtR# )PythonScript N)__name__
__module____qualname____firstlineno__sys
executablefilter__static_attributes__r       ;/usr/lib/python3/dist-packages/twisted/web/test/test_cgi.pyr   r   b   s    ^^Fr"   r   c                   2   a  ] tR t^ft o R tR tR tRtV tR# )_StartServerAndTearDownMixinc                D   \         P                  ! 4       p\        P                  ! \        V4      pVP                  R \        V4      4       \        P                  ! V4      p\        P                  ! ^ V4      V n        V P                  P                  4       P                  # )s   cgi)r   Resourcer
   sibpath__file__putChildr   r   Siter   	listenTCPpgetHostport)selfcgirootcgipathsites   &&   r#   startServer(_StartServerAndTearDownMixin.startServerg   sl      ",,x-fl734{{4 ""1d+vv~~$$$r"   c                `    \        V R R4      '       d   V P                  P                  4       # R# )r-   N)getattrr-   stopListening)r0   s   &r#   tearDown%_StartServerAndTearDownMixin.tearDowno   s)    4d##66'')) $r"   c                    \         P                  P                  V P                  4       4      p\	        VR 4      ;_uu_ 4       pVP                  V4       RRR4       V#   + '       g   i     T# ; i)wtN)ospathabspathmktempopenwrite)r0   sourcecgiFilenamecgiFiles   &&  r#   writeCGI%_StartServerAndTearDownMixin.writeCGIs   sO    ggoodkkm4+t$$MM&! % %$s   AA/	)r-   N)	r   r   r   r   r5   r:   rG   r!   __classdictcell____classdict__s   @r#   r%   r%   f   s     %* r"   r%   c                      a  ] tR t^zt o Rt]P                  P                  ]4      '       g   Rt	R t
R tR tR tR tR tR	 tR
 t^]n        R tR t^]n        R tR t^]n        R tR tRtV tR# )CGITestsz$
Tests for L{twcgi.FilteredScript}.
z5CGI tests require a functional reactor.spawnProcess()c                P   V P                  \        4      pV P                  V4      pR V3,          pVP                  R4      p\        P
                  ! \        4      P                  RV4      pVP                  \        P                  4       VP                  V P                  4       V# )http://localhost:%d/cgiascii   GET)rG   	DUMMY_CGIr5   encoder   Agentr   requestaddCallbackreadBody
_testCGI_1)r0   rE   portnumurlds   &    r#   test_CGICGITests.test_CGI   sz    mmI."";/'7*4jj!LL!))&#6	foo&	doo&r"   c                r    V P                  VR \        P                  P                  R4      ,           4       R# )s
   cgi outputrP   N)assertEqualr>   lineseprS   )r0   ress   &&r#   rX   CGITests._testCGI_1   s&    mbjj.?.?.HHIr"   c                :  a  S P                  \        4      pS P                  V4      pRV3,          pVP                  R4      p\        P
                  ! \        4      pVP                  RV4      pVP                  \        4       V 3R lpVP                  V4       V# )zK
If the CGI script emits a I{Server} or I{Date} header, these are
ignored.
rO   rP   rQ   c                    < SP                  R V P                  P                  R4      4       SP                  RV P                  P                  R4      4       R# )monkeysr   z	last yeardateN)assertNotInheadersgetRawHeadersresponser0   s   &r#   checkResponse;CGITests.test_protectedServerAndDate.<locals>.checkResponse   sE    Y(8(8(F(Fx(PQ[(*:*:*H*H*PQr"   )
rG   SPECIAL_HEADER_CGIr5   rS   r   rT   r   rU   rV   discardBodyr0   rE   rY   rZ   agentr[   rl   s   f      r#   test_protectedServerAndDate$CGITests.test_protectedServerAndDate   s    
 mm$67"";/'7*4jj!W%MM&#&	k"	R 	
m$r"   c                :  a  S P                  \        4      pS P                  V4      pRV3,          pVP                  R4      p\        P
                  ! \        4      pVP                  RV4      pVP                  \        4       V 3R lpVP                  V4       V# )z
If the CGI script emits a I{content-type} header, make sure that the
server doesn't add an additional (duplicate) one, as per ticket 4786.
rO   rP   rQ   c                 `   < SP                  V P                  P                  R 4      R.4       V # )zcontent-typeztext/cgi-duplicate-testr_   rh   ri   rj   s   &r#   rl   BCGITests.test_noDuplicateContentTypeHeaders.<locals>.checkResponse   s2      ..~>*+ Or"   )
rG   $NO_DUPLICATE_CONTENT_TYPE_HEADER_CGIr5   rS   r   rT   r   rU   rV   ro   rp   s   f      r#   "test_noDuplicateContentTypeHeaders+CGITests.test_noDuplicateContentTypeHeaders   s    
 mm$HI"";/'7*4jj!W%MM&#&	k"	 	
m$r"   c                  a  S P                  \        4      pS P                  V4      pRV3,          pVP                  R4      p\        P
                  ! \        4      p\        P                  ! RR.RR./4      pVP                  RW5R7      pV 3R	 lpVP                  \        P                  4       VP                  V4       V# )
zF
The CGI script is never called with the Proxy header passed through.
rO   rP   s   Proxys   foos   X-Innocent-Headers   barrQ   )rh   c                    < \         P                  ! V P                  R 4      4      pSP                  \	        VP                  4       4      0 Rm4       R# )rP   N>   	HTTP_HOSTHTTP_CONNECTIONHTTP_X_INNOCENT_HEADER)jsonloadsdecoder_   setkeys)rk   rh   r0   s   & r#   rl   7CGITests.test_noProxyPassthrough.<locals>.checkResponse   s9    jj!9:GGLLN#Jr"   )rG   HEADER_OUTPUT_CGIr5   rS   r   rT   r   r   HeadersrU   rV   rW   )r0   rE   rY   rZ   rq   rh   r[   rl   s   f       r#   test_noProxyPassthrough CGITests.test_noProxyPassthrough   s     mm$56"";/'7*4jj!W%&&x!5x@
 MM&#M7	 	
foo&	m$r"   c                :  a  S P                  \        4      pS P                  V4      pRV3,          pVP                  R4      p\        P
                  ! \        4      pVP                  RV4      pVP                  \        4       V 3R lpVP                  V4       V# )zX
If a CGI script emits two instances of the same header, both are sent
in the response.
rO   rP   rQ   c                 b   < SP                  V P                  P                  R 4      RR.4       R# )headerspameggsNrv   rj   s   &r#   rl   7CGITests.test_duplicateHeaderCGI.<locals>.checkResponse   s*    X--;;HEPVGWXr"   )
rG   DUAL_HEADER_CGIr5   rS   r   rT   r   rU   rV   ro   rp   s   f      r#   test_duplicateHeaderCGI CGITests.test_duplicateHeaderCGI   s    
 mmO4"";/'7*4jj!W%MM&#&	k"	Y 	
m$r"   c                  a a S P                  \        4      pS P                  V4      pRV3,          pVP                  R4      p\        P
                  ! \        4      pVP                  RV4      pVP                  \        4       . oV3R lp\        P                  ! V4       S P                  \        P                  V4       VV 3R lpVP                  V4       V# )z6
Check for the error message in the duplicated header
rO   rP   rQ   c                 R   < SP                  \        P                  ! V 4      4       R # N)appendr	   textFromEventDict)	eventDictloggedMessagess   &r#   
addMessage4CGITests.test_malformedHeaderCGI.<locals>.addMessage   s    !!#"7"7	"BCr"   c                 L   < SP                  R \        R4      ,           S4       R# )zignoring malformed CGI header: s   XYZN)assertInrepr)ignoredr   r0   s   &r#   rl   7CGITests.test_malformedHeaderCGI.<locals>.checkResponse  s    MM1DL@.r"   )rG   BROKEN_HEADER_CGIr5   rS   r   rT   r   rU   rV   ro   r	   addObserver
addCleanupremoveObserver)	r0   rE   rY   rZ   rq   r[   r   rl   r   s	   f       @r#   test_malformedHeaderCGI CGITests.test_malformedHeaderCGI   s     mm$56"";/'7*4jj!W%MM&#&	k"	D 	
#**J7	
 	
m$r"   c                   \         P                  P                  V P                  4       4      p\	        VR 4      ;_uu_ 4       pVP                  \        4       RRR4       V P                  V4      p\        P                  ! \        4      pRV3,          pVP                  R4      pVP                  RV4      pVP                  \        P                  4       VP                  V P                  4       V#   + '       g   i     L; i)r=   NrO   rP   rQ   )r>   r?   r@   rA   rB   rC   READINPUT_CGIr5   r   rT   r   rS   rU   rV   rW   _test_ReadEmptyInput_1r0   rE   rF   rY   rq   rZ   r[   s   &      r#   test_ReadEmptyInputCGITests.test_ReadEmptyInput	  s    ggoodkkm4+t$$MM-( % "";/W%'7*4jj!MM&#&	foo&	d112 %$s   C44D	c                p    R \         P                   2pVP                  R4      pV P                  W4       R# zreadinput okrP   Nr>   r`   rS   r_   r0   ra   expecteds   && r#   r   CGITests._test_ReadEmptyInput_1  .    !"**.??7+'r"   c           	     L   \         P                  P                  V P                  4       4      p\	        VR 4      ;_uu_ 4       pVP                  \        4       RRR4       V P                  V4      p\        P                  ! \        4      pRV3,          pVP                  R4      pVP                  VR\        P                  ! \        R4      4      R7      pVP                  \        P                   4       VP                  V P"                  4       V#   + '       g   i     L; ir=   NrO   rP   s   POSTs   Here is your stdin)urimethodbodyProducer)r>   r?   r@   rA   rB   rC   r   r5   r   rT   r   rS   rU   FileBodyProducerr   rV   rW   _test_ReadInput_1r   s   &      r#   test_ReadInputCGITests.test_ReadInput  s    ggoodkkm4+t$$MM-( % "";/W%'7*4jj!MM009N1OP  

 	
foo&	d,,- %$s   DD#	c                p    R \         P                   2pVP                  R4      pV P                  W4       R# r   r   r   s   && r#   r   CGITests._test_ReadInput_12  r   r"   c           	     H   \         P                  P                  V P                  4       4      p\	        VR 4      ;_uu_ 4       pVP                  \        4       RRR4       V P                  V4      pRV3,          pVP                  R4      p\        P                  ! \        4      P                  VR\        P                  ! \        R4      4      R7      pVP                  \        P                   4       VP                  V P"                  4       V#   + '       g   i     L; ir   )r>   r?   r@   rA   rB   rC   READALLINPUT_CGIr5   rS   r   rT   r   rU   r   r   rV   rW   _test_ReadAllInput_1)r0   rE   rF   rY   rZ   r[   s   &     r#   test_ReadAllInputCGITests.test_ReadAllInput7  s    ggoodkkm4+t$$MM*+ % "";/'7*4jj!LL!))009N1OP * 

 	
foo&	d//0 %$s   DD!	c                p    R \         P                   2pVP                  R4      pV P                  W4       R# )zreadallinput okrP   Nr   r   s   && r#   r   CGITests._test_ReadAllInput_1J  s.    $RZZL1??7+'r"   c                     ! R R4      pV! 4       p\        RR.4      p\        P                  ! RRR4      Vn        \        P
                  ! RVR	7      p\        WC4       V P                  VP                  4       R
# )z_
L{twcgi.FilteredScript.runProcess} uses the reactor passed as an
argument to the constructor.
c                   .   a  ] tR tRt o RtRtR tRtV tR# )5CGITests.test_useReactorArgument.<locals>.FakeReactoriU  z:
A fake reactor recording whether spawnProcess is called.
Fc                    RV n         R# )z
Set the C{called} flag to C{True} if C{spawnProcess} is called.

@param args: Positional arguments.
@param kwargs: Keyword arguments.
TNcalled)r0   argskwargss   &*,r#   spawnProcessBCGITests.test_useReactorArgument.<locals>.FakeReactor.spawnProcess\  s     #r"   r   N)	r   r   r   r   __doc__r   r   r!   rI   rJ   s   @r#   FakeReactorr   U  s      F# #r"   r   abTCP	127.0.0.190  z
dummy-filer   N)	r   r   IPv4Addressr   r   FilteredScriptr   
assertTruer   )r0   r   fakeReactorrU   r   s   &    r#   test_useReactorArgument CGITests.test_useReactorArgumentO  se    	# 	#  "mSz* ,,UKG''kJ"**+r"   r   N)r   r   r   r   r   r   IReactorProcess
providedByr   skipr\   rX   rr   ry   r   r   r   r   timeoutr   r   r   r   r   r   r!   rI   rJ   s   @r#   rM   rM   z   s      %%0099F	J*08(8 #$(
$ N(
" !"(
, ,r"   rM   c                   6   a  ] tR tRt o RtR tR tR tRtV t	R# )CGIScriptTestsin  z
Tests for L{twcgi.CGIScript}.
c                2   V P                  \        4      pV P                  V4      pRV3,          p\        P                  ! \
        4      pVP                  RV4      pVP                  \        P                  4       VP                  V P                  4       V# )zS
If the CGI script is passed URL parameters, do not fall over,
as per ticket 9887.
s"   http://localhost:%d/cgi?param=1234rQ   )
rG   URL_PARAMETER_CGIr5   r   rT   r   rU   rV   rW   _test_urlParameters_1)r0   rE   rY   rZ   rq   r[   s   &     r#   test_urlParameters!CGIScriptTests.test_urlParameterss  st    
 mm$56"";/3wj@W%MM&#&	foo&	d001r"   c                p    R \         P                   2pVP                  R4      pV P                  W4       R# )z
param=1234rP   Nr   r   s   && r#   r   $CGIScriptTests._test_urlParameters_1  s.    

|,??7+'r"   c                $    ! R R4      pV! 4       p\         P                  ! V P                  4       VR7      p\        RR.4      p\        P
                  ! RRR4      Vn        \        W44       V P                  VP                  R	,          R
4       R# )z\
L{twcgi.CGIScript.render} sets the process environment
I{PATH_INFO} from the request path.
c                   *   a  ] tR tRt o RtR tRtV tR# )1CGIScriptTests.test_pathInfo.<locals>.FakeReactori  zB
A fake reactor recording the environment passed to spawnProcess.
c                    W@n         R# )z
Store the C{env} L{dict} to an instance attribute.

@param process: Ignored
@param filename: Ignored
@param args: Ignored
@param env: The environment L{dict} which will be stored
@param wdir: Ignored
Nprocess_env)r0   processfilenamer   envwdirs   &&&&&&r#   r   >CGIScriptTests.test_pathInfo.<locals>.FakeReactor.spawnProcess  s
     $' r"   r   N)r   r   r   r   r   r   r!   rI   rJ   s   @r#   r   r     s     
' 
'r"   r   r   r   r   r   r   r   	PATH_INFOz/a/bN)
r   	CGIScriptrA   r   r   r   r   r   r_   r   )r0   r   _reactorr   rU   s   &    r#   test_pathInfoCGIScriptTests.test_pathInfo  sr    	' 	'" =??4;;=(CSz* ,,UKG"--k:FCr"   r   N)
r   r   r   r   r   r   r   r   r!   rI   rJ   s   @r#   r   r   n  s      (
D Dr"   r   c                   0   a  ] tR tRt o RtR tR tRtV tR# )CGIDirectoryTestsi  z"
Tests for L{twcgi.CGIDirectory}.
c                   a a \         P                  ! S P                  4       4      p\        R.4      o\	        VS4      pVV 3R lpVP                  V4       V# )zK
L{twcgi.CGIDirectory.render} sets the HTTP response code to I{NOT
FOUND}.
 c                 H   < SP                  SP                  \        4       R # r   r_   responseCoder   r   rU   r0   s   &r#   
cbRendered1CGIDirectoryTests.test_render.<locals>.cbRendered      W119=r"   )r   CGIDirectoryrA   r   r   rV   )r0   r   r[   r  rU   s   f   @r#   test_renderCGIDirectoryTests.test_render  sK    
 %%dkkm4t$Hg&	> 	
j!r"   c                  a a S P                  4       p\        P                  ! V4       \        P                  ! V4      p\        R.4      oVP                  ! RS4      p\        VS4      pVV 3R lpVP                  V4       V# )z
L{twcgi.CGIDirectory.getChild} returns a resource which renders an
response with the HTTP I{NOT FOUND} status code if the indicated child
does not exist as an entry in the directory used to initialized the
L{twcgi.CGIDirectory}.
fooc                 H   < SP                  SP                  \        4       R # r   r   r  s   &r#   r  8CGIDirectoryTests.test_notFoundChild.<locals>.cbRendered  r  r"   )	rA   r>   makedirsr   r  r   getChildr   rV   )r0   r?   r   childr[   r  rU   s   f     @r#   test_notFoundChild$CGIDirectoryTests.test_notFoundChild  sn     {{}
D%%d+w'!!%1E7#	> 	
j!r"   r   N)	r   r   r   r   r   r  r  r!   rI   rJ   s   @r#   r   r     s      r"   r   c                   0   a  ] tR tRt o RtR tR tRtV tR# )CGIProcessProtocolTestsi  z(
Tests for L{twcgi.CGIProcessProtocol}.
c                    \        R.4      p\        P                  ! V4      pVP                  \        P
                  ! \        P                  ! 4       4      4       V P                  VP                  \        4       R# )z
If the process communicating with L{CGIProcessProtocol} ends before
finishing writing out headers, the response has I{INTERNAL SERVER
ERROR} as its status code.
r   N)r   r   CGIProcessProtocolprocessEndedr   Failurer   ProcessTerminatedr_   r  r   )r0   rU   protocols   &  r#   test_prematureEndOfHeaders2CGIProcessProtocolTests.test_prematureEndOfHeaders  sW     t$++G4gooe.E.E.GHI--/DEr"   c                @   \        4       p\        P                  ! VR4      p\        P                  ! V4      pVP                  \        P                  ! \        R4      4      4       VP                  \        P                  ! \        P                  ! 4       4      4       R# )zO
Ensure that the CGI process ends cleanly when the request connection
is lost.
TzConnection doneN)r   r   Requestr   r  connectionLostr   r  r   r  r   r  )r0   r[   rU   r  s   &   r#   test_connectionLost+CGIProcessProtocolTests.test_connectionLost  sh    
 N,,q$'++G4w~>O/PQRgooe.E.E.GHIr"   r   N)	r   r   r   r   r   r  r  r!   rI   rJ   s   @r#   r  r    s     	F	J 	Jr"   r  c                V   a  \         P                  ! S 4      P                  V 3R l4      # )z^
Discard the body of a HTTP response.

@param response: The response.

@return: The response.
c                    < S# r   r   )_rk   s   &r#   <lambda>discardBody.<locals>.<lambda>  s    8r"   )r   rW   rV   )rk   s   fr#   ro   ro     s      ??8$001CDDr"   )4r   r   r>   r   ior   twisted.internetr   r   r   r   twisted.internet.errorr   twisted.pythonr   r	   r
   twisted.trialr   twisted.webr   r   r   r   r   r   twisted.web.httpr   r   twisted.web.test._utilr   twisted.web.test.requesthelperr   r   rR   r   r   rn   r   r   rx   r   r   r   r   r%   TestCaserM   r   r   r  ro   r   r"   r#   <module>r0     s     	 
  @ @ 1 - - " K K = * E	   ( $  5''  (q,+X->-> q,h5D183D3D 5Dp&)) &RJh// J8Er"   