Package: tproxy
tproxytproxy is a simple TCP routing proxy (layer 7)  built onGeventthat lets you configure the routine logic in Python. It’s heavily
inspired fromproxy machinebut have some unique features like the pre-fork worker model borrowed toGunicorn.Instalationtproxy requiresPython 2.x >= 2.5. Python 3.x support is planned.$ pip install gevent
$ pip install tproxyTo install from source:$ git clone git://github.com/benoitc/tproxy.git
$ cd tproxy
$ pip install -r requirements.txt
$ python setup.py installTest your installation by running the command line:$ tproxy examples/transparent.pyAnd go onhttp://127.0.0.1:5000, you should see the google homepage.Usage$ tproxy -h

Usage: tproxy [OPTIONS] script_path

Options:
  --version                     show program's version number and exit
  -h, --help                    show this help message and exit
  --log-file=FILE               The log file to write to. [-]
  --log-level=LEVEL             The granularity of log outputs. [info]
  --log-config=FILE             The log config file to use. [None]
  -n STRING, --name=STRING      A base to use with setproctitle for process naming.
                                [None]
  -D, --daemon                  Daemonize the tproxy process. [False]
  -p FILE, --pid=FILE           A filename to use for the PID file. [None]
  -u USER, --user=USER          Switch worker processes to run as this user. [501]
  -g GROUP, --group=GROUP
                                Switch worker process to run as this group. [20]
  -m INT, --umask=INT           A bit mask for the file mode on files written by
                                tproxy. [0]
  -b ADDRESS, --bind=ADDRESS    The socket to bind. [127.0.0.1:8000]
  --backlog=INT                 The maximum number of pending connections.     [2048]
  --ssl-keyfile=STRING          Ssl key file [None]
  --ssl-certfile=STRING         Ssl ca certs file. contains concatenated
                                "certification [None]
  --ssl-ca-certs=STRING         Ssl ca certs file. contains concatenated
                                "certification [None]
  --ssl-cert-reqs=INT           Specifies whether a certificate is required from the
                                other [0]
  -w INT, --workers=INT         The number of worker process for handling requests. [1]
  --worker-connections=INT      The maximum number of simultaneous clients per worker.
                                [1000]
  -t INT, --timeout=INT         Workers silent for more than this many seconds are
                                killed and restarted. [30]SignalsQUIT    -   Graceful shutdown. Stop accepting connections immediatly
            and wait until all connections close

TERM    -   Fast shutdown. Stop accepting and close all conections
            after 10s.
INT     -   Same as TERM

HUP     -   Graceful reloading. Reload all workers with the new code
            in your routing script.

USR2    -   Upgrade tproxy on the fly

TTIN    -   Increase the number of worker from 1

TTOU    -   Decrease the number of worker from 1Exemple of routing scriptimport re
re_host = re.compile("Host:\s*(.*)\r\n")

class CouchDBRouter(object):
    # look at the routing table and return a couchdb node to use
    def lookup(self, name):
        """ do something """

router = CouchDBRouter()

# Perform content-aware routing based on the stream data. Here, the
# Host header information from the HTTP protocol is parsed to find the
# username and a lookup routine is run on the name to find the correct
# couchdb node. If no match can be made yet, do nothing with the
# connection. (make your own couchone server...)

def proxy(data):
    matches = re_host.findall(data)
    if matches:
        host = router.lookup(matches.pop())
        return {"remote": host}
    return NoneExample SOCKS4 Proxy in 18 Linesimport socket
import struct

def proxy(data):
    if len(data) < 9:
        return

    command = ord(data[1])
    ip, port = socket.inet_ntoa(data[4:8]), struct.unpack(">H", data[2:4])[0]
    idx = data.index("\0")
    userid = data[8:idx]

    if command == 1: #connect
        return dict(remote="%s:%s" % (ip, port),
                reply="\0\x5a\0\0\0\0\0\0",
                data=data[idx:])
    else:
        return {"close": "\0\x5b\0\0\0\0\0\0"}Example of returning a fileimport os

WELCOME_FILE = os.path.join(os.path.dirname(__file__), "welcome.txt")

def proxy(data):
    fno = os.open(WELCOME_FILE, os.O_RDONLY)
    return {
            "file": fno,
            "reply": "HTTP/1.1 200 OK\r\n\r\n"
           }Valid return values{ “remote:”: string or tuple } - String is the host:port of the
server that will be proxied.{ “remote”: String, “data”: String} - Same as above, but
send the given data instead.{ “remote”: String, “data”: String, “reply”: String} - Same as above,
but reply with given data back to the clientNone  - Do nothing.{ “close”: True } - Close the connection.{ “close”: String } - Close the connection after sending
the String.{ “file”: String } - Return a file specify by the file path and close
the connection.{ “file”: String, “reply”: String } - Return a file specify by the
file path and close the connection.{ “file”: Int, “reply”: String} - Same as above but reply with given
data back to the client{ “file”: Int } - Return a file specify by
its file descriptor{ “file”: Int, “reply”: String} - Same as above
but reply with given data back to the clientNotes:IfsendfileAPI available it
will be used to send a file with “file” command.Thefilecommand can have 2 optionnnal parameters:offset: argument specifies where to begin in the file.nbytes: specifies how many bytes of the file should be sentTohandle ssl for remote connectionyou can add these optionals
arguments:ssl: True or False, if you want to connect with sslssl_args: dict, optionals ssl arguments. Read thessl documentationfor more informations about them.Handle errorsYou can easily handling error by adding aproxy_errorfunction in
your script:def proxy_error(client, e):
    passThis function get the ClientConnection instance (current connection) as
first arguments and the error exception in second argument.Rewrite requests & responsesMain goal of tproxy is to allows you to route transparently tcp to your
applications. But some case you want to do more. For example you need in
HTTP 1.1 to change the Host header to make sure remote HTTP server will
know what to do if uses virtual hosting.To do that, add arewrite_requestfunction in your function to
simply rewrite clienrt request andrewrite_responseto rewrite the
remote response. Both functions take a tproxy.rewrite.RewriteIO instance
which is based on io.RawIOBase class.See thehttprewrite.pyexample for an example of HTTP rewrite.Copyright2011 (c) Benoît Chesneau <benoitc@e-engura.org>