;ò 4>ò>c@s—dZdkZdklZdkZdklZdeifd„ƒYZeZ defd„ƒYZ de fd „ƒYZ d e fd „ƒYZ dS( sžThis module contains the Proxy class. Although the Proxy class has a simple API, the module as a whole is quite confusing. Here are the logical entities involved: proxy client - This is the client of the proxy. proxied host - This is the host being proxied. proxy - This is the proxy as a whole. The proxy itself is devided into three parts: proxy server - This is the server portion of the proxy. It listens for connections from proxy clients. proxy server backend - this is backend of the proxy server. it handles a connection from a proxy client. proxied host client - This is the portion of the proxy that connects to the proxied host. Notice that proxy server backend and proxied host client are similar in that they each have a single connection. In fact, I call them peers. Consider the following usage scenario. The proxy client wishes to connect to the proxied host. The proxy client connects to the proxy server. The proxy server creates a proxy server backend. The proxy server backend start the creation of a proxy host client. If everything is successful, the proxy client can send data to the proxy server backend. The proxy server backend forwards the data to the proxy host client. The proxy host client forwards the data to the proxied host. The data flow above can be generalized to the following: A proxy server backend or proxied host client receives data, fowards it to its peer, who fowards it to its associated proxied host or proxy client respectively. The API is simple in that the user only has to worry about instantiating the Proxy class, catching socket.error exceptions, and calling asyncore.loop. By the way, due to the way the code flows, the Proxy class is actually just a pseudonym for the ProxyServer class. Concerning line endings, the standard is " ", but we need to be prepared to receive " " as well. Hence, look for " ", and if there's a " " in front of it, that's fine too. N(s async_chat(sStringIOs ProxyServercBs tZdZd„Zd„ZRS(s™This is the server portion of the proxy. It listens for connections from proxy clients. It is also the entry point into this module. Thus it goes by the pseudonym Proxy. The following private variables are used: _proxiedHost, _proxiedPort - These are host and port that are being proxied. _encrypt, _decrypt - These are the encrypt and decrypt functions to use. cCsdd}||_||_||_||_ |i t i t i ƒ|id|fƒ|i|ƒdS(s!Start listening on listeningPort.isN(sLISTENs proxiedHostsselfs _proxiedHosts proxiedPorts _proxiedPortsencrypts_encryptsdecrypts_decrypts create_socketssocketsAF_INETs SOCK_STREAMsbinds listeningPortslisten(sselfs proxiedHosts proxiedPorts listeningPortsencryptsdecryptsLISTEN((s ./Proxy.pys__init__Ds    cCsF|iƒ\}}t||iƒ}t||i|ƒ}||_ dS(sâAccept a connection. Create a _ProxyServerBackend and a _ProxiedHostClient. Let the _ProxiedHostClient instance take over processing since we now need to connect to the proxied host. N( sselfsacceptssocketsaddresss_ProxiedHostClients_decryptsproxiedHostClients_ProxyServerBackends_encryptsproxyServerBackendspeer(sselfsproxiedHostClientsproxyServerBackendsaddressssocket((s ./Proxy.pys handle_acceptPs   (s__name__s __module__s__doc__s__init__s handle_accept(((s ./Proxy.pys ProxyServer4s  s_PeercBs)tZdZd„Zd„Zd„ZRS(sThis is the base class for _ProxyServerBackend and _ProxiedHostClient. It provides common behavior concerning data flow. The following attributes are provided: peer - This is the peer of this _Peer. Remember that instances of _ProxyServerBackend and _ProxiedHostClient are peers of each other. The following private variables are used: _translator - Apply this to the data before transfering the data to this _Peer's peer. _buf - This is a StringIO buffer for incoming data. cCsHti||ƒ|idƒt|_||_||_ t ƒ|_ dS(s Initialize the async_chat class.s N( s async_chats__init__sselfssocketsset_terminatorsFalsesshutdownspeers translators _translatorsStringIOs_buf(sselfssockets translatorspeer((s ./Proxy.pys__init__us    cCs|ii|ƒdS(sJust buffer the data.N(sselfs_bufswritesdata(sselfsdata((s ./Proxy.pyscollect_incoming_data~scCs<|i|iiƒdƒ}|ii|ƒtƒ|_dS(s1Forward _translator(_buf) to peer and reset _buf.s N(sselfs _translators_bufsgetvalueslinespeerspushsStringIO(sselfsline((s ./Proxy.pysfound_terminator‚s(s__name__s __module__s__doc__s__init__scollect_incoming_datasfound_terminator(((s ./Proxy.pys_Peeras  s_ProxyServerBackendcBstZdZRS(s1This is backend of the proxy server. It handles a connection from a proxy client. It turns out that the baseclass is doing all the work. However, I'll keep this class just in case I end up needing to do something here. More importantly, it's helpful to maintain the terminology. (s__name__s __module__s__doc__(((s ./Proxy.pys_ProxyServerBackend‰s s_ProxiedHostClientcBs tZdZd„Zd„ZRS(sCThis is the portion of the proxy that connects to the proxied host.cCsIti|t|tƒ|ititiƒ|i |i |i fƒdS(s'Start a connection to the proxied host.N( s_Peers__init__sselfsNones translators create_socketssocketsAF_INETs SOCK_STREAMsconnects proxyServers _proxiedHosts _proxiedPort(sselfs proxyServers translator((s ./Proxy.pys__init__œscCsdS(s"Do nothing. This must be defined.N((sself((s ./Proxy.pyshandle_connect¢s(s__name__s __module__s__doc__s__init__shandle_connect(((s ./Proxy.pys_ProxiedHostClient˜s  ( s__doc__sasyncoresasynchats async_chatssockets cStringIOsStringIOs dispatchers ProxyServersProxys_Peers_ProxyServerBackends_ProxiedHostClient( s_ProxiedHostClientsasyncoressocketsStringIOs ProxyServersProxys_ProxyServerBackends_Peers async_chat((s ./Proxy.pys?,s    *(