{ "info": { "author": "Benoit Chesneau", "author_email": "benoitc@e-engura.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Other Environment", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: MacOS :: MacOS X", "Operating System :: POSIX", "Programming Language :: Python", "Topic :: Internet", "Topic :: Internet :: Proxy Servers", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: System :: Networking", "Topic :: Utilities" ], "description": "tproxy\n------\n\ntproxy is a simple TCP routing proxy (layer 7) built on\nGevent_ that lets you configure the routine logic in Python. It's heavily\ninspired from `proxy machine `_\nbut have some unique features like the pre-fork worker model borrowed to\nGunicorn_.\n\n\nInstalation\n-----------\n\ntproxy requires **Python 2.x >= 2.5**. Python 3.x support is planned.\n\n::\n\n $ pip install gevent\n $ pip install tproxy\n\nTo install from source::\n\n $ git clone git://github.com/benoitc/tproxy.git\n $ cd tproxy\n $ pip install -r requirements.txt\n $ python setup.py install\n\n\nTest your installation by running the command line::\n\n $ tproxy examples/transparent.py\n\nAnd go on http://127.0.0.1:5000 , you should see the google homepage.\n\n\nUsage\n-----\n\n::\n\n $ tproxy -h\n\n Usage: tproxy [OPTIONS] script_path\n\n Options:\n --version show program's version number and exit\n -h, --help show this help message and exit\n --log-file=FILE The log file to write to. [-]\n --log-level=LEVEL The granularity of log outputs. [info]\n --log-config=FILE The log config file to use. [None]\n -n STRING, --name=STRING A base to use with setproctitle for process naming.\n [None]\n -D, --daemon Daemonize the tproxy process. [False]\n -p FILE, --pid=FILE A filename to use for the PID file. [None]\n -u USER, --user=USER Switch worker processes to run as this user. [501]\n -g GROUP, --group=GROUP\n Switch worker process to run as this group. [20]\n -m INT, --umask=INT A bit mask for the file mode on files written by\n tproxy. [0]\n -b ADDRESS, --bind=ADDRESS The socket to bind. [127.0.0.1:8000]\n --backlog=INT The maximum number of pending connections. [2048]\n --ssl-keyfile=STRING Ssl key file [None]\n --ssl-certfile=STRING Ssl ca certs file. contains concatenated\n \"certification [None]\n --ssl-ca-certs=STRING Ssl ca certs file. contains concatenated\n \"certification [None]\n --ssl-cert-reqs=INT Specifies whether a certificate is required from the\n other [0]\n -w INT, --workers=INT The number of worker process for handling requests. [1]\n --worker-connections=INT The maximum number of simultaneous clients per worker.\n [1000]\n -t INT, --timeout=INT Workers silent for more than this many seconds are\n killed and restarted. [30]\n\nSignals\n-------\n::\n\n QUIT - Graceful shutdown. Stop accepting connections immediatly\n and wait until all connections close\n\n TERM - Fast shutdown. Stop accepting and close all conections\n after 10s.\n INT - Same as TERM\n\n HUP - Graceful reloading. Reload all workers with the new code\n in your routing script.\n \n USR2 - Upgrade tproxy on the fly\n \n TTIN - Increase the number of worker from 1\n \n TTOU - Decrease the number of worker from 1\n\n\nExemple of routing script\n-------------------------\n\n::\n\n import re\n re_host = re.compile(\"Host:\\s*(.*)\\r\\n\")\n\n class CouchDBRouter(object):\n # look at the routing table and return a couchdb node to use\n def lookup(self, name):\n \"\"\" do something \"\"\"\n\n router = CouchDBRouter()\n\n # Perform content-aware routing based on the stream data. Here, the\n # Host header information from the HTTP protocol is parsed to find the \n # username and a lookup routine is run on the name to find the correct\n # couchdb node. If no match can be made yet, do nothing with the\n # connection. (make your own couchone server...)\n\n def proxy(data):\n matches = re_host.findall(data)\n if matches:\n host = router.lookup(matches.pop()) \n return {\"remote\": host}\n return None \n\nExample SOCKS4 Proxy in 18 Lines\n--------------------------------\n\n::\n\n import socket\n import struct\n\n def proxy(data):\n if len(data) < 9:\n return\n\n command = ord(data[1])\n ip, port = socket.inet_ntoa(data[4:8]), struct.unpack(\">H\", data[2:4])[0]\n idx = data.index(\"\\0\")\n userid = data[8:idx]\n\n if command == 1: #connect\n return dict(remote=\"%s:%s\" % (ip, port),\n reply=\"\\0\\x5a\\0\\0\\0\\0\\0\\0\",\n data=data[idx:])\n else:\n return {\"close\": \"\\0\\x5b\\0\\0\\0\\0\\0\\0\"}\n\nExample of returning a file\n---------------------------\n\n::\n\n import os\n\n WELCOME_FILE = os.path.join(os.path.dirname(__file__), \"welcome.txt\")\n\n def proxy(data):\n fno = os.open(WELCOME_FILE, os.O_RDONLY) \n return {\n \"file\": fno,\n \"reply\": \"HTTP/1.1 200 OK\\r\\n\\r\\n\"\n }\n\nValid return values\n-------------------\n\n* { \"remote:\": string or tuple } - String is the host:port of the\n server that will be proxied.\n* { \"remote\": String, \"data\": String} - Same as above, but\n send the given data instead.\n* { \"remote\": String, \"data\": String, \"reply\": String} - Same as above,\n but reply with given data back to the client \n* None - Do nothing.\n* { \"close\": True } - Close the connection.\n* { \"close\": String } - Close the connection after sending\n the String.\n* { \"file\": String }\u00a0- Return a file specify by the file path and close\n the connection.\n* { \"file\": String, \"reply\": String }\u00a0- Return a file specify by the\n file path and close the connection.\n* { \"file\": Int, \"reply\": String}\u00a0- Same as above but reply with given\n data back to the client \n* { \"file\": Int }\u00a0- Return a file specify by\n its file descriptor \n* { \"file\": Int, \"reply\": String}\u00a0- Same as above\n but reply with given data back to the client\n\nNotes:\n++++++\n\nIf `sendfile `_ API available it\nwill be used to send a file with \"file\" command. \n\nThe **file** command can have 2 optionnnal parameters:\n\n- offset: argument specifies where to begin in the file.\n- nbytes: specifies how many bytes of the file should be sent\n\n\nTo **handle ssl for remote connection** you can add these optionals\narguments:\n\n- ssl: True or False, if you want to connect with ssl\n- ssl_args: dict, optionals ssl arguments. Read the `ssl documentation\n `_ for more informations about them. \n\nHandle errors\n-------------\n\nYou can easily handling error by adding a **proxy_error** function in\nyour script::\n\n def proxy_error(client, e):\n pass\n\nThis function get the ClientConnection instance (current connection) as\nfirst arguments and the error exception in second argument.\n\nRewrite requests & responses\n----------------------------\n\nMain goal of tproxy is to allows you to route transparently tcp to your\napplications. But some case you want to do more. For example you need in\nHTTP 1.1 to change the Host header to make sure remote HTTP server will\nknow what to do if uses virtual hosting.\n\nTo do that, add a **rewrite_request** function in your function to\nsimply rewrite clienrt request and **rewrite_response** to rewrite the\nremote response. Both functions take a tproxy.rewrite.RewriteIO instance\nwhich is based on io.RawIOBase class.\n\nSee the `httprewrite.py `_ example for an example of HTTP rewrite.\n\n\nCopyright\n---------\n2011 (c) Beno\u00eet Chesneau \n\n\n.. _Gevent: http://gevent.org\n.. _Gunicorn: http://gunicorn.org", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/benoitc/tproxy", "keywords": null, "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "tproxy", "package_url": "https://pypi.org/project/tproxy/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/tproxy/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/benoitc/tproxy" }, "release_url": "https://pypi.org/project/tproxy/0.5.4/", "requires_dist": null, "requires_python": null, "summary": "WSGI HTTP Server for UNIX", "version": "0.5.4" }, "last_serial": 800837, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "3146b11d415be13f9f59a8e540175baa", "sha256": "17a31126e3c08494c7da9899dc9e4f9730af19f07efb658b55d3b2d1f7d631dc" }, "downloads": -1, "filename": "tproxy-0.1.0.tar.gz", "has_sig": false, "md5_digest": "3146b11d415be13f9f59a8e540175baa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18181, "upload_time": "2011-04-12T15:49:46", "url": "https://files.pythonhosted.org/packages/f5/55/ce93e74dcf2d41bd4c9d670740376605137ee40b132347e7fdb29574058a/tproxy-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "dc155cdf89399f005fdf78641b157e9b", "sha256": "58217121186618e25110494bbca56364c9f13824b52d5c1d8aa93d3ea8bf499f" }, "downloads": -1, "filename": "tproxy-0.2.0.tar.gz", "has_sig": false, "md5_digest": "dc155cdf89399f005fdf78641b157e9b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21677, "upload_time": "2011-04-19T11:53:21", "url": "https://files.pythonhosted.org/packages/87/12/8d040fd67aeec79c4a1438940b5bcebc17511d82e8ab04dbdc70cf98a36c/tproxy-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "678fa162f365b2774f36df2c34744bcf", "sha256": "9a2d069e43de4dcc3b410e08163b800566b3a2e8e15648955d8f5757417d7916" }, "downloads": -1, "filename": "tproxy-0.2.1.tar.gz", "has_sig": false, "md5_digest": "678fa162f365b2774f36df2c34744bcf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21972, "upload_time": "2011-04-19T12:06:02", "url": "https://files.pythonhosted.org/packages/ec/2e/d0e36feeda2f6d1f5df791266f30fdf31c56db322c3638100a04c292d2b8/tproxy-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "80768c58ddd140bad726fcbd488bb198", "sha256": "a59e4a993cfa3b634ed0f7b85600c9d808ae73f15c98dc86c6989aa3e6253be2" }, "downloads": -1, "filename": "tproxy-0.2.2.tar.gz", "has_sig": false, "md5_digest": "80768c58ddd140bad726fcbd488bb198", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22039, "upload_time": "2011-04-19T14:30:13", "url": "https://files.pythonhosted.org/packages/35/9c/1d39621932bfc8f16146a81619f04c7643af9b62f177b9e76312f52f3df8/tproxy-0.2.2.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "ed1f77b1c9603666a8b3fa978704b8db", "sha256": "43017db60df9b21e05663bae43665b2468143bf82a39e99114d019ded2d0af18" }, "downloads": -1, "filename": "tproxy-0.2.3.tar.gz", "has_sig": false, "md5_digest": "ed1f77b1c9603666a8b3fa978704b8db", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22586, "upload_time": "2011-04-19T15:35:41", "url": "https://files.pythonhosted.org/packages/d1/11/98272f88667f5d1fa75ec2cfd2194cc377d4e1972849eb879d3557414d70/tproxy-0.2.3.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "28293bb3d26098e75ea41e0be484e29c", "sha256": "81260c9f03a9e15acc455edb4dcb441a2193d2e83b8ceeae5757963429a9bebc" }, "downloads": -1, "filename": "tproxy-0.3.0.tar.gz", "has_sig": false, "md5_digest": "28293bb3d26098e75ea41e0be484e29c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22733, "upload_time": "2011-05-02T13:13:02", "url": "https://files.pythonhosted.org/packages/08/13/a9f8c2e14adb41095d857303dda1bb82a6ca54846ae7184a4338a4628ee5/tproxy-0.3.0.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "5c53bdcbaac0cfa0691be44d97938dd3", "sha256": "efd8acaba05fb420c1b3be5d9abd8c0420d29fc7dc37ebc48970b4bb087f6037" }, "downloads": -1, "filename": "tproxy-0.4.0.tar.gz", "has_sig": false, "md5_digest": "5c53bdcbaac0cfa0691be44d97938dd3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24172, "upload_time": "2011-05-02T22:13:55", "url": "https://files.pythonhosted.org/packages/fc/5e/f6dd33eeb008d7e8db8ba95014afbee9cc1cd938424fa17dc7b45538048b/tproxy-0.4.0.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "ceb990a592aa3d2a2a1cb0e5751664c0", "sha256": "8a5338c0dccb76f74823ece7c7c94d207171151d6931e3d3d895ebf1ad3c4830" }, "downloads": -1, "filename": "tproxy-0.4.1.tar.gz", "has_sig": false, "md5_digest": "ceb990a592aa3d2a2a1cb0e5751664c0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24287, "upload_time": "2011-05-02T22:21:12", "url": "https://files.pythonhosted.org/packages/23/fb/ba257fed77ef57d9f5ae116368c8b829daf4a3bae94608a46e36073101d9/tproxy-0.4.1.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "3d3b5e6af5eea03e730582f0f968538a", "sha256": "a411372a649dbeca91b52c8f60238711545702a6ae65266a086152b286254ad0" }, "downloads": -1, "filename": "tproxy-0.5.0.tar.gz", "has_sig": false, "md5_digest": "3d3b5e6af5eea03e730582f0f968538a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23894, "upload_time": "2011-05-04T01:31:30", "url": "https://files.pythonhosted.org/packages/dc/d2/af839d007d42d40d8bd9f806261c3d91f78e51bf47ebcd04ef345c73bea2/tproxy-0.5.0.tar.gz" } ], "0.5.1": [ { "comment_text": "", "digests": { "md5": "2963703e711c0ed8896542c1e60ddff0", "sha256": "629820c7892da4e499ef59c24baf16d015e21ae5e52c00878536d899f548aeaf" }, "downloads": -1, "filename": "tproxy-0.5.1.tar.gz", "has_sig": false, "md5_digest": "2963703e711c0ed8896542c1e60ddff0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23813, "upload_time": "2011-05-05T22:16:47", "url": "https://files.pythonhosted.org/packages/6f/e9/63e5b46ce23c18eeee963b1c69fec1c23cbdbe3350faed02d00bb3f5dc24/tproxy-0.5.1.tar.gz" } ], "0.5.2": [ { "comment_text": "", "digests": { "md5": "e6cd652641ca0a074dfe36d313dc83dd", "sha256": "829a1c3fe5c6ef2909cd1102b95f58d3251b140838fd1d58b4bda3905ef20ff4" }, "downloads": -1, "filename": "tproxy-0.5.2.tar.gz", "has_sig": false, "md5_digest": "e6cd652641ca0a074dfe36d313dc83dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24527, "upload_time": "2011-05-05T23:37:56", "url": "https://files.pythonhosted.org/packages/9c/46/fd06b669be5626993d7b0f36dd45e37ef1cc818dc93812f7244ba211c823/tproxy-0.5.2.tar.gz" } ], "0.5.3": [ { "comment_text": "", "digests": { "md5": "79e16933307561a4d01cb8c9293a0c43", "sha256": "4828f63f593fb409315ff4f868fe16f9f96d1220cc4ef025578086281a36e183" }, "downloads": -1, "filename": "tproxy-0.5.3.tar.gz", "has_sig": false, "md5_digest": "79e16933307561a4d01cb8c9293a0c43", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26126, "upload_time": "2011-05-10T14:04:43", "url": "https://files.pythonhosted.org/packages/c8/68/b6d19fdc565de02e17075e90d993c1baa0295f9db79748ec0309d303e79d/tproxy-0.5.3.tar.gz" } ], "0.5.4": [ { "comment_text": "", "digests": { "md5": "fde87839e38a6cb60d68ccc8ef05ff01", "sha256": "d5f17a4fed54f35494c7e7ad12e10dfbb790904c5e7e319476560497948879d1" }, "downloads": -1, "filename": "tproxy-0.5.4.tar.gz", "has_sig": false, "md5_digest": "fde87839e38a6cb60d68ccc8ef05ff01", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25847, "upload_time": "2011-05-11T19:04:46", "url": "https://files.pythonhosted.org/packages/29/de/6a142a2027b10432cdae67732fd0e8b096730b778ec5099a1813a3372d5f/tproxy-0.5.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "fde87839e38a6cb60d68ccc8ef05ff01", "sha256": "d5f17a4fed54f35494c7e7ad12e10dfbb790904c5e7e319476560497948879d1" }, "downloads": -1, "filename": "tproxy-0.5.4.tar.gz", "has_sig": false, "md5_digest": "fde87839e38a6cb60d68ccc8ef05ff01", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25847, "upload_time": "2011-05-11T19:04:46", "url": "https://files.pythonhosted.org/packages/29/de/6a142a2027b10432cdae67732fd0e8b096730b778ec5099a1813a3372d5f/tproxy-0.5.4.tar.gz" } ] }