<s> """<STR_LIT>""" <EOL> import urlparse <EOL> from urllib import quote as urlquote <EOL> from twisted . internet import reactor <EOL> from twisted . internet . protocol import ClientFactory <EOL> from twisted . web . resource import Resource <EOL> from twisted . web . server import NOT_DONE_YET <EOL> from twisted . web . http import HTTPClient , Request , HTTPChannel <EOL> class ProxyClient ( HTTPClient ) : <EOL> """<STR_LIT>""" <EOL> _finished = False <EOL> def __init__ ( self , command , rest , version , headers , data , father ) : <EOL> self . father = father <EOL> self . command = command <EOL> self . rest = rest <EOL> if "<STR_LIT>" in headers : <EOL> del headers [ "<STR_LIT>" ] <EOL> headers [ "<STR_LIT>" ] = "<STR_LIT>" <EOL> headers . pop ( '<STR_LIT>' , None ) <EOL> self . headers = headers <EOL> self . data = data <EOL> def connectionMade ( self ) : <EOL> self . sendCommand ( self . command , self . rest ) <EOL> for header , value in self . headers . items ( ) : <EOL> self . sendHeader ( header , value ) <EOL> self . endHeaders ( ) <EOL> self . transport . write ( self . data ) <EOL> def handleStatus ( self , version , code , message ) : <EOL> self . father . setResponseCode ( int ( code ) , message ) <EOL> def handleHeader ( self , key , value ) : <EOL> if key . lower ( ) in [ '<STR_LIT>' , '<STR_LIT:date>' , '<STR_LIT>' ] : <EOL> self . father . responseHeaders . setRawHeaders ( key , [ value ] ) <EOL> else : <EOL> self . father . responseHeaders . addRawHeader ( key , value ) <EOL> def handleResponsePart ( self , buffer ) : <EOL> self . father . write ( buffer ) <EOL> def handleResponseEnd ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . _finished : <EOL> self . _finished = True <EOL> self . father . finish ( ) <EOL> self . transport . loseConnection ( ) <EOL> class ProxyClientFactory ( ClientFactory ) : <EOL> """<STR_LIT>""" <EOL> protocol = ProxyClient <EOL> def __init__ ( self , command , rest , version , headers , data , father ) : <EOL> self . father = father <EOL> self . command = command <EOL> self . rest = rest <EOL> self . headers = headers <EOL> self . data = data <EOL> self . version = version <EOL> def buildProtocol ( self , addr ) : <EOL> return self . protocol ( self . command , self . rest , self . version , <EOL> self . headers , self . data , self . father ) <EOL> def clientConnectionFailed ( self , connector , reason ) : <EOL> """<STR_LIT>""" <EOL> self . father . setResponseCode ( <NUM_LIT> , "<STR_LIT>" ) <EOL> self . father . responseHeaders . addRawHeader ( "<STR_LIT:Content-Type>" , "<STR_LIT>" ) <EOL> self . father . write ( "<STR_LIT>" ) <EOL> self . father . finish ( ) <EOL> class ProxyRequest ( Request ) : <EOL> """<STR_LIT>""" <EOL> protocols = { '<STR_LIT:http>' : ProxyClientFactory } <EOL> ports = { '<STR_LIT:http>' : <NUM_LIT> } <EOL> def __init__ ( self , channel , queued , reactor = reactor ) : <EOL> Request . __init__ ( self , channel , queued ) <EOL> self . reactor = reactor <EOL> def process ( self ) : <EOL> parsed = urlparse . urlparse ( self . uri ) <EOL> protocol = parsed [ <NUM_LIT:0> ] <EOL> host = parsed [ <NUM_LIT:1> ] <EOL> port = self . ports [ protocol ] <EOL> if '<STR_LIT::>' in host : <EOL> host , port = host . split ( '<STR_LIT::>' ) <EOL> port = int ( port ) <EOL> rest = urlparse . urlunparse ( ( '<STR_LIT>' , '<STR_LIT>' ) + parsed [ <NUM_LIT:2> : ] ) <EOL> if not rest : <EOL> rest = rest + '<STR_LIT:/>' <EOL> class_ = self . protocols [ protocol ] <EOL> headers = self . getAllHeaders ( ) . copy ( ) <EOL> if '<STR_LIT:host>' not in headers : <EOL> headers [ '<STR_LIT:host>' ] = host <EOL> self . content . seek ( <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> s = self . content . read ( ) <EOL> clientFactory = class_ ( self . method , rest , self . clientproto , headers , <EOL> s , self ) <EOL> self . reactor . connectTCP ( host , port , clientFactory ) <EOL> class Proxy ( HTTPChannel ) : <EOL> """<STR_LIT>""" <EOL> requestFactory = ProxyRequest <EOL> class ReverseProxyRequest ( Request ) : <EOL> """<STR_LIT>""" <EOL> proxyClientFactoryClass = ProxyClientFactory <EOL> def __init__ ( self , channel , queued , reactor = reactor ) : <EOL> Request . __init__ ( self , channel , queued ) <EOL> self . reactor = reactor <EOL> def process ( self ) : <EOL> """<STR_LIT>""" <EOL> self . received_headers [ '<STR_LIT:host>' ] = self . factory . host <EOL> clientFactory = self . proxyClientFactoryClass ( <EOL> self . method , self . uri , self . clientproto , self . getAllHeaders ( ) , <EOL> self . content . read ( ) , self ) <EOL> self . reactor . connectTCP ( self . factory . host , self . factory . port , <EOL> clientFactory ) <EOL> class ReverseProxy ( HTTPChannel ) : <EOL> """<STR_LIT>""" <EOL> requestFactory = ReverseProxyRequest <EOL> class ReverseProxyResource ( Resource ) : <EOL> """<STR_LIT>""" <EOL> proxyClientFactoryClass = ProxyClientFactory <EOL> def __init__ ( self , host , port , path , reactor = reactor ) : <EOL> """<STR_LIT>""" <EOL> Resource . __init__ ( self ) <EOL> self . host = host <EOL> self . port = port <EOL> self . path = path <EOL> self . reactor = reactor <EOL> def getChild ( self , path , request ) : <EOL> """<STR_LIT>""" <EOL> return ReverseProxyResource ( <EOL> self . host , self . port , self . path + '<STR_LIT:/>' + urlquote ( path , safe = "<STR_LIT>" ) , <EOL> self . reactor ) <EOL> def render ( self , request ) : <EOL> """<STR_LIT>""" <EOL> if self . port == <NUM_LIT> : <EOL> host = self . host <EOL> else : <EOL> host = "<STR_LIT>" % ( self . host , self . port ) <EOL> request . received_headers [ '<STR_LIT:host>' ] = host <EOL> request . content . seek ( <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> qs = urlparse . urlparse ( request . uri ) [ <NUM_LIT:4> ] <EOL> if qs : <EOL> rest = self . path + '<STR_LIT:?>' + qs <EOL> else : <EOL> rest = self . path <EOL> clientFactory = self . proxyClientFactoryClass ( <EOL> request . method , rest , request . clientproto , <EOL> request . getAllHeaders ( ) , request . content . read ( ) , request ) <EOL> self . reactor . connectTCP ( self . host , self . port , clientFactory ) <EOL> return NOT_DONE_YET </s>
