
    Yf;                        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j+                  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! Z3dS )"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dS )PythonScriptN)__name__
__module____qualname__sys
executablefilter     K/var/www/html/env/lib/python3.11/site-packages/twisted/web/test/test_cgi.pyr   r   b   s        ^FFFr!   r   c                        e Zd Zd Zd Zd ZdS )_StartServerAndTearDownMixinc                 :   t          j                    }t          j        t          |          }|                    dt          |                     t          j        |          }t          j
        d|          | _        | 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   su     "",x--fl733444{4  "1d++v~~$$r!   c                 Z    t          | dd           r| j                                        S d S )Nr,   )getattrr,   stopListening)r/   s    r"   tearDownz%_StartServerAndTearDownMixin.tearDowno   s4    4d## 	*6'')))	* 	*r!   c                     t           j                            |                                           }t	          |d          5 }|                    |           d d d            n# 1 swxY w Y   |S )Nwt)ospathabspathmktempopenwrite)r/   sourcecgiFilenamecgiFiles       r"   writeCGIz%_StartServerAndTearDownMixin.writeCGIs   s    goodkkmm44+t$$ 	"MM&!!!	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	"s   A$$A(+A(N)r   r   r   r4   r8   rD   r    r!   r"   r$   r$   f   sA        % % %* * *    r!   r$   c                       e Zd ZdZe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dS )CGITestsz,
    Tests for L{twcgi.FilteredScript}.
    z5CGI tests require a functional reactor.spawnProcess()c                 f   |                      t                    }|                     |          }d|fz  }|                    d          }t	          j        t                                        d|          }|                    t          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   s    mmI.."";//'7*4jj!!L!!))&#66	fo&&&	do&&&r!   c                 r    |                      |dt          j                            d          z              d S )Ns
   cgi outputrI   )assertEqualr;   lineseprL   )r/   ress     r"   rQ   zCGITests._testCGI_1   s3    mbj.?.?.H.HHIIIIIr!   c                 b                          t                    }                     |          }d|fz  }|                    d          }t	          j        t                    }|                    d|          }|                    t                      fd}|                    |           |S )zc
        If the CGI script emits a I{Server} or I{Date} header, these are
        ignored.
        rH   rI   rJ   c                                          d| j                            d                                          d| j                            d                     d S )Nmonkeysr   z	last yeardate)assertNotInheadersgetRawHeadersresponser/   s    r"   checkResponsez;CGITests.test_protectedServerAndDate.<locals>.checkResponse   sW    Y(8(F(Fx(P(PQQQ[(*:*H*H*P*PQQQQ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"";//'7*4jj!!W%%MM&#&&	k"""	R 	R 	R 	R 	R 	
m$$$r!   c                 b                          t                    }                     |          }d|fz  }|                    d          }t	          j        t                    }|                    d|          }|                    t                      fd}|                    |           |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                 f                         | j                            d          dg           | S )Nzcontent-typeztext/cgi-duplicate-testrW   r_   r`   ra   s    r"   rc   zBCGITests.test_noDuplicateContentTypeHeaders.<locals>.checkResponse   s<     ..~>>*+   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I"";//'7*4jj!!W%%MM&#&&	k"""	 	 	 	 	 	
m$$$r!   c                                           t                    }                     |          }d|fz  }|                    d          }t	          j        t                    }t          j        dgdgd          }|	                    d||          } fd}|
                    t          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        |                     d                    }                    t	          |                                          h d           d S )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   s\    j!9!9::GGLLNN##JJ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6"";//'7*4jj!!W%%&xx@@
 
 MM&#wM77	 	 	 	 	 	
fo&&&	m$$$r!   c                 b                          t                    }                     |          }d|fz  }|                    d          }t	          j        t                    }|                    d|          }|                    t                      fd}|                    |           |S )zp
        If a CGI script emits two instances of the same header, both are sent
        in the response.
        rH   rI   rJ   c                 h                         | j                            d          ddg           d S )Nheaderspameggsrk   ra   s    r"   rc   z7CGITests.test_duplicateHeaderCGI.<locals>.checkResponse   s6    X-;;HEEPVGWXXXXXr!   )
rD   DUAL_HEADER_CGIr4   rL   r   rM   r   rN   rO   re   rf   s   `      r"   test_duplicateHeaderCGIz CGITests.test_duplicateHeaderCGI   s    
 mmO44"";//'7*4jj!!W%%MM&#&&	k"""	Y 	Y 	Y 	Y 	Y 	
m$$$r!   c                                           t                    }                     |          }d|fz  }|                    d          }t	          j        t                    }|                    d|          }|                    t                     g fd}t          j        |                                t          j        |            fd}|                    |           |S )zF
        Check for the error message in the duplicated header
        rH   rI   rJ   c                 V                         t          j        |                      d S N)appendr
   textFromEventDict)	eventDictloggedMessagess    r"   
addMessagez4CGITests.test_malformedHeaderCGI.<locals>.addMessage   s(    !!#"7	"B"BCCCCCr!   c                 T                         dt          d          z              d S )Nzignoring malformed CGI header: s   XYZ)assertInrepr)ignoredr   r/   s    r"   rc   z7CGITests.test_malformedHeaderCGI.<locals>.checkResponse  s3    MM1DLL@.    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6"";//'7*4jj!!W%%MM&#&&	k"""	D 	D 	D 	D 	D 	
###*J777	 	 	 	 	 	
 	
m$$$r!   c                    t           j                            |                                           }t	          |d          5 }|                    t                     d d d            n# 1 swxY w Y   |                     |          }t          j	        t                    }d|fz  }|                    d          }|                    d|          }|                    t          j                   |                    | j                   |S )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   goodkkmm44+t$$ 	)MM-(((	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) "";//W%%'7*4jj!!MM&#&&	fo&&&	d1222   A))A-0A-   c                 z    dt           j         }|                    d          }|                     ||           d S Nzreadinput okrI   r;   rX   rL   rW   r/   rY   expecteds      r"   r   zCGITests._test_ReadEmptyInput_1  >    ."*..??7++h'''''r!   c           	      ^   t           j                            |                                           }t	          |d          5 }|                    t                     d d d            n# 1 swxY w Y   |                     |          }t          j	        t                    }d|fz  }|                    d          }|                    |dt          j        t          d                              }|                    t          j                   |                    | j                   |S 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  s7   goodkkmm44+t$$ 	)MM-(((	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) "";//W%%'7*4jj!!MM09N1O1OPP  
 

 	
fo&&&	d,---r   c                 z    dt           j         }|                    d          }|                     ||           d S r   r   r   s      r"   r   zCGITests._test_ReadInput_12  r   r!   c           	      Z   t           j                            |                                           }t	          |d          5 }|                    t                     d d d            n# 1 swxY w Y   |                     |          }d|fz  }|                    d          }t          j
        t                                        |dt          j        t          d                              }|                    t          j                   |                    | j                   |S 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  s5   goodkkmm44+t$$ 	,MM*+++	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, "";//'7*4jj!!L!!))09N1O1OPP * 
 

 	
fo&&&	d/000r   c                 z    dt           j         }|                    d          }|                     ||           d S )Nzreadallinput okrI   r   r   s      r"   r   zCGITests._test_ReadAllInput_1J  s>    1RZ11??7++h'''''r!   c                     G d d          } |            }t          ddg          }t          j        ddd          |_        t	          j        d|	          }t          ||           |                     |j                   d
S )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dS )5CGITests.test_useReactorArgument.<locals>.FakeReactorzR
            A fake reactor recording whether spawnProcess is called.
            Fc                     d| _         dS )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  s4          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  s    	# 	# 	# 	# 	# 	# 	# 	#  "kmmSz** ,UKGG'kJJ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   s4         %0099 GF	 	 	J J J  *  0  8  (  8   #$( ( (
  $ N( ( (
  " !"( ( (
, , , , ,r!   rF   c                   $    e Zd ZdZd Zd Zd ZdS )CGIScriptTestsz'
    Tests for L{twcgi.CGIScript}.
    c                 @   |                      t                    }|                     |          }d|fz  }t          j        t
                    }|                    d|          }|                    t          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  s    
 mm$566"";//3wj@W%%MM&#&&	fo&&&	d0111r!   c                 z    dt           j         }|                    d          }|                     ||           d S )Nz
param=1234rI   r   r   s      r"   r   z$CGIScriptTests._test_urlParameters_1  s>    ,
,,??7++h'''''r!   c                 >    G d d          } |            }t          j        |                                 |          }t          ddg          }t	          j        ddd          |_        t          ||           |                     |j	        d	         d
           dS )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dS )1CGIScriptTests.test_pathInfo.<locals>.FakeReactorzZ
            A fake reactor recording the environment passed to spawnProcess.
            c                     || _         dS )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  s    	' 	' 	' 	' 	' 	' 	' 	'" ;==?4;;==(CCCSz** ,UKGG'"""-k:FCCCCCr!   N)r   r   r   r   r   r   r   r    r!   r"   r   r   n  sP           ( ( (
D D D D Dr!   r   c                       e Zd ZdZd Zd ZdS )CGIDirectoryTestsz*
    Tests for L{twcgi.CGIDirectory}.
    c                      t          j                                                   }t          dg          t	          |          } fd}|                    |           |S )zc
        L{twcgi.CGIDirectory.render} sets the HTTP response code to I{NOT
        FOUND}.
         c                 H                         j        t                     d S r   rW   responseCoder   r   rN   r/   s    r"   
cbRenderedz1CGIDirectoryTests.test_render.<locals>.cbRendered  "    W19=====r!   )r   CGIDirectoryr>   r   r   rO   )r/   r   rT   r   rN   s   `   @r"   test_renderzCGIDirectoryTests.test_render  ss    
 %dkkmm44t$$Hg&&	> 	> 	> 	> 	> 	> 	
j!!!r!   c                                                       }t          j        |           t          j        |          }t          dg           |j        d          }t          |          } fd}|                    |           |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                 H                         j        t                     d S 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  s     {{}}
D%d++w''!!%1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dS )CGIProcessProtocolTestsz0
    Tests for L{twcgi.CGIProcessProtocol}.
    c                     t          dg          }t          j        |          }|                    t	          j        t          j                                         |                     |j	        t                     dS )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  sj     t$$+G44goe.E.G.GHHIII-/DEEEEEr!   c                 L   t                      }t          j        |d          }t          j        |          }|                    t          j        t          d                               |	                    t          j        t          j                                         dS )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  s    
 NN,q$''+G44w~>O/P/PQQRRRgoe.E.G.GHHIIIIIr!   N)r   r   r   r   r   r   r    r!   r"   r   r     sD         	F 	F 	F	J 	J 	J 	J 	Jr!   r   c                 X     t          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01C1C1C1CD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 1 1 1 1 1 - - - - - - - - - - " " " " " " K K K K K K K K K K K K K K K K = = = = = = = = * * * * * * E E E E E E E E	   ( $      5'          (q, q, q, q, q,+X-> q, q, q,h5D 5D 5D 5D 5D183D 5D 5D 5Dp& & & & &) & & &RJ J J J Jh/ J J J8E E E E Er!   