
    tfLN                     &   d Z ddlmZmZ ddlmZ ddlmZmZm	Z	m
Z
mZ ddlmZ ddlmZ ddlmZ  G d d	e          Z G d
 d          Z G d de          Z G d de          Z G d de          Z G d d          Z G d de          ZdS )z 
Test for L{twisted.web.proxy}.
    )MemoryReactor StringTransportWithDisconnection)TestCase)ProxyClientProxyClientFactoryProxyRequestReverseProxyRequestReverseProxyResource)Resource)SiteDummyRequestc                   6    e Zd ZdZd Zd Zd Zd Zd Zd Z	dS )	ReverseProxyResourceTestsz,
    Tests for L{ReverseProxyResource}.
    c                    t                      }t                      }t          ddd|          }|                    d|           t	          |          }t                      }|                    d          }|                    |           |                     |j	        d           |
                    d|z   dz              |j        \  \  }	}
}}}|                     |	d           |                     |
d           |                     |t                     |                     |j        |           |                     |j        d         d	           dS )
z
        Check that a request pointing at C{uri} produce a new proxy connection,
        with the path of this request pointing at C{expectedURI}.
        	127.0.0.1     /paths   indexNs   GET s     HTTP/1.1
Accept: text/html

   hosts   127.0.0.1:1234)r   r   r
   putChildr   r   buildProtocolmakeConnection
addCleanupconnectionLostdataReceived
tcpClientsassertEqualassertIsInstancer   restheaders)selfuriexpectedURIrootreactorresourcesite	transportchannelhostportfactory_timeout
_bind_addrs                 Z/var/www/surfInsights/venv3-11/lib/python3.11/site-packages/twisted/web/test/test_proxy.py_testRenderz%ReverseProxyResourceTests._testRender   sF   
 zz//'T8WMMh)))Dzz466	$$T**y))).555Ws]-VVWWW8?8J5	4$gx{+++t$$$ 	g'9:::{33313DEEEEE    c                 .    |                      dd          S )z
        Test that L{ReverseProxyResource.render} initiates a connection to the
        given server with a L{ProxyClientFactory} as parameter.
        s   /indexr   r0   r!   s    r/   test_renderz%ReverseProxyResourceTests.test_render8   s    
 	8444r1   c                 .    |                      dd          S )z
        Test that L{ReverseProxyResource.render} will instantiate a child
        resource that will initiate a connection to the given server
        requesting the apropiate url subpath.
        s   /index/page1s   /path/page1r3   r4   s    r/   test_render_subpagez-ReverseProxyResourceTests.test_render_subpage?   s     @@@r1   c                 .    |                      dd          S )zr
        Test that L{ReverseProxyResource.render} passes query parameters to the
        created factory.
        s   /index?foo=bars   /path?foo=barr3   r4   s    r/   test_renderWithQueryz.ReverseProxyResourceTests.test_renderWithQueryG   s    
  13CDDDr1   c                    t                      }t          ddd|          }|                    dd          }|                     |t                     |                     |j        d           |                     |j        d           |                     |j        d           |                     |j	        |j	                   dS )a  
        The L{ReverseProxyResource.getChild} method should return a resource
        instance with the same class as the originating resource, forward
        port, host, and reactor values, and update the path value with the
        value passed.
        r   r   r      fooNs	   /path/foo)
r   r
   getChildr   r   pathr+   r*   assertIdenticalr%   )r!   r%   r&   childs       r/   test_getChildz'ReverseProxyResourceTests.test_getChildN   s      //'T8WMM!!&$//e%9:::\222T***[111U]H,<=====r1   c                     t          ddd          }|                    dd          }|                     |j        d           dS )zu
        The L{ReverseProxyResource} return by C{getChild} has a path which has
        already been quoted.
        r   r   r   s    /%Ns   /path/%20%2F%25)r
   r<   r   r=   )r!   r&   r?   s      r/   test_getChildWithSpecialz2ReverseProxyResourceTests.test_getChildWithSpecial_   sI    
 (T8DD!!&$//%788888r1   N)
__name__
__module____qualname____doc__r0   r5   r7   r9   r@   rB    r1   r/   r   r      s         F F F:5 5 5A A AE E E> > >"9 9 9 9 9r1   r   c                   *    e Zd ZdZd Zd Zd Zd ZdS )DummyChannelz
    A dummy HTTP channel, that does nothing but holds a transport and saves
    connection lost.

    @ivar transport: the transport used by the client.
    @ivar lostReason: the reason saved at connection lost.
    c                 "    || _         d| _        dS )z4
        Hold a reference to the transport.
        N)r(   
lostReason)r!   r(   s     r/   __init__zDummyChannel.__init__r   s     #r1   c                     || _         dS )z;
        Keep track of the connection lost reason.
        N)rK   )r!   reasons     r/   r   zDummyChannel.connectionLosty   s     !r1   c                 4    | j                                         S )z:
        Get peer information from the transport.
        )r(   getPeerr4   s    r/   rP   zDummyChannel.getPeer        ~%%'''r1   c                 4    | j                                         S )z:
        Get host information from the transport.
        )r(   getHostr4   s    r/   rS   zDummyChannel.getHost   rQ   r1   N)rC   rD   rE   rF   rL   r   rP   rS   rG   r1   r/   rI   rI   i   sZ           ! ! !( ( (( ( ( ( (r1   rI   c                   |    e Zd ZdZd Zd ZddZd Zd	 Zd
 Z	d Z
	 	 	 ddZd Zd Zd Zd Zd Zd Zd Zd ZdS )ProxyClientTestsz#
    Tests for L{ProxyClient}.
    c                     |                     d          \  }}|                     d          }|                    d          }|t          d |D                       |fS )aC  
        Parse the headers out of some web content.

        @param content: Bytes received from a web server.
        @return: A tuple of (requestLine, headers, body). C{headers} is a dict
            of headers, C{requestLine} is the first line (e.g. "POST /foo ...")
            and C{body} is whatever is left.
        s   

   
r   c              3   @   K   | ]}|                     d           V  dS )   : N)split).0headers     r/   	<genexpr>z4ProxyClientTests._parseOutHeaders.<locals>.<genexpr>   s.      !L!L&&,,u"5"5!L!L!L!L!L!Lr1   )rZ   popdict)r!   contentr    bodyrequestLines        r/   _parseOutHeadersz!ProxyClientTests._parseOutHeaders   s]      k22--((kk!nnT!L!LG!L!L!LLLdSSr1   c                      t          |          S )z
        Make a dummy request object for the URL path.

        @param path: A URL path, beginning with a slash.
        @return: A L{DummyRequest}.
        r   )r!   r=   s     r/   makeRequestzProxyClientTests.makeRequest   s     D!!!r1      GETNr1   c                 J    |ddi}d|j         z   }t          ||d|||          S )a  
        Make a L{ProxyClient} object used for testing.

        @param request: The request to use.
        @param method: The HTTP method to use, GET by default.
        @param headers: The HTTP headers to use expressed as a dict. If not
            provided, defaults to {'accept': 'text/html'}.
        @param requestBody: The body of the request. Defaults to the empty
            string.
        @return: A L{ProxyClient}
        N   accept	   text/html   /   HTTP/1.0)postpathr   )r!   requestmethodr    requestBodyr=   s         r/   makeProxyClientz ProxyClientTests.makeProxyClient   s8     ? ,/Gg&&64g{GTTTr1   c                 Z    t                      }||_        |                    |           |S )z
        Connect a proxy client to a L{StringTransportWithDisconnection}.

        @param proxyClient: A L{ProxyClient}.
        @return: The L{StringTransportWithDisconnection}.
        )r   protocolr   )r!   proxyClientclientTransports      r/   connectProxyzProxyClientTests.connectProxy   s1     ;<<#. ""?333r1   c                     |                      |           |j                                        }|                     |          \  }}}|                     ||           |                     ||           |S )a`  
        Assert that C{proxyClient} sends C{headers} when it connects.

        @param proxyClient: A L{ProxyClient}.
        @param requestLine: The request line we expect to be sent.
        @param headers: A dict of headers we expect to be sent.
        @return: If the assertion is successful, return the request body as
            bytes.
        )ru   r(   valuerc   r   )r!   rs   rb   r    requestContentreceivedLinereceivedHeadersra   s           r/   assertForwardsHeadersz&ProxyClientTests.assertForwardsHeaders   sw     	+&&&$.4466.2.C.CN.S.S+ot{333'222r1   c                    dt          |                              d          z   dz   |z   g}|D ]%\  }}|D ]}|                    |dz   |z              &|                    d|g           d                    |          S )Ns	   HTTP/1.0 ascii    rY   r1   rW   )strencodeappendextendjoin)	r!   codemessager    ra   linesr\   valuesrw   s	            r/   makeResponseBytesz"ProxyClientTests.makeResponseBytes   s    D		 0 0 9 99D@7JK% 	5 	5NFF 5 5Ve^e344445c4[!!!||E"""r1   c                    |                      |j        |           |                      |j        |           t          |j                                                  }|                                 |dd         }|                                 |                      ||           |                      d                    |j                  |           dS )aK  
        Assert that C{request} has forwarded a response from the server.

        @param request: A L{DummyRequest}.
        @param code: The expected HTTP response code.
        @param message: The expected HTTP message.
        @param headers: The expected HTTP headers.
        @param body: The expected response body.
        Nr1   )	r   responseCoderesponseMessagelistresponseHeadersgetAllRawHeaderssortr   written)r!   rm   r   r   r    ra   rz   expectedHeaderss           r/   assertForwardsResponsez'ProxyClientTests.assertForwardsResponse   s     	-t4440':::w6GGIIJJ!!!!*/:::'/22D99999r1   Tc                    |                      d          }|                     ||ddi|          }	|                     |	|dz   ddd          }
|                     |
|           |	                    |                     ||||                     |                     |||||           |r|	j                                         | 	                    |	j        j
                   |                     |j        d           dS )	z
        Build a fake proxy connection, and send C{data} over it, checking that
        it's forwarded to the originating request.
        r;   rh   ri   s    /foo HTTP/1.0   close)
   connectionrh      N)re   rp   r{   r   r   r   r   r(   loseConnectionassertFalse	connectedfinished)r!   r   r   r    ra   rn   ro   r   rm   clientreceivedBodys              r/   _testDataForwardz!ProxyClientTests._testDataForward   s"    ""6**%%Vi6
 
 11&&$>>
 
 	{333 	D224'4PPQQQ 	##GT7GTJJJ  	.++---
 	)3444)1-----r1   c                 <    |                      dddddgfgd          S )z
        When connected to the server, L{ProxyClient} should send the saved
        request, with modifications of the headers, and then forward the result
        to the parent request.
              OK   Foo   bars   baz   Some data
r   r4   s    r/   test_forwardzProxyClientTests.test_forward  s3     $$&66"2346F
 
 	
r1   c                 >    |                      ddddgfgddd          S )z~
        Try to post content in the request, and check that the proxy client
        forward the body of the request.
        r   r   r   r   r      POST   Some contentr   r4   s    r/   test_postDatazProxyClientTests.test_postData'  s4    
 $$&6(+,.>
 
 	
r1   c                 2    |                      ddg d          S )z
        If the response contains a status with a message, it should be
        forwarded to the parent request with all the information.
        i  s	   Not Foundr1   r   r4   s    r/   test_statusWithMessagez'ProxyClientTests.test_statusWithMessage0  s    
 $$S,C@@@r1   c           
          d}|                      dddt          t          |                                        d          gfg|          S )z
        If the response contains a I{Content-Length} header, the inbound
        request object should still only have C{finish} called on it once.
           foo bar bazr   r      Content-Lengthr}   r   r   lenr   r!   datas     r/   test_contentLengthz#ProxyClientTests.test_contentLength7  sQ    
 $$+c#d))nn.C.CG.L.L-MNOQU
 
 	
r1   c           
          d}|                      dddt          t          |                                        d          gfg|d          S )z
        If the response contains a I{Content-Length} header, the outgoing
        connection is closed when all response body data has been received.
        r   r   r   r   r}   F)r   r   r   s     r/   test_losesConnectionz%ProxyClientTests.test_losesConnectionA  sZ    
 $$#c$ii.."7"7"@"@!ABC  % 
 
 	
r1   c                 p    t          dddddddd          }|                     |j        dd	d
           dS )z
        The headers given at initialization should be modified:
        B{proxy-connection} should be removed if present, and B{connection}
        should be added.
        rf      /foork   ri   r;   )rh   s   proxy-connectionr1   Nr   rh   r   )r   r   r    )r!   r   s     r/   test_headersCleanupsz%ProxyClientTests.test_headersCleanupsO  s`     $6BB
 
 	NXNN	
 	
 	
 	
 	
r1   c                     dddd}|                                 }d|d<   |d= t          ddd	|d
d          }|                     |d|           dS )z
        The proxy doesn't really know what to do with keepalive things from
        the remote server, so we stomp over any keepalive header we get from
        the client.
        ri   s   300
   keep-alive)rh   r   r   r   r   rf   r   rk   r1   Ns   GET /foo HTTP/1.0)copyr   r{   )r!   r    r   r   s       r/   test_keepaliveNotForwardedz+ProxyClientTests.test_keepaliveNotForwardeda  sp     $!(
 

 ",,..)1&M*VWk7CNN""6+?QQQQQr1   c           	      0   |                      d          }|j                            ddg           |j                            ddg           |j                            ddg           |                     |dd	i
          }|                     |           dgdgdgd}|                    |                     dd|                                d                     |                     |ddt          |                                          d           dS )z
        L{server.Request} within the proxy sets certain response headers by
        default. When we get these headers back from the remote server, the
        defaults are overridden rather than simply appended.
        r;   s   servers   old-bars   dates   old-bazs   content-types   old/quxrh   ri   )r    r   s
   2010-01-01s   application/x-baz)s   Servers   Date   Content-Typer   r   r1   N)
re   r   setRawHeadersrp   ru   r   r   itemsr   r   )r!   rm   r   r    s       r/   test_defaultHeadersOverriddenz.ProxyClientTests.test_defaultHeadersOverriddenr  s    ""6**--i*FFF--g
|DDD--o
|LLL%%g	<7P%QQ&!!!x#_23
 

 	D223w}}PSTTUUU##GS%gmmoo9N9NPSTTTTTr1   )rf   Nr1   )rf   r1   T)rC   rD   rE   rF   rc   re   rp   ru   r{   r   r   r   r   r   r   r   r   r   r   r   rG   r1   r/   rU   rU      s6        T T T" " "U U U U"
 
 
  "# # #: : :2 *. *. *. *.X
 
 

 
 
A A A
 
 

 
 

 
 
$R R R"U U U U Ur1   rU   c                       e Zd ZdZd Zd ZdS )ProxyClientFactoryTestsz*
    Tests for L{ProxyClientFactory}.
    c                    t          dg          }t          dddddid|          }|                    dd           |                     |j        d	           |                     |j        d
           |                     t          |j                                                  ddgfg           |                     d	                    |j
                  d           |                     |j        d           dS )z
        Check that L{ProxyClientFactory.clientConnectionFailed} produces
        a B{501} response to the parent request.
        r;   rf   r   rk   rh   ri    Ni  s   Gateway errorr   r1   s   <H1>Could not connect</H1>r   )r   r   clientConnectionFailedr   r   r   r   r   r   r   r   r   )r!   rm   r,   s      r/   test_connectionFailedz-ProxyClientFactoryTests.test_connectionFailed  s   
 x(($G[9l*CR
 
 	&&tT222-s33302BCCC(99;;<<~./	
 	
 	
 	'/224QRRR)1-----r1   c                 p   t          dddddidd          }|                    d          }|                     |t                     |                     |j        d           |                     |j        d           |                     |j        d           |                     |j        ddd	           dS )
z
        L{ProxyClientFactory.buildProtocol} should produce a L{ProxyClient}
        with the same values of attributes (with updates on the headers).
        rf   r   rk   rh   ri   s	   Some dataNr   r   )	r   r   r   r   r   commandr   r   r    )r!   r,   protos      r/   test_buildProtocolz*ProxyClientFactoryTests.test_buildProtocol  s    
 %G[9l*C\SW
 
 %%d++e[111///W---\222M|HMM	
 	
 	
 	
 	
r1   N)rC   rD   rE   rF   r   r   rG   r1   r/   r   r     s<         . . .(
 
 
 
 
r1   r   c                   2    e Zd ZdZd
dZd Zd Zd Zd Zd	S )ProxyRequestTestsz$
    Tests for L{ProxyRequest}.
    rf   r1   c                    t                      }t          |          }t                      }t          |d|          }|                    t          |                     |                    |           |                    |d|z   d           |                     t          |j	                  d           |                     |j	        d         d         d           |                     |j	        d         d         d           |j	        d         d         }	| 
                    |	t                     |                     |	j        |           |                     |	j        d           |                     |	j        d	d
i           |                     |	j        |           |                     |	j        |           |                     |	j        |           dS )z
        Build a request pointing at C{uri}, and check that a proxied request
        is created, pointing a C{expectedURI}.
        Fs   http://example.comrk   r   r   example.comP      r      example.comN)r   rI   r   r   	gotLengthr   handleContentChunkrequestReceivedr   r   r   r   r   versionr    r   r   father)
r!   r"   r#   rn   r   r(   r)   r%   rm   r,   s
             r/   _testProcesszProxyRequestTests._testProcess  s   
 566	y))//ww77#d))$$$""4((((=(C[QQQW/00!444+A.q1=AAA+A.q12666$Q'*g'9:::&111+6667N*CDDDt,,,{33311111r1   c                 .    |                      dd          S )a  
        L{ProxyRequest.process} should create a connection to the given server,
        with a L{ProxyClientFactory} as connection factory, with the correct
        parameters:
            - forward comment, version and data values
            - update headers with the B{host} value
            - remove the host from the URL
            - pass the request as parent request
           /foo/barr   r4   s    r/   test_processzProxyRequestTests.test_process  s       k:::r1   c                 .    |                      dd          S )z
        If the incoming request doesn't contain a slash,
        L{ProxyRequest.process} should add one when instantiating
        L{ProxyClientFactory}.
        r1   rj   r   r4   s    r/    test_processWithoutTrailingSlashz2ProxyRequestTests.test_processWithoutTrailingSlash  s       d+++r1   c                 2    |                      dddd          S )zl
        L{ProxyRequest.process} should be able to retrieve request body and
        to forward it.
        r   r   r   r   r4   s    r/   test_processWithDataz&ProxyRequestTests.test_processWithData  s    
   k7OTTTr1   c                    t                      }t          |          }t                      }t          |d|          }|                    d           |                    ddd           |                     t          |j                  d           |                     |j        d         d         d           |                     |j        d         d         d           d	S )
z
        Check that L{ProxyRequest.process} correctly parse port in the incoming
        URL, and create an outgoing connection with this port.
        Fr   rf   s   http://example.com:1234/foo/barrk   r   r   r   N)	r   rI   r   r   r   r   r   r   r   )r!   r(   r)   r%   rm   s        r/   test_processWithPortz&ProxyRequestTests.test_processWithPort  s    
 566	y))//ww77!(JKXXX 	W/00!444+A.q1=AAA+A.q1488888r1   N)rf   r1   )	rC   rD   rE   rF   r   r   r   r   r   rG   r1   r/   r   r     sq         2 2 2 24
; 
; 
;, , ,U U U9 9 9 9 9r1   r   c                       e Zd ZdZd ZdS )DummyFactoryz>
    A simple holder for C{host} and C{port} information.
    c                 "    || _         || _        d S )N)r*   r+   )r!   r*   r+   s      r/   rL   zDummyFactory.__init__  s    				r1   N)rC   rD   rE   rF   rL   rG   r1   r/   r   r     s-             r1   r   c                       e Zd ZdZd ZdS )ReverseProxyRequestTestsz+
    Tests for L{ReverseProxyRequest}.
    c                    t                      }t          |          }t                      }t          |d|          }t	          dd          |_        |                    d           |                    ddd           |                     t          |j
                  d           |                     |j
        d         d         d           |                     |j
        d         d         d           |j
        d         d	         }|                     |t                     |                     |j        d
di           dS )a  
        L{ReverseProxyRequest.process} should create a connection to its
        factory host/port, using a L{ProxyClientFactory} instantiated with the
        correct parameters, and particularly set the B{host} header to the
        factory host.
        Fr   r   r   rf   r   rk   r   r   r   r   N)r   rI   r   r	   r   r,   r   r   r   r   r   r   r   r    )r!   r(   r)   r%   rm   r,   s         r/   r   z%ReverseProxyRequestTests.test_process  s*    566	y))//%gug>>&}d;;![AAA 	W/00!444+A.q1=AAA+A.q14888 $Q'*g'9:::7N*CDDDDDr1   N)rC   rD   rE   rF   r   rG   r1   r/   r   r     s2         E E E E Er1   r   N)rF   twisted.internet.testingr   r   twisted.trial.unittestr   twisted.web.proxyr   r   r   r	   r
   twisted.web.resourcer   twisted.web.serverr   twisted.web.test.test_webr   r   rI   rU   r   r   r   r   rG   r1   r/   <module>r      s    U T T T T T T T + + + + + +              * ) ) ) ) ) # # # # # # 2 2 2 2 2 2P9 P9 P9 P9 P9 P9 P9 P9f (  (  (  (  (  (  (  (FxU xU xU xU xUx xU xU xUv(
 (
 (
 (
 (
h (
 (
 (
VI9 I9 I9 I9 I9 I9 I9 I9X       E E E E Ex E E E E Er1   