UNIX WSGI HTTP服务器
项目描述
tproxy
tproxy是一个简单的TCP路由代理(第7层),基于Gevent构建,允许您用Python配置路由逻辑。它深受proxy machine的启发,但有一些独特功能,例如从Gunicorn借用到的预fork工作模型。
安装
tproxy需要Python 2.x >= 2.5。计划支持Python 3.x。
$ pip install gevent $ pip install tproxy
从源安装
$ git clone git://github.com/benoitc/tproxy.git $ cd tproxy $ pip install -r requirements.txt $ python setup.py install
通过运行命令行测试您的安装
$ tproxy examples/transparent.py
然后转到http://127.0.0.1:5000,您应该看到谷歌主页。
用法
$ 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]
信号
QUIT - 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 1
路由脚本示例
import 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 None
18行内的SOCKS4代理示例
import 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"}
返回文件的示例
import 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"
}
有效的返回值
{ “remote:”: string or tuple } - String是代理的服务器的主机:端口。
{ “remote”: String, “data”: String} - 同上,但发送给定数据。
{ “remote”: String, “data”: String, “reply”: String} - 同上,但向客户端发送给定数据作为回复。
None - 不做任何事情。
{ “close”: True } - 关闭连接。
{ “close”: String } - 在发送字符串后关闭连接。
{ “file”: String } - 通过文件路径返回指定文件并关闭连接。
{ “file”: String, “reply”: String } - 通过文件路径返回指定文件并关闭连接。
{ “file”: Int, “reply”: String} - 与上述相同,但用给定数据回复客户端
{ “file”: Int } - 返回指定文件描述符的文件
{ “file”: Int, “reply”: String} - 与上述相同,但用给定数据回复客户端
注意事项
如果sendfile API可用,它将用于通过“file”命令发送文件。
“file”命令可以有2个可选参数
offset: 指定从文件中的哪个位置开始。
nbytes: 指定应发送多少字节的文件。
要为远程连接处理ssl,您可以添加以下可选参数
ssl: True或False,如果您想使用ssl连接
ssl_args: dict,可选ssl参数。阅读ssl文档以获取更多关于它们的信息。
处理错误
您可以通过在脚本中添加一个名为proxy_error的函数来轻松处理错误。
def proxy_error(client, e):
pass
该函数将ClientConnection实例(当前连接)作为第一个参数,错误异常作为第二个参数。
重写请求与响应
tproxy的主要目标是允许您透明地路由tcp到您的应用程序。但有些情况下您需要做更多。例如,在HTTP 1.1中,您需要更改Host头,以确保远程HTTP服务器知道如何处理使用虚拟主机的情况。
为此,请将rewrite_request函数添加到您的函数中,以简单地重写客户端请求,将rewrite_response重写为远程响应。这两个函数都接受一个基于io.RawIOBase类的tproxy.rewrite.RewriteIO实例。
请参阅httprewrite.py示例,了解HTTP重写的示例。
版权
2011 (c) Benoît Chesneau <benoitc@e-engura.org>
项目详情
tproxy-0.5.4.tar.gz的散列
| 算法 | 散列摘要 | |
|---|---|---|
| SHA256 | d5f17a4fed54f35494c7e7ad12e10dfbb790904c5e7e319476560497948879d1 |
|
| MD5 | fde87839e38a6cb60d68ccc8ef05ff01 |
|
| BLAKE2b-256 | 29de6a142a2027b10432cdae67732fd0e8b096730b778ec5099a1813a3372d5f |