o
    Óó·i;  ã                   @   sT  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„ dej+ƒZ,G dd„ dƒZ-G dd„ de-ej.ƒZ/G dd„ de-ej.ƒZ0G dd„ dej.ƒZ1G dd „ d ej.ƒZ2d!d"„ 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")
z†import 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                   @   s   e Zd ZejZdS )ÚPythonScriptN)Ú__name__Ú
__module__Ú__qualname__ÚsysÚ
executableÚfilter© r   r   ú_C:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\twisted/web/test/test_cgi.pyr   b   s    
r   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )Ú_StartServerAndTearDownMixinc                 C   sH   t  ¡ }t t|¡}| dt|ƒ¡ t |¡}t	 
d|¡| _| j ¡ jS )Ns   cgir   )r   ÚResourcer
   ZsibpathÚ__file__ZputChildr   r   ZSiter   Z	listenTCPÚpZgetHostÚport)ÚselfÚcgiÚrootZcgipathÚsiter   r   r   ÚstartServerg   s   
z(_StartServerAndTearDownMixin.startServerc                 C   s   t | dd ƒr| j ¡ S d S )Nr#   )Úgetattrr#   ÚstopListening©r%   r   r   r   ÚtearDowno   s   
ÿz%_StartServerAndTearDownMixin.tearDownc                 C   sJ   t j |  ¡ ¡}t|dƒ�}| |¡ W d   ƒ |S 1 sw   Y  |S )NÚwt)ÚosÚpathÚabspathÚmktempÚopenÚwrite)r%   ÚsourceÚcgiFilenameÚcgiFiler   r   r   ÚwriteCGIs   s   
ÿþz%_StartServerAndTearDownMixin.writeCGIN)r   r   r   r)   r-   r8   r   r   r   r   r    f   s    r    c                   @   s¢   e Zd ZdZej e¡sdZdd„ Z	dd„ Z
dd„ Zd	d
„ Zdd„ Zdd„ Zdd„ Zdd„ Zde_dd„ Zdd„ Zde_dd„ Zdd„ Zde_dd„ Zdd„ Zd S )!ÚCGITestsz,
    Tests for L{twcgi.FilteredScript}.
    z5CGI tests require a functional reactor.spawnProcess()c                 C   sV   |   t¡}|  |¡}d|f }| d¡}t t¡ d|¡}| tj	¡ | | j
¡ |S )Núhttp://localhost:%d/cgiÚasciió   GET)r8   Ú	DUMMY_CGIr)   Úencoder   ÚAgentr   ÚrequestÚaddCallbackÚreadBodyÚ
_testCGI_1)r%   r6   ÚportnumÚurlÚdr   r   r   Útest_CGI‚   s   



zCGITests.test_CGIc                 C   s   |   |dtj d¡ ¡ d S )Ns
   cgi outputr;   )ÚassertEqualr/   Úlinesepr>   )r%   Úresr   r   r   rC   �   ó   zCGITests._testCGI_1c                    ób   ˆ   t¡}ˆ  |¡}d|f }| d¡}t t¡}| d|¡}| t	¡ ‡ fdd„}| |¡ |S )zc
        If the CGI script emits a I{Server} or I{Date} header, these are
        ignored.
        r:   r;   r<   c                    s,   ˆ   d| j d¡¡ ˆ   d| j d¡¡ d S )NZmonkeysr   z	last yearÚdate)ZassertNotInÚheadersÚgetRawHeaders©Úresponser,   r   r   ÚcheckResponsež   s   z;CGITests.test_protectedServerAndDate.<locals>.checkResponseN)
r8   ÚSPECIAL_HEADER_CGIr)   r>   r   r?   r   r@   rA   ÚdiscardBody©r%   r6   rD   rE   ÚagentrF   rR   r   r,   r   Útest_protectedServerAndDate�   s   






z$CGITests.test_protectedServerAndDatec                    rL   )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.
        r:   r;   r<   c                    s   ˆ   | j d¡dg¡ | S )Nzcontent-typeztext/cgi-duplicate-test©rH   rN   rO   rP   r,   r   r   rR   ³   s
   
þzBCGITests.test_noDuplicateContentTypeHeaders.<locals>.checkResponseN)
r8   Ú$NO_DUPLICATE_CONTENT_TYPE_HEADER_CGIr)   r>   r   r?   r   r@   rA   rT   rU   r   r,   r   Ú"test_noDuplicateContentTypeHeaders¥   s   






z+CGITests.test_noDuplicateContentTypeHeadersc                    s|   ˆ   t¡}ˆ  |¡}d|f }| d¡}t t¡}t dgdgdœ¡}|j	d||d�}‡ fdd	„}| 
tj¡ | 
|¡ |S )zV
        The CGI script is never called with the Proxy header passed through.
        r:   r;   s   foos   bar)s   Proxys   X-Innocent-Headerr<   )rN   c                    s,   t  |  d¡¡}ˆ  t| ¡ ƒh d£¡ d S )Nr;   >   Z	HTTP_HOSTZHTTP_CONNECTIONZHTTP_X_INNOCENT_HEADER)ÚjsonÚloadsÚdecoderH   ÚsetÚkeys)rQ   rN   r,   r   r   rR   Î   s
   
þz7CGITests.test_noProxyPassthrough.<locals>.checkResponseN)r8   ÚHEADER_OUTPUT_CGIr)   r>   r   r?   r   r   ZHeadersr@   rA   rB   )r%   r6   rD   rE   rV   rN   rF   rR   r   r,   r   Útest_noProxyPassthrough½   s   




ÿ
z CGITests.test_noProxyPassthroughc                    rL   )zp
        If a CGI script emits two instances of the same header, both are sent
        in the response.
        r:   r;   r<   c                    s   ˆ   | j d¡ddg¡ d S )NÚheaderZspamÚeggsrX   rP   r,   r   r   rR   ç   rK   z7CGITests.test_duplicateHeaderCGI.<locals>.checkResponseN)
r8   ÚDUAL_HEADER_CGIr)   r>   r   r?   r   r@   rA   rT   rU   r   r,   r   Útest_duplicateHeaderCGIÙ   s   






z CGITests.test_duplicateHeaderCGIc                    sŒ   ˆ  t¡}ˆ |¡}d|f }| d¡}t t¡}| d|¡}| t	¡ g ‰ ‡ fdd„}t
 |¡ ˆ t
j|¡ ‡ ‡fdd„}| |¡ |S )	zF
        Check for the error message in the duplicated header
        r:   r;   r<   c                    s   ˆ   t | ¡¡ d S ©N)Úappendr	   ZtextFromEventDict)Z	eventDict)ÚloggedMessagesr   r   Ú
addMessageû   s   z4CGITests.test_malformedHeaderCGI.<locals>.addMessagec                    s   ˆ  dtdƒ ˆ ¡ d S )Nzignoring malformed CGI header: s   XYZ)ZassertInÚrepr©Zignored©rh   r%   r   r   rR     s   ÿz7CGITests.test_malformedHeaderCGI.<locals>.checkResponseN)r8   ÚBROKEN_HEADER_CGIr)   r>   r   r?   r   r@   rA   rT   r	   ZaddObserverZ
addCleanupZremoveObserver)r%   r6   rD   rE   rV   rF   ri   rR   r   rl   r   Útest_malformedHeaderCGIí   s   







z CGITests.test_malformedHeaderCGIc                 C   s”   t j |  ¡ ¡}t|dƒ�}| t¡ W d   ƒ n1 sw   Y  |  |¡}t 	t
¡}d|f }| d¡}| d|¡}| tj¡ | | j¡ |S )Nr.   r:   r;   r<   )r/   r0   r1   r2   r3   r4   ÚREADINPUT_CGIr)   r   r?   r   r>   r@   rA   rB   Ú_test_ReadEmptyInput_1©r%   r6   r7   rD   rV   rE   rF   r   r   r   Útest_ReadEmptyInput	  s   ÿ



zCGITests.test_ReadEmptyInputé   c                 C   ó&   dt j› �}| d¡}|  ||¡ d S ©Nzreadinput okr;   ©r/   rI   r>   rH   ©r%   rJ   Úexpectedr   r   r   rp     ó   
zCGITests._test_ReadEmptyInput_1c                 C   s¢   t j |  ¡ ¡}t|dƒ�}| t¡ W d   ƒ n1 sw   Y  |  |¡}t 	t
¡}d|f }| d¡}|j|dt tdƒ¡d�}| tj¡ | | j¡ |S ©Nr.   r:   r;   s   POSTs   Here is your stdin)ÚuriÚmethodZbodyProducer)r/   r0   r1   r2   r3   r4   ro   r)   r   r?   r   r>   r@   ÚFileBodyProducerr   rA   rB   Ú_test_ReadInput_1rq   r   r   r   Útest_ReadInput  s    ÿ



ýzCGITests.test_ReadInputc                 C   rt   ru   rv   rw   r   r   r   r~   2  ry   zCGITests._test_ReadInput_1c                 C   sž   t j |  ¡ ¡}t|dƒ�}| t¡ W d   ƒ n1 sw   Y  |  |¡}d|f }| d¡}t	 
t¡j|dt	 tdƒ¡d�}| t	j¡ | | j¡ |S rz   )r/   r0   r1   r2   r3   r4   ÚREADALLINPUT_CGIr)   r>   r   r?   r   r@   r}   r   rA   rB   Ú_test_ReadAllInput_1)r%   r6   r7   rD   rE   rF   r   r   r   Útest_ReadAllInput7  s   ÿ



ýzCGITests.test_ReadAllInputc                 C   rt   )Nzreadallinput okr;   rv   rw   r   r   r   r�   J  ry   zCGITests._test_ReadAllInput_1c                 C   sX   G dd„ dƒ}|ƒ }t ddgƒ}t ddd¡|_tjd|d	�}t||ƒ |  |j¡ d
S )zw
        L{twcgi.FilteredScript.runProcess} uses the reactor passed as an
        argument to the constructor.
        c                   @   s   e Zd ZdZdZdd„ ZdS )z5CGITests.test_useReactorArgument.<locals>.FakeReactorzR
            A fake reactor recording whether spawnProcess is called.
            Fc                 _   s
   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Úkwargsr   r   r   ÚspawnProcess\  s   
zBCGITests.test_useReactorArgument.<locals>.FakeReactor.spawnProcessN)r   r   r   Ú__doc__rƒ   r†   r   r   r   r   ÚFakeReactorU  s    rˆ   ÚaÚbÚTCPú	127.0.0.1é90  z
dummy-file©r   N)	r   r   ÚIPv4Addressr   r   ÚFilteredScriptr   Ú
assertTruerƒ   )r%   rˆ   ZfakeReactorr@   r   r   r   r   Útest_useReactorArgumentO  s   
z CGITests.test_useReactorArgumentN)r   r   r   r‡   r   ZIReactorProcessZ
providedByr   ÚskiprG   rC   rW   rZ   ra   re   rn   rr   Útimeoutrp   r   r~   r‚   r�   r’   r   r   r   r   r9   z   s*    r9   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚCGIScriptTestsz'
    Tests for L{twcgi.CGIScript}.
    c                 C   sP   |   t¡}|  |¡}d|f }t 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=1234r<   N)
r8   ÚURL_PARAMETER_CGIr)   r   r?   r   r@   rA   rB   Ú_test_urlParameters_1)r%   r6   rD   rE   rV   rF   r   r   r   Útest_urlParameterss  s   



z!CGIScriptTests.test_urlParametersc                 C   rt   )Nz
param=1234r;   rv   rw   r   r   r   r—   �  ry   z$CGIScriptTests._test_urlParameters_1c                 C   sb   G dd„ dƒ}|ƒ }t j|  ¡ |d�}tddgƒ}t 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                   @   s   e Zd ZdZdd„ ZdS )z1CGIScriptTests.test_pathInfo.<locals>.FakeReactorzZ
            A fake reactor recording the environment passed to spawnProcess.
            c                 S   s
   || _ 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„   ÚenvZwdirr   r   r   r†   ‘  s   

z>CGIScriptTests.test_pathInfo.<locals>.FakeReactor.spawnProcessN)r   r   r   r‡   r†   r   r   r   r   rˆ   Œ  s    rˆ   rŽ   r‰   rŠ   r‹   rŒ   r�   Z	PATH_INFOz/a/bN)
r   Z	CGIScriptr2   r   r   r�   r   r   rH   r™   )r%   rˆ   Z_reactorr   r@   r   r   r   Útest_pathInfo†  s   
zCGIScriptTests.test_pathInfoN)r   r   r   r‡   r˜   r—   r�   r   r   r   r   r•   n  s
    r•   c                   @   ó    e Zd ZdZdd„ Zdd„ ZdS )ÚCGIDirectoryTestsz*
    Tests for L{twcgi.CGIDirectory}.
    c                    s>   t  ˆ ¡ ¡}tdgƒ‰ t|ˆ ƒ}‡ ‡fdd„}| |¡ |S )zc
        L{twcgi.CGIDirectory.render} sets the HTTP response code to I{NOT
        FOUND}.
        Ú c                    ó   ˆ  ˆ jt¡ d S rf   ©rH   ÚresponseCoder   rk   ©r@   r%   r   r   Ú
cbRendered´  ó   z1CGIDirectoryTests.test_render.<locals>.cbRenderedN)r   ÚCGIDirectoryr2   r   r   rA   )r%   r   rF   r¥   r   r¤   r   Útest_render«  s   


zCGIDirectoryTests.test_renderc                    sX   ˆ  ¡ }t |¡ t |¡}tdgƒ‰ | dˆ ¡}t|ˆ ƒ}‡ ‡fd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}.
        Zfooc                    r¡   rf   r¢   rk   r¤   r   r   r¥   È  r¦   z8CGIDirectoryTests.test_notFoundChild.<locals>.cbRenderedN)	r2   r/   Úmakedirsr   r§   r   ÚgetChildr   rA   )r%   r0   r   ÚchildrF   r¥   r   r¤   r   Útest_notFoundChildº  s   




z$CGIDirectoryTests.test_notFoundChildN)r   r   r   r‡   r¨   r¬   r   r   r   r   rŸ   ¦  s    rŸ   c                   @   rž   )ÚCGIProcessProtocolTestsz0
    Tests for L{twcgi.CGIProcessProtocol}.
    c                 C   s:   t dgƒ}t |¡}| t t ¡ ¡¡ |  |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   ÚProcessTerminatedrH   r£   r   )r%   r@   Úprotocolr   r   r   Útest_prematureEndOfHeadersÔ  s   

z2CGIProcessProtocolTests.test_prematureEndOfHeadersc                 C   sH   t ƒ }t |d¡}t |¡}| t tdƒ¡¡ | 	t t
 ¡ ¡¡ dS )zg
        Ensure that the CGI process ends cleanly when the request connection
        is lost.
        TzConnection doneN)r   r   ÚRequestr   r®   ZconnectionLostr   r°   r   r¯   r   r±   )r%   rF   r@   r²   r   r   r   Útest_connectionLostß  s
   
z+CGIProcessProtocolTests.test_connectionLostN)r   r   r   r‡   r³   rµ   r   r   r   r   r­   Ï  s    r­   c                    s   t  ˆ ¡ ‡ fdd„¡S )zn
    Discard the body of a HTTP response.

    @param response: The response.

    @return: The response.
    c                    s   ˆ S rf   r   )Ú_rP   r   r   Ú<lambda>ó  s    zdiscardBody.<locals>.<lambda>N)r   rB   rA   rP   r   rP   r   rT   ë  s   rT   )4r‡   r[   r/   r   Úior   Ztwisted.internetr   r   r   r   Ztwisted.internet.errorr   Ztwisted.pythonr   r	   r
   Ztwisted.trialr   Ztwisted.webr   r   r   r   r   r   Ztwisted.web.httpr   r   Ztwisted.web.test._utilr   Ztwisted.web.test.requesthelperr   r   r=   rd   rm   rS   ro   r€   rY   r`   r–   r�   r   r    ZTestCaser9   r•   rŸ   r­   rT   r   r   r   r   Ú<module>   s<    		 u8)