
    \d&                     *   d Z ddlmZmZmZ ddlm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  G d d	e          Z G d
 de	          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          ZdS )aT  
Simplistic HTTP proxy support.

This comes in two main variants - the Proxy and the ReverseProxy.

When a Proxy is in use, a browser trying to connect to a server (say,
www.yahoo.com) will be intercepted by the Proxy, and the proxy will covertly
connect to the server, and return the result.

When a ReverseProxy is in use, the client connects directly to the ReverseProxy
(say, www.yahoo.com) which farms off the request to one of a pool of servers,
and returns the result.

Normally, a Proxy is used on the client end of an Internet connection, while a
ReverseProxy is used on the server end.
    )quoteurlparse
urlunparse)reactor)ClientFactory)_QUEUED_SENTINELHTTPChannel
HTTPClientRequest)Resource)NOT_DONE_YETc                   :    e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
d	S )
ProxyClientz
    Used by ProxyClientFactory to implement a simple web proxy.

    @ivar _finished: A flag which indicates whether or not the original request
        has been finished yet.
    Fc                     || _         || _        || _        d|v r|d= d|d<   |                    dd            || _        || _        d S )Ns   proxy-connections   closes
   connections
   keep-alive)fathercommandrestpopheadersdataselfr   r   versionr   r   r   s          1lib/python3.11/site-packages/twisted/web/proxy.py__init__zProxyClient.__init__)   s[    	'))+,!)M4(((			    c                    |                      | j        | j                   | j                                        D ]\  }}|                     ||           |                                  | j                            | j	                   d S N)
sendCommandr   r   r   items
sendHeader
endHeaders	transportwriter   )r   headervalues      r   connectionMadezProxyClient.connectionMade4   s    ty111!\//11 	+ 	+MFEOOFE****TY'''''r   c                 V    | j                             t          |          |           d S r   )r   setResponseCodeint)r   r   codemessages       r   handleStatuszProxyClient.handleStatus;   s&    ##CIIw77777r   c                     |                                 dv r#| j        j                            ||g           d S | j        j                            ||           d S )N)s   servers   dates   content-type)lowerr   responseHeaderssetRawHeadersaddRawHeader)r   keyr&   s      r   handleHeaderzProxyClient.handleHeader>   s\    
 99;;???K'55cE7CCCCCK'44S%@@@@@r   c                 :    | j                             |           d S r   )r   r$   )r   buffers     r   handleResponsePartzProxyClient.handleResponsePartH   s    &!!!!!r   c                     | j         s;d| _         | j                                         | j                                         dS dS )z
        Finish the original request, indicating that the response has been
        completely written to it, and disconnect the outgoing transport.
        TN)	_finishedr   finishr#   loseConnection)r   s    r   handleResponseEndzProxyClient.handleResponseEndK   sM    
 ~ 	,!DNK   N))+++++	, 	,r   N)__name__
__module____qualname____doc__r9   r   r'   r-   r4   r7   r<    r   r   r   r      s          I	 	 	( ( (8 8 8A A A" " ", , , , ,r   r   c                   (    e Zd ZdZeZd Zd Zd ZdS )ProxyClientFactoryz?
    Used by ProxyRequest to implement a simple web proxy.
    c                 Z    || _         || _        || _        || _        || _        || _        d S r   )r   r   r   r   r   r   r   s          r   r   zProxyClientFactory.__init__^   s0    		r   c                 r    |                      | j        | j        | j        | j        | j        | j                  S r   )protocolr   r   r   r   r   r   )r   addrs     r   buildProtocolz ProxyClientFactory.buildProtocolf   s1    }}L$)T\4<DK
 
 	
r   c                     | j                             dd           | j         j                            dd           | j                             d           | j                                          dS )zh
        Report a connection failure in a response to the incoming request as
        an error.
        i  s   Gateway errors   Content-Types	   text/htmls   <H1>Could not connect</H1>N)r   r)   r0   r2   r$   r:   )r   	connectorreasons      r   clientConnectionFailedz)ProxyClientFactory.clientConnectionFailedk   si    
 	##C)9:::#00,OOO7888r   N)	r=   r>   r?   r@   r   rF   r   rH   rL   rA   r   r   rC   rC   V   sR         
 H  
 
 

    r   rC   c                   4    e Zd ZdZdeiZddiZeefdZ	d Z
dS )ProxyRequestz
    Used by Proxy to implement a simple web proxy.

    @ivar reactor: the reactor used to create connections.
    @type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
    s   httpP   c                 @    t          j        | ||           || _        d S r   r   r   r   r   channelqueuedr   s       r   r   zProxyRequest.__init__   "    w///r   c                    t          | j                  }|d         }|d                             d          }| j        |         }d|v r'|                    d          \  }}t          |          }t          d|dd          z             }|s|dz   }| j        |         }|                                 	                                }d|vr|
                    d          |d<   | j                            dd           | j                                        } || j        || j        |||           }	| j                            |||	           d S )	Nr      ascii:)r   r         /   host)r   uridecodeportssplitr*   r   	protocolsgetAllHeaderscopyencodecontentseekreadmethodclientprotor   
connectTCP)
r   parsedrF   hostportr   class_r   sclientFactorys
             r   processzProxyRequest.process   sC   $(##!9ay((z(#$;;CJD$t99D*vabbz122 	$;D)$$&&++--'!!#{{733GG!QLt{D$2BGQPTUUdM:::::r   N)r=   r>   r?   r@   rC   ra   r_   r   r   r   rq   rA   r   r   rN   rN   v   s\          ,-IbME'7    ; ; ; ; ;r   rN   c                       e Zd ZdZeZdS )Proxyao  
    This class implements a simple web proxy.

    Since it inherits from L{twisted.web.http.HTTPChannel}, to use it you
    should do something like this::

        from twisted.web import http
        f = http.HTTPFactory()
        f.protocol = Proxy

    Make the HTTPFactory a listener on a port as per usual, and you have
    a fully-functioning web proxy!
    N)r=   r>   r?   r@   rN   requestFactoryrA   r   r   rs   rs      s          "NNNr   rs   c                   (    e Zd ZdZeZeefdZd Z	dS )ReverseProxyRequestal  
    Used by ReverseProxy to implement a simple reverse proxy.

    @ivar proxyClientFactoryClass: a proxy client factory class, used to create
        new connections.
    @type proxyClientFactoryClass: L{ClientFactory}

    @ivar reactor: the reactor used to create connections.
    @type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
    c                 @    t          j        | ||           || _        d S r   rQ   rR   s       r   r   zReverseProxyRequest.__init__   rU   r   c                 |   | j                             d| j        j                            d          g           |                     | j        | j        | j        | 	                                | j
                                        |           }| j                            | j        j        | j        j        |           dS )z
        Handle this request by connecting to the proxied server and forwarding
        it there, then forwarding the response back as the response to this
        request.
        r\   rX   N)requestHeadersr1   factoryrl   rd   proxyClientFactoryClassrh   r]   ri   rb   re   rg   r   rj   rm   )r   rp   s     r   rq   zReverseProxyRequest.process   s     	))'DL4E4L4LW4U4U3VWWW44KH  L
 
 	 14<3DmTTTTTr   N)
r=   r>   r?   r@   rC   r{   r   r   r   rq   rA   r   r   rv   rv      sS        	 	 1'7    U U U U Ur   rv   c                       e Zd ZdZeZdS )ReverseProxyzo
    Implements a simple reverse proxy.

    For details of usage, see the file examples/reverse-proxy.py.
    N)r=   r>   r?   r@   rv   rt   rA   r   r   r}   r}      s          )NNNr   r}   c                   ,    e Zd ZdZeZefdZd Zd Z	dS )ReverseProxyResourcea  
    Resource that renders the results gotten from another server

    Put this resource in the tree to cause everything below it to be relayed
    to a different server.

    @ivar proxyClientFactoryClass: a proxy client factory class, used to create
        new connections.
    @type proxyClientFactoryClass: L{ClientFactory}

    @ivar reactor: the reactor used to create connections.
    @type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
    c                 f    t          j        |            || _        || _        || _        || _        dS )aU  
        @param host: the host of the web server to proxy.
        @type host: C{str}

        @param port: the port of the web server to proxy.
        @type port: C{port}

        @param path: the base path to fetch data from. Note that you shouldn't
            put any trailing slashes in it, it will be added automatically in
            request. For example, if you put B{/foo}, a request on B{/bar} will
            be proxied to B{/foo/bar}.  Any required encoding of special
            characters (such as " " or "/") should have been done already.

        @type path: C{bytes}
        N)r   r   rl   rm   pathr   )r   rl   rm   r   r   s        r   r   zReverseProxyResource.__init__   s5      	$			r   c           	          t          | j        | j        | j        dz   t	          |d                              d          z   | j                  S )z
        Create and return a proxy resource with the same proxy configuration
        as this one, except that its path also contains the segment given by
        C{path} at the end.
        r[   r   )safezutf-8)r   rl   rm   r   urlquoterd   r   )r   r   requests      r   getChildzReverseProxyResource.getChild  sO     $IIIx3777>>wGGGL	
 
 	
r   c                 4   | j         dk    r| j        }nd| j        | j         fz  }|j                            d|                    d          g           |j                            dd           t          |j                  d         }|r| j	        dz   |z   }n| j	        }| 
                    |j        ||j        |                                |j                                        |          }| j                            | j        | j         |           t"          S )zJ
        Render a request by forwarding it to the proxied server.
        rO   z%s:%dr\   rX   r         ?)rm   rl   ry   r1   rd   re   rf   r   r]   r   r{   rh   ri   rb   rg   r   rj   r   )r   r   rl   qsr   rp   s         r   renderzReverseProxyResource.render  s    9??9DDdi33D,,Wt{{77K7K6LMMMQ"""gk""1% 	9t#b(DD9D44N!!##O  ""
 
 		49mDDDr   N)
r=   r>   r?   r@   rC   r{   r   r   r   r   rA   r   r   r   r      s[          118    ,
 
 
    r   r   N)r@   urllib.parser   r   r   r   twisted.internetr   twisted.internet.protocolr   twisted.web.httpr   r	   r
   r   twisted.web.resourcer   twisted.web.serverr   r   rC   rN   rs   rv   r}   r   rA   r   r   <module>r      s  
 " A @ @ @ @ @ @ @ @ @ $ $ $ $ $ $ 3 3 3 3 3 3 O O O O O O O O O O O O ) ) ) ) ) ) + + + + + +4, 4, 4, 4, 4,* 4, 4, 4,n       @!; !; !; !; !;7 !; !; !;H" " " " "K " " "$!U !U !U !U !U' !U !U !UH) ) ) ) ); ) ) )N N N N N8 N N N N Nr   