o b&@sdZddlmZmZmZddlmZddlm Z ddl m Z m Z m Z mZddlmZddlmZGdd d e ZGd d d e ZGd d d eZGddde ZGdddeZGddde ZGdddeZdS)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. )quoteurlparse urlunparse)reactor) ClientFactory)_QUEUED_SENTINEL HTTPChannel HTTPClientRequest)Resource) NOT_DONE_YETc@sDeZdZdZdZddZddZddZd d Zd d Z d dZ dS) 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. FcCsD||_||_||_d|vr|d=d|d<|dd||_||_dS)Nsproxy-connectionscloses connections keep-alive)fathercommandrestpopheadersdataselfrrversionrrrr3/usr/lib/python3/dist-packages/twisted/web/proxy.py__init__)s  zProxyClient.__init__cCsJ||j|j|jD] \}}|||q ||j|j dSN) sendCommandrrritems sendHeader endHeaders transportwriter)rheadervaluerrrconnectionMade4s zProxyClient.connectionMadecCs|jt||dSr)rsetResponseCodeint)rrcodemessagerrr handleStatus;szProxyClient.handleStatuscCs6|dvr|jj||gdS|jj||dS)N)sserversdates content-type)lowerrresponseHeaders setRawHeaders addRawHeader)rkeyr"rrr handleHeader>s zProxyClient.handleHeadercCs|j|dSr)rr )rbufferrrrhandleResponsePartHszProxyClient.handleResponsePartcCs(|jsd|_|j|jdSdS)z Finish the original request, indicating that the response has been completely written to it, and disconnect the outgoing transport. TN) _finishedrfinishrloseConnection)rrrrhandleResponseEndKs  zProxyClient.handleResponseEndN) __name__ __module__ __qualname____doc__r1rr#r(r.r0r4rrrrr s  r c@s,eZdZdZeZddZddZddZdS) ProxyClientFactoryz? Used by ProxyRequest to implement a simple web proxy. cCs(||_||_||_||_||_||_dSr)rrrrrrrrrrr^s  zProxyClientFactory.__init__cCs ||j|j|j|j|j|jSr)protocolrrrrrr)raddrrrr buildProtocolfsz ProxyClientFactory.buildProtocolcCs8|jdd|jjdd|jd|jdS)zh Report a connection failure in a response to the incoming request as an error. is Gateway errors Content-Types text/htmls

Could not connect

N)rr$r*r,r r2)r connectorreasonrrrclientConnectionFailedks z)ProxyClientFactory.clientConnectionFailedN) r5r6r7r8r r:rr<r?rrrrr9Vs  r9c@s6eZdZdZdeiZddiZeefddZ ddZ dS) 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} shttpPcCt|||||_dSrr rrrchannelqueuedrrrrr zProxyRequest.__init__c Cst|j}|d}|dd}|j|}d|vr$|d\}}t|}td|dd}|s4|d}|j|}| }d|vrJ| d|d<|j dd|j }||j||j|||} |j||| dS) Nrascii:)rK/host)ruridecodeportssplitr%r protocols getAllHeaderscopyencodecontentseekreadmethod clientprotor connectTCP) rparsedr:hostportrclass_rs clientFactoryrrrprocesss$     zProxyRequest.processN) r5r6r7r8r9rSrQrrrrcrrrrr@vs  r@c@eZdZdZeZdS)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)r5r6r7r8r@requestFactoryrrrrresrec@s*eZdZdZeZeefddZddZ dS)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} cCrBrrCrDrrrrrGzReverseProxyRequest.__init__cCsZ|jd|jjdg||j|j|j| |j |}|j |jj|jj|dS)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. rNrIN)requestHeadersr+factoryr^rVproxyClientFactoryClassrZrOr[rTrWrYrr\r_)rrbrrrrcszReverseProxyRequest.processN) r5r6r7r8r9rjrrrrcrrrrrgs   rgc@rd) ReverseProxyzo Implements a simple reverse proxy. For details of usage, see the file examples/reverse-proxy.py. N)r5r6r7r8rgrfrrrrrksrkc@s0eZdZdZeZefddZddZddZ dS) 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} cCs&t|||_||_||_||_dS)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 rr^r_pathr)rr^r_rmrrrrrs  zReverseProxyResource.__init__cCs,t|j|j|jdt|ddd|jS)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. rMrK)safezutf-8)rlr^r_rmurlquoterVr)rrmrequestrrrgetChilds zReverseProxyResource.getChildcCs|jdkr |j}nd|j|jf}|jd|dg|jddt|jd}|r4|j d|}n|j }| |j ||j | |j|}|j|j|j|tS)zJ Render a request by forwarding it to the proxied server. rAz%s:%drNrIr?)r_r^rhr+rVrWrXrrOrmrjrZr[rTrYrr\r )rrpr^qsrrbrrrrenders& zReverseProxyResource.renderN) r5r6r7r8r9rjrrrqrurrrrrls   rlN)r8 urllib.parserrorrtwisted.internetrtwisted.internet.protocolrtwisted.web.httprrr r twisted.web.resourcer twisted.web.serverr r r9r@rergrkrlrrrrs    7 $$