
    Ϫf&                         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y)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                   8    e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
y	)
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<   |j                  dd        || _        || _        y )Ns   proxy-connections   closes
   connections
   keep-alive)fathercommandrestpopheadersdataselfr   r   versionr   r   r   s          3/usr/lib/python3/dist-packages/twisted/web/proxy.py__init__zProxyClient.__init__)   sN    	')+,!)M4(	    c                 "   | j                  | j                  | j                         | j                  j	                         D ]  \  }}| j                  ||        | j                          | j                  j                  | j                         y N)
sendCommandr   r   r   items
sendHeader
endHeaders	transportwriter   )r   headervalues      r   connectionMadezProxyClient.connectionMade4   sh    tyy1!\\//1 	+MFEOOFE*	+TYY'r   c                 N    | j                   j                  t        |      |       y r   )r   setResponseCodeint)r   r   codemessages       r   handleStatuszProxyClient.handleStatus;   s    ##CIw7r   c                     |j                         dv r(| j                  j                  j                  ||g       y | j                  j                  j	                  ||       y )N)s   servers   dates   content-type)lowerr   responseHeaderssetRawHeadersaddRawHeader)r   keyr&   s      r   handleHeaderzProxyClient.handleHeader>   sI    
 99;??KK''55cE7CKK''44S%@r   c                 :    | j                   j                  |       y r   )r   r$   )r   buffers     r   handleResponsePartzProxyClient.handleResponsePartH   s    &!r   c                     | j                   s<d| _         | j                  j                          | j                  j	                          yy)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   s7    
 ~~!DNKK NN))+ r   N)__name__
__module____qualname____doc__r9   r   r'   r-   r4   r7   r<    r   r   r   r      s-     I	(8A",r   r   c                   &    e Zd ZdZeZd Zd Zd Zy)ProxyClientFactoryz?
    Used by ProxyRequest to implement a simple web proxy.
    c                 X    || _         || _        || _        || _        || _        || _        y r   )r   r   r   r   r   r   r   s          r   r   zProxyClientFactory.__init__^   s,    		r   c                     | j                  | j                  | j                  | j                  | j                  | j
                  | j                        S r   )protocolr   r   r   r   r   r   )r   addrs     r   buildProtocolz ProxyClientFactory.buildProtocolf   s8    }}LL$))T\\4<<DKK
 	
r   c                     | j                   j                  dd       | j                   j                  j                  dd       | j                   j	                  d       | j                   j                          y)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   sV    
 	##C)9:##00,O78r   N)	r=   r>   r?   r@   r   rF   r   rH   rL   rA   r   r   rC   rC   V   s    
 H

r   rC   c                   2    e Zd ZdZdeiZddiZeefdZ	d Z
y)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                  | ||       || _        y r   r   r   r   r   channelqueuedr   s       r   r   zProxyRequest.__init__       w/r   c                 f   t        | j                        }|d   }|d   j                  d      }| j                  |   }d|v r|j	                  d      \  }}t        |      }t        d|dd  z         }|s|dz   }| j                  |   }| j                         j                         }d|vr|j                  d      |d<   | j                  j                  dd       | j                  j                         } || j                  || j                  |||       }	| j                   j#                  |||	       y )	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   s   $((#!9ay(zz(#$;CJD$t9D*vabz12$;D)$$&++-'!#{{73GG!QLLt{{D$2B2BGQPT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y)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     "Nr   rs   c                   &    e Zd ZdZeZeefdZd Z	y)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                  | ||       || _        y r   rQ   rR   s       r   r   zReverseProxyRequest.__init__   rU   r   c                    | j                   j                  d| j                  j                  j	                  d      g       | j                  | j                  | j                  | j                  | j                         | j                  j                         |       }| j                  j                  | j                  j                  | j                  j                  |       y)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     	))'DLL4E4E4L4LW4U3VW44KKHH LL
 	 1 14<<3D3DmTr   N)
r=   r>   r?   r@   rC   r{   r   r   r   rq   rA   r   r   rv   rv      s    	 1'7 Ur   rv   c                       e Zd ZdZeZy)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     )Nr   r}   c                   *    e Zd ZdZeZefdZd Zd Z	y)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                  |        || _        || _        || _        || _        y)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__   s.      	$			r   c           	          t        | j                  | j                  | j                  dz   t	        |d      j                  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  sI     $IIIIIIx37>>wGGLL	
 	
r   c                    | j                   dk(  r| j                  }nd| j                  | j                   fz  }|j                  j                  d|j	                  d      g       |j
                  j                  dd       t        |j                        d   }|r| j                  dz   |z   }n| j                  }| j                  |j                  ||j                  |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     99?99Ddii33D,,Wt{{77K6LMQ"gkk"1%99t#b(D99D44NN!!#OO  "
 			499m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 O O ) +4,* 4,n @!;7 !;H"K "$!U' !UH); )N8 Nr   