
    VhLN                         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y)z 
Test for L{twisted.web.proxy}.
    )MemoryReactor StringTransportWithDisconnection)TestCase)ProxyClientProxyClientFactoryProxyRequestReverseProxyRequestReverseProxyResource)Resource)SiteDummyRequestc                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	ReverseProxyResourceTestsz,
    Tests for L{ReverseProxyResource}.
    c                 R   t               }t               }t        ddd|      }|j                  d|       t	        |      }t               }|j                  d      }|j                  |       | j                  |j                  d       |j                  d|z   dz          |j                  \  \  }	}
}}}| j                  |	d       | j                  |
d       | j                  |t               | j                  |j                  |       | j                  |j                   d   d	       y)
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                 K/home/dcms/DCMS/lib/python3.12/site-packages/twisted/web/test/test_proxy.py_testRenderz%ReverseProxyResourceTests._testRender   s   
 z/'T8WMh)Dz46	$$T*y)..5Ws]-VVW8?8J8J5	4$gx{+t$ 	g'9:{313DE    c                 &    | j                  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4r1   c                 &    | j                  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                 &    | j                  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Dr1   c                 x   t               }t        ddd|      }|j                  dd      }| j                  |t               | j	                  |j
                  d       | j	                  |j                  d       | j	                  |j                  d       | j                  |j                  |j                         y)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!!&$/e%9:\2T*[1U]]H,<,<=r1   c                 z    t        ddd      }|j                  dd      }| j                  |j                  d       y)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_   s9    
 (T8D!!&$/%78r1   N)
__name__
__module____qualname____doc__r0   r5   r7   r9   r@   rB    r1   r/   r   r      s(    F:5AE>"9r1   r   c                   (    e Zd ZdZd Zd Zd Zd Zy)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| _        y)z4
        Hold a reference to the transport.
        N)r(   
lostReason)r!   r(   s     r/   __init__zDummyChannel.__init__r   s     #r1   c                     || _         y)z;
        Keep track of the connection lost reason.
        N)rK   )r!   reasons     r/   r   zDummyChannel.connectionLosty   s     !r1   c                 6    | j                   j                         S )z:
        Get peer information from the transport.
        )r(   getPeerr4   s    r/   rP   zDummyChannel.getPeer        ~~%%''r1   c                 6    | j                   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   s    !((r1   rI   c                   z    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y)ProxyClientTestsz#
    Tests for L{ProxyClient}.
    c                     |j                  d      \  }}|j                  d      }|j                  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   | ]  }|j                  d         yw)   : N)split).0headers     r/   	<genexpr>z4ProxyClientTests._parseOutHeaders.<locals>.<genexpr>   s     !L&&,,u"5!Ls   )rZ   popdict)r!   contentr    bodyrequestLines        r/   _parseOutHeadersz!ProxyClientTests._parseOutHeaders   sI      k2--(kk!nT!LG!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   Nc                 L    |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}
           accept	   text/html   /   HTTP/1.0)postpathr   )r!   requestmethodr    requestBodyr=   s         r/   makeProxyClientz ProxyClientTests.makeProxyClient   s8     ? ,/Gg&&&64g{GTTr1   c                 J    t               }||_        |j                  |       |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   s(     ;<#. ""?3r1   c                     | j                  |       |j                  j                         }| j                  |      \  }}}| j	                  ||       | 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.
        )rt   r(   valuerc   r   )r!   rr   rb   r    requestContentreceivedLinereceivedHeadersra   s           r/   assertForwardsHeadersz&ProxyClientTests.assertForwardsHeaders   sb     	+&$..446.2.C.CN.S+ot{3'2r1   c                     dt        |      j                  d      z   dz   |z   g}|D ]#  \  }}|D ]  }|j                  |dz   |z           % |j                  d|g       dj	                  |      S )Ns	   HTTP/1.0 ascii    rY   r1   rW   )strencodeappendextendjoin)	r!   codemessager    ra   linesr\   valuesrv   s	            r/   makeResponseBytesz"ProxyClientTests.makeResponseBytes   s    D	 0 0 99D@7JK% 	5NFF 5Ve^e345	5 	c4[!||E""r1   c                 ~   | j                  |j                  |       | j                  |j                  |       t        |j                  j                               }|j                          |dd }|j                          | j                  ||       | j                  dj                  |j                        |       y)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!   rl   r   r   r    ra   ry   expectedHeaderss           r/   assertForwardsResponsez'ProxyClientTests.assertForwardsResponse   s     	--t400':w66GGIJ!!*/:'//2D9r1   c                    | j                  d      }| j                  ||ddi|      }	| j                  |	|dz   ddd      }
| j                  |
|       |	j	                  | j                  ||||             | j                  |||||       |r|	j                  j                          | j                  |	j                  j                         | j                  |j                  d       y)	z
        Build a fake proxy connection, and send C{data} over it, checking that
        it's forwarded to the originating request.
        r;   rg   rh   s    /foo HTTP/1.0   close)
   connectionrg      N)re   ro   rz   r   r   r   r   r(   loseConnectionassertFalse	connectedfinished)r!   r   r   r    ra   rm   rn   r   rl   clientreceivedBodys              r/   _testDataForwardz!ProxyClientTests._testDataForward   s     ""6*%%Vi6
 11&&$>
 	{3 	D224'4PQ 	##GT7GTJ ++-
 	))334))1-r1   c                 4    | j                  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  s.     $$&66"2346F
 	
r1   c                 6    | j                  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'  s/    
 $$&6(+,.>
 	
r1   c                 *    | j                  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           
      x    d}| j                  dddt        t        |            j                  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  sE    
 $$+c#d)n.C.CG.L-MNOQU
 	
r1   c           
      |    d}| j                  dddt        t        |            j                  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  sN    
 $$#c$i."7"7"@!ABC  % 
 	
r1   c                 h    t        dddddddd      }| j                  |j                  dd	d
       y)z
        The headers given at initialization should be modified:
        B{proxy-connection} should be removed if present, and B{connection}
        should be added.
           GET   /foorj   rh   r;   )rg   s   proxy-connectionr1   Nr   rg   r   )r   r   r    )r!   r   s     r/   test_headersCleanupsz%ProxyClientTests.test_headersCleanupsO  sC     $6B
 	NNXN	
r1   c                     dddd}|j                         }d|d<   |d= t        ddd	|d
d      }| j                  |d|       y)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.
        rh   s   300
   keep-alive)rg   r   r   r   r   r   r   rj   r1   Ns   GET /foo HTTP/1.0)copyr   rz   )r!   r    r   r   s       r/   test_keepaliveNotForwardedz+ProxyClientTests.test_keepaliveNotForwardeda  sZ     $!(

 ",,.)1&M*VWk7CN""6+?Qr1   c           	         | j                  d      }|j                  j                  ddg       |j                  j                  ddg       |j                  j                  ddg       | j                  |dd	i
      }| j	                  |       dgdgdgd}|j                  | j                  dd|j                         d             | j                  |ddt        |j                               d       y)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/quxrg   rh   )r    r   s
   2010-01-01s   application/x-baz)s   Servers   Date   Content-Typer   r   r1   N)
re   r   setRawHeadersro   rt   r   r   itemsr   r   )r!   rl   r   r    s       r/   test_defaultHeadersOverriddenz.ProxyClientTests.test_defaultHeadersOverriddenr  s     ""6*--i*F--g
|D--o
|L%%g	<7P%Q&!x#_23

 	D223w}}PSTU##GS%gmmo9NPSTr1   )r   Nr1   )r   r1   T)rC   rD   rE   rF   rc   re   ro   rt   rz   r   r   r   r   r   r   r   r   r   r   r   rG   r1   r/   rU   rU      sh    T"U"
"#:2 *.X

A


$R"Ur1   rU   c                       e Zd ZdZd Zd Zy)ProxyClientFactoryTestsz*
    Tests for L{ProxyClientFactory}.
    c                    t        dg      }t        dddddid|      }|j                  dd       | j                  |j                  d	       | j                  |j
                  d
       | j                  t        |j                  j                               ddgfg       | j                  dj                  |j                        d       | j                  |j                  d       y)z
        Check that L{ProxyClientFactory.clientConnectionFailed} produces
        a B{501} response to the parent request.
        r;   r   r   rj   rg   rh    Ni  s   Gateway errorr   r1   s   <H1>Could not connect</H1>r   )r   r   clientConnectionFailedr   r   r   r   r   r   r   r   r   )r!   rl   r,   s      r/   test_connectionFailedz-ProxyClientFactoryTests.test_connectionFailed  s    
 x($G[9l*CR
 	&&tT2--s3002BC((99;<~./	
 	'//24QR))1-r1   c                 \   t        dddddidd      }|j                  d      }| j                  |t               | j	                  |j
                  d       | j	                  |j                  d       | j	                  |j                  d       | j	                  |j                  ddd	       y)
z
        L{ProxyClientFactory.buildProtocol} should produce a L{ProxyClient}
        with the same values of attributes (with updates on the headers).
        r   r   rj   rg   rh   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/W-\2MM|HM	
r1   N)rC   rD   rE   rF   r   r   rG   r1   r/   r   r     s    .(
r1   r   c                   0    e Zd ZdZddZd Zd Zd Zd Zy)	ProxyRequestTestsz$
    Tests for L{ProxyRequest}.
    c                 T   t               }t        |      }t               }t        |d|      }|j	                  t        |             |j                  |       |j                  |d|z   d       | j                  t        |j                        d       | j                  |j                  d   d   d       | j                  |j                  d   d   d       |j                  d   d   }	| j                  |	t               | j                  |	j                  |       | j                  |	j                  d       | j                  |	j                  d	d
i       | j                  |	j                  |       | j                  |	j                   |       | j                  |	j"                  |       y)z
        Build a request pointing at C{uri}, and check that a proxied request
        is created, pointing a C{expectedURI}.
        Fs   http://example.comrj   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#   rm   r   r(   r)   r%   rl   r,   s
             r/   _testProcesszProxyRequestTests._testProcess  sa   
 56	y)/ww7#d)$""4((=(C[QW//0!4++A.q1=A++A.q126$$Q'*g'9:&1+67N*CDt,{31r1   c                 &    | j                  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                 &    | j                  dd      S )z
        If the incoming request doesn't contain a slash,
        L{ProxyRequest.process} should add one when instantiating
        L{ProxyClientFactory}.
        r1   ri   r   r4   s    r/    test_processWithoutTrailingSlashz2ProxyRequestTests.test_processWithoutTrailingSlash  s       d++r1   c                 *    | j                  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Tr1   c                 v   t               }t        |      }t               }t        |d|      }|j	                  d       |j                  ddd       | j                  t        |j                        d       | j                  |j                  d   d   d       | j                  |j                  d   d   d       y	)
z
        Check that L{ProxyRequest.process} correctly parse port in the incoming
        URL, and create an outgoing connection with this port.
        Fr   r   s   http://example.com:1234/foo/barrj   r   r   r   N)	r   rI   r   r   r   r   r   r   r   )r!   r(   r)   r%   rl   s        r/   test_processWithPortz&ProxyRequestTests.test_processWithPort  s    
 56	y)/ww7!(JKX 	W//0!4++A.q1=A++A.q148r1   N)r   r1   )	rC   rD   rE   rF   r   r   r   r   r   rG   r1   r/   r   r     s!    24
;,U9r1   r   c                       e Zd ZdZd Zy)DummyFactoryz>
    A simple holder for C{host} and C{port} information.
    c                      || _         || _        y )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y)ReverseProxyRequestTestsz+
    Tests for L{ReverseProxyRequest}.
    c                 $   t               }t        |      }t               }t        |d|      }t	        dd      |_        |j                  d       |j                  ddd       | j                  t        |j                        d       | j                  |j                  d   d   d       | j                  |j                  d   d   d       |j                  d   d	   }| j                  |t               | j                  |j                  d
di       y)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   r   r   rj   r   r   r   r   N)r   rI   r   r	   r   r,   r   r   r   r   r   r   r   r    )r!   r(   r)   r%   rl   r,   s         r/   r   z%ReverseProxyRequestTests.test_process  s     56	y)/%gug>&}d;![A 	W//0!4++A.q1=A++A.q148 $$Q'*g'9:7N*CDr1   N)rC   rD   rE   rF   r   rG   r1   r/   r   r     s    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 +  * # 2P9 P9f (  (FxUx xUv(
h (
VI9 I9X Ex Er1   