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.

Revisions

  1. fiorix revised this gist Jul 18, 2012. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion tcp-proxy.py
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,6 @@
    #!/usr/bin/env python
    # coding: utf-8
    # http://musta.sh/2012-03-04/twisted-tcp-proxy.html

    import sys

    @@ -72,4 +73,4 @@ def connectionLost(self, why):
    factory = protocol.Factory()
    factory.protocol = ProxyServer
    reactor.listenTCP(9999, factory, interface="0.0.0.0")
    reactor.run()
    reactor.run()
  2. fiorix created this gist Feb 21, 2012.
    75 changes: 75 additions & 0 deletions tcp-proxy.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,75 @@
    #!/usr/bin/env python
    # coding: utf-8

    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()