Skip to content

Instantly share code, notes, and snippets.

@fiorix
Created February 21, 2012 21:12
Show Gist options
  • Save fiorix/1878983 to your computer and use it in GitHub Desktop.
Save fiorix/1878983 to your computer and use it in GitHub Desktop.
twisted tcp proxy
#!/usr/bin/env python
# coding: utf-8
# http://musta.sh/2012-03-04/twisted-tcp-proxy.html
import sys
from twisted.internet import defer
from twisted.internet import protocol
from twisted.internet import reactor
from twisted.python import log
class ProxyClientProtocol(protocol.Protocol):
def connectionMade(self):
log.msg("Client: connected to peer")
self.cli_queue = self.factory.cli_queue
self.cli_queue.get().addCallback(self.serverDataReceived)
def serverDataReceived(self, chunk):
if chunk is False:
self.cli_queue = None
log.msg("Client: disconnecting from peer")
self.factory.continueTrying = False
self.transport.loseConnection()
elif self.cli_queue:
log.msg("Client: writing %d bytes to peer" % len(chunk))
self.transport.write(chunk)
self.cli_queue.get().addCallback(self.serverDataReceived)
else:
self.factory.cli_queue.put(chunk)
def dataReceived(self, chunk):
log.msg("Client: %d bytes received from peer" % len(chunk))
self.factory.srv_queue.put(chunk)
def connectionLost(self, why):
if self.cli_queue:
self.cli_queue = None
log.msg("Client: peer disconnected unexpectedly")
class ProxyClientFactory(protocol.ReconnectingClientFactory):
maxDelay = 10
continueTrying = True
protocol = ProxyClientProtocol
def __init__(self, srv_queue, cli_queue):
self.srv_queue = srv_queue
self.cli_queue = cli_queue
class ProxyServer(protocol.Protocol):
def connectionMade(self):
self.srv_queue = defer.DeferredQueue()
self.cli_queue = defer.DeferredQueue()
self.srv_queue.get().addCallback(self.clientDataReceived)
factory = ProxyClientFactory(self.srv_queue, self.cli_queue)
reactor.connectTCP("127.0.0.1", 6666, factory)
def clientDataReceived(self, chunk):
log.msg("Server: writing %d bytes to original client" % len(chunk))
self.transport.write(chunk)
self.srv_queue.get().addCallback(self.clientDataReceived)
def dataReceived(self, chunk):
log.msg("Server: %d bytes received" % len(chunk))
self.cli_queue.put(chunk)
def connectionLost(self, why):
self.cli_queue.put(False)
if __name__ == "__main__":
log.startLogging(sys.stdout)
factory = protocol.Factory()
factory.protocol = ProxyServer
reactor.listenTCP(9999, factory, interface="0.0.0.0")
reactor.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment