
    Vh;                        d Z ddlZddlZddlZddlmZ ddlmZmZm	Z	m
Z
 ddlmZ ddlmZmZmZ ddlmZ ddlmZmZmZmZmZmZ dd	lmZmZ dd
lmZ ddlm Z m!Z! dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ* G d dejV                        Z, G d d      Z- G d de-ej\                        Z/ G d de-ej\                        Z0 G d dej\                        Z1 G d d ej\                        Z2d! Z3y)"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                   $    e Zd Zej                  Zy)PythonScriptN)__name__
__module____qualname__sys
executablefilter     I/home/dcms/DCMS/lib/python3.12/site-packages/twisted/web/test/test_cgi.pyr   r   b   s    ^^Fr!   r   c                       e Zd Zd Zd Zd Zy)_StartServerAndTearDownMixinc                 <   t        j                         }t        j                  t        |      }|j                  dt        |             t        j                  |      }t        j                  d|      | _        | j                  j                         j                  S )Ns   cgir   )r   Resourcer   sibpath__file__putChildr   r   Siter   	listenTCPpgetHostport)selfcgirootcgipathsites        r"   startServerz(_StartServerAndTearDownMixin.startServerg   sl      ",,x-fl734{{4 ""1d+vv~~$$$r!   c                 R    t        | dd       r| j                  j                         S y )Nr,   )getattrr,   stopListening)r/   s    r"   tearDownz%_StartServerAndTearDownMixin.tearDowno   s&    4d#66'')) $r!   c                     t         j                  j                  | j                               }t	        |d      5 }|j                  |       d d d        |S # 1 sw Y   |S xY w)Nwt)ospathabspathmktempopenwrite)r/   sourcecgiFilenamecgiFiles       r"   writeCGIz%_StartServerAndTearDownMixin.writeCGIs   sN    ggoodkkm4+t$ 	"MM&!	"	"s   AA N)r   r   r   r4   r8   rD   r    r!   r"   r$   r$   f   s    %*r!   r$   c                       e Zd ZdZej
                  j                  e      sdZd Z	d Z
d Zd Zd Zd Zd	 Zd
 Zde_        d Zd Zde_        d Zd Zde_        d Zd Zy)CGITestsz,
    Tests for L{twcgi.FilteredScript}.
    z5CGI tests require a functional reactor.spawnProcess()c                 F   | j                  t              }| j                  |      }d|fz  }|j                  d      }t	        j
                  t              j                  d|      }|j                  t        j                         |j                  | j                         |S )Nhttp://localhost:%d/cgiascii   GET)rD   	DUMMY_CGIr4   encoder   Agentr   requestaddCallbackreadBody
_testCGI_1)r/   rB   portnumurlds        r"   test_CGIzCGITests.test_CGI   sz    mmI."";/'7*4jj!LL!))&#6	foo&	doo&r!   c                 h    | j                  |dt        j                  j                  d      z          y )Ns
   cgi outputrI   )assertEqualr;   lineseprL   )r/   ress     r"   rQ   zCGITests._testCGI_1   s&    mbjj.?.?.HHIr!   c                 .     j                  t              } j                  |      }d|fz  }|j                  d      }t	        j
                  t              }|j                  d|      }|j                  t                fd}|j                  |       |S )zc
        If the CGI script emits a I{Server} or I{Date} header, these are
        ignored.
        rH   rI   rJ   c                     j                  d| j                  j                  d             j                  d| j                  j                  d             y )Nmonkeysr   z	last yeardate)assertNotInheadersgetRawHeadersresponser/   s    r"   checkResponsez;CGITests.test_protectedServerAndDate.<locals>.checkResponse   sE    Y(8(8(F(Fx(PQ[(*:*:*H*H*PQr!   )
rD   SPECIAL_HEADER_CGIr4   rL   r   rM   r   rN   rO   discardBodyr/   rB   rR   rS   agentrT   rc   s   `      r"   test_protectedServerAndDatez$CGITests.test_protectedServerAndDate   s    
 mm$67"";/'7*4jj!W%MM&#&	k"	R 	
m$r!   c                 .     j                  t              } j                  |      }d|fz  }|j                  d      }t	        j
                  t              }|j                  d|      }|j                  t                fd}|j                  |       |S )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.
        rH   rI   rJ   c                 `    j                  | j                  j                  d      dg       | S )Nzcontent-typeztext/cgi-duplicate-testrW   r_   r`   ra   s    r"   rc   zBCGITests.test_noDuplicateContentTypeHeaders.<locals>.checkResponse   s2      ..~>*+ Or!   )
rD   $NO_DUPLICATE_CONTENT_TYPE_HEADER_CGIr4   rL   r   rM   r   rN   rO   re   rf   s   `      r"   "test_noDuplicateContentTypeHeadersz+CGITests.test_noDuplicateContentTypeHeaders   s    
 mm$HI"";/'7*4jj!W%MM&#&	k"	 	
m$r!   c                 z     j                  t              } j                  |      }d|fz  }|j                  d      }t	        j
                  t              }t        j                  dgdgd      }|j                  d||      } fd}|j                  t        j                         |j                  |       |S )	zV
        The CGI script is never called with the Proxy header passed through.
        rH   rI   s   foos   bar)s   Proxys   X-Innocent-HeaderrJ   )r_   c                     t        j                  | j                  d            }j                  t	        |j                               h d       y )NrI   >   	HTTP_HOSTHTTP_CONNECTIONHTTP_X_INNOCENT_HEADER)jsonloadsdecoderW   setkeys)rb   r_   r/   s     r"   rc   z7CGITests.test_noProxyPassthrough.<locals>.checkResponse   s9    jj!9:GGLLN#Jr!   )rD   HEADER_OUTPUT_CGIr4   rL   r   rM   r   r   HeadersrN   rO   rP   )r/   rB   rR   rS   rg   r_   rT   rc   s   `       r"   test_noProxyPassthroughz CGITests.test_noProxyPassthrough   s     mm$56"";/'7*4jj!W%&&xx@
 MM&#wM7	 	
foo&	m$r!   c                 .     j                  t              } j                  |      }d|fz  }|j                  d      }t	        j
                  t              }|j                  d|      }|j                  t                fd}|j                  |       |S )zp
        If a CGI script emits two instances of the same header, both are sent
        in the response.
        rH   rI   rJ   c                 `    j                  | j                  j                  d      ddg       y )Nheaderspameggsrk   ra   s    r"   rc   z7CGITests.test_duplicateHeaderCGI.<locals>.checkResponse   s*    X--;;HEPVGWXr!   )
rD   DUAL_HEADER_CGIr4   rL   r   rM   r   rN   rO   re   rf   s   `      r"   test_duplicateHeaderCGIz CGITests.test_duplicateHeaderCGI   s    
 mmO4"";/'7*4jj!W%MM&#&	k"	Y 	
m$r!   c                      j                  t              } j                  |      }d|fz  }|j                  d      }t	        j
                  t              }|j                  d|      }|j                  t               g fd}t        j                  |        j                  t        j                  |        fd}|j                  |       |S )zF
        Check for the error message in the duplicated header
        rH   rI   rJ   c                 N    j                  t        j                  |              y N)appendr
   textFromEventDict)	eventDictloggedMessagess    r"   
addMessagez4CGITests.test_malformedHeaderCGI.<locals>.addMessage   s    !!#"7"7	"BCr!   c                 B    j                  dt        d      z          y )Nzignoring malformed CGI header: s   XYZ)assertInrepr)ignoredr   r/   s    r"   rc   z7CGITests.test_malformedHeaderCGI.<locals>.checkResponse  s    MM1DL@.r!   )rD   BROKEN_HEADER_CGIr4   rL   r   rM   r   rN   rO   re   r
   addObserver
addCleanupremoveObserver)	r/   rB   rR   rS   rg   rT   r   rc   r   s	   `       @r"   test_malformedHeaderCGIz CGITests.test_malformedHeaderCGI   s     mm$56"";/'7*4jj!W%MM&#&	k"	D 	
#**J7	
 	
m$r!   c                    t         j                  j                  | j                               }t	        |d      5 }|j                  t               d d d        | j                  |      }t        j                  t              }d|fz  }|j                  d      }|j                  d|      }|j                  t        j                         |j                  | j                         |S # 1 sw Y   xY w)Nr:   rH   rI   rJ   )r;   r<   r=   r>   r?   r@   READINPUT_CGIr4   r   rM   r   rL   rN   rO   rP   _test_ReadEmptyInput_1r/   rB   rC   rR   rg   rS   rT   s          r"   test_ReadEmptyInputzCGITests.test_ReadEmptyInput	  s    ggoodkkm4+t$ 	)MM-(	) "";/W%'7*4jj!MM&#&	foo&	d112	) 	)s   C''C0   c                 p    dt         j                   }|j                  d      }| j                  ||       y Nzreadinput okrI   r;   rX   rL   rW   r/   rY   expecteds      r"   r   zCGITests._test_ReadEmptyInput_1  0    !"**.??7+h'r!   c           	      "   t         j                  j                  | j                               }t	        |d      5 }|j                  t               d d d        | j                  |      }t        j                  t              }d|fz  }|j                  d      }|j                  |dt        j                  t        d                  }|j                  t        j                          |j                  | j"                         |S # 1 sw Y   xY wNr:   rH   rI   s   POSTs   Here is your stdin)urimethodbodyProducer)r;   r<   r=   r>   r?   r@   r   r4   r   rM   r   rL   rN   FileBodyProducerr   rO   rP   _test_ReadInput_1r   s          r"   test_ReadInputzCGITests.test_ReadInput  s    ggoodkkm4+t$ 	)MM-(	) "";/W%'7*4jj!MM009N1OP  

 	
foo&	d,,-	) 	)s   DDc                 p    dt         j                   }|j                  d      }| j                  ||       y r   r   r   s      r"   r   zCGITests._test_ReadInput_12  r   r!   c           	         t         j                  j                  | j                               }t	        |d      5 }|j                  t               d d d        | j                  |      }d|fz  }|j                  d      }t        j                  t              j                  |dt        j                  t        d                  }|j                  t        j                          |j                  | j"                         |S # 1 sw Y   xY wr   )r;   r<   r=   r>   r?   r@   READALLINPUT_CGIr4   rL   r   rM   r   rN   r   r   rO   rP   _test_ReadAllInput_1)r/   rB   rC   rR   rS   rT   s         r"   test_ReadAllInputzCGITests.test_ReadAllInput7  s    ggoodkkm4+t$ 	,MM*+	, "";/'7*4jj!LL!))009N1OP * 

 	
foo&	d//0	, 	,s   DDc                 p    dt         j                   }|j                  d      }| j                  ||       y )Nzreadallinput okrI   r   r   s      r"   r   zCGITests._test_ReadAllInput_1J  s0    $RZZL1??7+h'r!   c                      G d d      } |       }t        ddg      }t        j                  ddd      |_        t	        j
                  d|	      }t        ||       | j                  |j                         y
)zw
        L{twcgi.FilteredScript.runProcess} uses the reactor passed as an
        argument to the constructor.
        c                       e Zd ZdZdZd Zy)5CGITests.test_useReactorArgument.<locals>.FakeReactorzR
            A fake reactor recording whether spawnProcess is called.
            Fc                     d| _         y)z
                Set the C{called} flag to C{True} if C{spawnProcess} is called.

                @param args: Positional arguments.
                @param kwargs: Keyword arguments.
                TN)called)r/   argskwargss      r"   spawnProcesszBCGITests.test_useReactorArgument.<locals>.FakeReactor.spawnProcess\  s     #r!   N)r   r   r   __doc__r   r   r    r!   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   )r/   r   fakeReactorrN   r   s        r"   test_useReactorArgumentz CGITests.test_useReactorArgumentO  sg    	# 	#  "mSz* ,,UKG''kJ'"**+r!   N)r   r   r   r   r   IReactorProcess
providedByr   skiprU   rQ   rh   rm   rz   r   r   r   timeoutr   r   r   r   r   r   r    r!   r"   rF   rF   z   s     %%009F	J*08(8 #$(
$ N(
" !"(
,r!   rF   c                   "    e Zd ZdZd Zd Zd Zy)CGIScriptTestsz'
    Tests for L{twcgi.CGIScript}.
    c                 (   | j                  t              }| j                  |      }d|fz  }t        j                  t
              }|j                  d|      }|j                  t        j                         |j                  | j                         |S )zk
        If the CGI script is passed URL parameters, do not fall over,
        as per ticket 9887.
        s"   http://localhost:%d/cgi?param=1234rJ   )
rD   URL_PARAMETER_CGIr4   r   rM   r   rN   rO   rP   _test_urlParameters_1)r/   rB   rR   rS   rg   rT   s         r"   test_urlParametersz!CGIScriptTests.test_urlParameterss  st    
 mm$56"";/3wj@W%MM&#&	foo&	d001r!   c                 p    dt         j                   }|j                  d      }| j                  ||       y )Nz
param=1234rI   r   r   s      r"   r   z$CGIScriptTests._test_urlParameters_1  s0    

|,??7+h'r!   c                     G d d      } |       }t        j                  | j                         |      }t        ddg      }t	        j
                  ddd      |_        t        ||       | j                  |j                  d	   d
       y)zt
        L{twcgi.CGIScript.render} sets the process environment
        I{PATH_INFO} from the request path.
        c                       e Zd ZdZd Zy)1CGIScriptTests.test_pathInfo.<locals>.FakeReactorzZ
            A fake reactor recording the environment passed to spawnProcess.
            c                     || _         y)a9  
                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)r/   processfilenamer   envwdirs         r"   r   z>CGIScriptTests.test_pathInfo.<locals>.FakeReactor.spawnProcess  s     $' r!   N)r   r   r   r   r   r    r!   r"   r   r     s    
'r!   r   r   r   r   r   r   r   	PATH_INFOz/a/bN)
r   	CGIScriptr>   r   r   r   r   r   rW   r   )r/   r   _reactorr   rN   s        r"   test_pathInfozCGIScriptTests.test_pathInfo  st    	' 	'" =??4;;=(CSz* ,,UKG'"--k:FCr!   N)r   r   r   r   r   r   r   r    r!   r"   r   r   n  s    (
Dr!   r   c                       e Zd ZdZd Zd Zy)CGIDirectoryTestsz*
    Tests for L{twcgi.CGIDirectory}.
    c                      t        j                   j                               }t        dg      t	        |      } fd}|j                  |       |S )zc
        L{twcgi.CGIDirectory.render} sets the HTTP response code to I{NOT
        FOUND}.
         c                 F    j                  j                  t               y r   rW   responseCoder   r   rN   r/   s    r"   
cbRenderedz1CGIDirectoryTests.test_render.<locals>.cbRendered      W119=r!   )r   CGIDirectoryr>   r   r   rO   )r/   r   rT   r   rN   s   `   @r"   test_renderzCGIDirectoryTests.test_render  sK    
 %%dkkm4t$Hg&	> 	
j!r!   c                      j                         }t        j                  |       t        j                  |      }t        dg       |j                  d      }t        |      } fd}|j                  |       |S )a  
        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                 F    j                  j                  t               y r   r   r   s    r"   r   z8CGIDirectoryTests.test_notFoundChild.<locals>.cbRendered  r   r!   )	r>   r;   makedirsr   r   r   getChildr   rO   )r/   r<   r   childrT   r   rN   s   `     @r"   test_notFoundChildz$CGIDirectoryTests.test_notFoundChild  sp     {{}
D%%d+w'!!!%1E7#	> 	
j!r!   N)r   r   r   r   r   r   r    r!   r"   r   r     s    r!   r   c                       e Zd ZdZd Zd Zy)CGIProcessProtocolTestsz0
    Tests for L{twcgi.CGIProcessProtocol}.
    c                     t        dg      }t        j                  |      }|j                  t	        j
                  t        j                                      | j                  |j                  t               y)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   ProcessTerminatedrW   r   r   )r/   rN   protocols      r"   test_prematureEndOfHeadersz2CGIProcessProtocolTests.test_prematureEndOfHeaders  sW     t$++G4gooe.E.E.GHI--/DEr!   c                 4   t               }t        j                  |d      }t        j                  |      }|j                  t        j                  t        d                   |j                  t        j                  t        j                                      y)zg
        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   )r/   rT   rN   r   s       r"   test_connectionLostz+CGIProcessProtocolTests.test_connectionLost  sh    
 N,,q$'++G4w~>O/PQRgooe.E.E.GHIr!   N)r   r   r   r   r   r   r    r!   r"   r   r     s    	F	Jr!   r   c                 R     t        j                         j                   fd      S )zn
    Discard the body of a HTTP response.

    @param response: The response.

    @return: The response.
    c                     S r   r    )_rb   s    r"   <lambda>zdiscardBody.<locals>.<lambda>  s    8 r!   )r   rP   rO   )rb   s   `r"   re   re     s      ??8$001CDDr!   )4r   rs   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   rK   r   r   rd   r   r   rl   rx   r   r   r   r$   TestCaserF   r   r   r   re   r    r!   r"   <module>r     s     	 
  @ @ 1 - - " K K = * E	   ( $  5''  (q,+X->-> q,h5D183D3D 5Dp&)) &RJh// J8Er!   