防止Django在代理HTTP请求时阻塞
我正在Django网站上工作,该网站允许通过云服务连接到受限网络中的设备。设备通过VPN或SSH隧道连接到云服务器,客户端通过HTTP连接到虚拟主机。Django部分是管理复杂的组织角色访问用户关系所必需的 目前,我正在一个定制的Django中间件模块中进行访问控制,该模块解析HTTP_主机,进行身份验证,获取页面并将其转发给原始请求者。问题是,当请求进行时,Django不处理任何其他请求。芹菜不能解决问题,因为这不是真正的后台任务。客户端通过单个地址和端口提供服务,这使得防火墙规则不适合此任务 相关代码如下:防止Django在代理HTTP请求时阻塞,django,http,nginx,proxy,uwsgi,Django,Http,Nginx,Proxy,Uwsgi,我正在Django网站上工作,该网站允许通过云服务连接到受限网络中的设备。设备通过VPN或SSH隧道连接到云服务器,客户端通过HTTP连接到虚拟主机。Django部分是管理复杂的组织角色访问用户关系所必需的 目前,我正在一个定制的Django中间件模块中进行访问控制,该模块解析HTTP_主机,进行身份验证,获取页面并将其转发给原始请求者。问题是,当请求进行时,Django不处理任何其他请求。芹菜不能解决问题,因为这不是真正的后台任务。客户端通过单个地址和端口提供服务,这使得防火墙规则不适合此任务
class NodeProxyMiddleware:
def process_request(self, request, *args, **kwargs):
if not 'HTTP_HOST' in request.META:
return None
hardware_id = match_hwid.match(request.META["HTTP_HOST"])
if not hardware_id:
return None
kwargs["hardware_id"] = hardware_id.group("hwid")
if not authenticate(request, *args, **kwargs):
return HttpResponseForbidden("No access")
return proxy_request(request, *args, **kwargs)
@csrf_exempt
def proxy_request(request, *args, **kwargs):
# Get the port of target Node
hardware_id = kwargs.get("hardware_id", "")
try:
port = Node.objects.filter(hardware_id=hardware_id)[0].port
except IndexError: # Node with given hwid was not found
raise Http404
# We have to convert request.META back to original form manually
headers = convert_headers(request) # HTTP_FOO_BAR to Foo-Bar
headers["connection"] = "close"
connection = httplib2.Http(timeout=5)
url = "http://127.0.0.1:%d%s" % (port, request.META['PATH_INFO'])
method = request.method
# GET -- url ?d=a&t=a has to be urlencoded
if method == "GET":
data = None
if request.GET:
url += "?" + request.GET.urlencode()
# POST -- body has to be urlencoded
elif method == "POST":
data = request.POST.urlencode()
headers["content-type"] = "application/x-www-form-urlencoded"
try:
response, content = connection.request(
url, method, data, headers=headers)
except Exception as e:
print e
return HttpResponse(content=e, status=503)
django_response = HttpResponse(
content=content,
status=int(response["status"]),
mimetype=response["content-type"],
)
# Strip hop-by-hop headers -- See RFC2616 semantically transparent
# proxying. Also, WSGI forbids passing such headers back to it.
hop_by_hop_headers = [
"connection",
"keep-alive",
"proxy-authenticate",
"proxy-authorization",
"te",
"trailers",
"transfer-encoding",
"upgrade",
]
for key, value in response.iteritems():
if key.lower() in hop_by_hop_headers:
continue
django_response[key] = value
return django_response
在Django中,通过调整上面的代码或其他设置是否可以执行这种代理?我运行的软件栈是Nginx+uWSGI+Django 1.6。uWSGI配置为:
[uwsgi]
chdir = /home/foo/production/
file = /home/foo/production/wsgi.py
home = /home/foo/virtualenv
master = true
processes = 8
socket = /var/nginx/foo.socket
chmod-socket = 666
vacuum = true
daemonize = /home/foo/production/uwsgi.log
你的uwsgi.ini是什么?我所能想到的是,您只需在上面编辑和添加WSGI服务器配置。