Django作为反向代理

时间:2011-03-07 22:43:54

标签: django http client-server reverse-proxy

我的客户端 - 服务器应用程序主要基于专用的http服务器,它以类似Ajax的方式与客户端通信,即。客户端GUI在异步http请求/响应周期时刷新。

专用http服务器的可扩展性是有限的,随着应用程序的增长,需要越来越多的标准功能,例如Django提供的。

因此,我想添加一个Django应用程序作为外观/反向代理,以隐藏非标准的专用服务器,并能够从Django获得。我想将Django应用程序作为网关,出于安全原因而不使用http-redirect并隐藏复杂性。

然而,我担心的是,在服务器上通过Django隧道传输可能会破坏性能。这是一个有效的问题吗?

这个问题会有替代解决方案吗?

2 个答案:

答案 0 :(得分:3)

我继续建造了一个简单的原型。它相对简单,我只需要设置一个映射,映射我想要重定向的所有URL。 view函数看起来像这样:

def redirect(request):
    url = "http://%s%s" % (server, request.path)
    # add get parameters
    if request.GET:
        url += '?' + urlencode(request.GET)

    # add headers of the incoming request
    # see https://docs.djangoproject.com/en/1.7/ref/request-response/#django.http.HttpRequest.META for details about the request.META dict
    def convert(s):
        s = s.replace('HTTP_','',1)
        s = s.replace('_','-')
        return s

    request_headers = dict((convert(k),v) for k,v in request.META.iteritems() if k.startswith('HTTP_'))
    # add content-type and and content-length
    request_headers['CONTENT-TYPE'] = request.META.get('CONTENT_TYPE', '')
    request_headers['CONTENT-LENGTH'] = request.META.get('CONTENT_LENGTH', '')

    # get original request payload
    if request.method == "GET":
        data = None
    else:
        data = request.raw_post_data

    downstream_request = urllib2.Request(url, data, headers=request_headers)
    page = urllib2.urlopen(downstream_request)
    response = django.http.HttpResponse(page)
    return response

所以它实际上非常简单并且性能足够好,特别是如果重定向到同一主机上的环回接口。

答案 1 :(得分:2)

通常在制作中,您将在Apache httpd或nginx等Web容器后面托管Django。这些模块设计用于代理请求(例如,proxy_pass用于nginx中的location。如果你需要的话,它们可以像开箱一样为你提供一些额外的功能。与通过Django应用程序的请求管道进行代理相比,这可以节省您的开发时间,同时提供更好的性能。但是,当您使用这样的解决方案时,您牺牲了完全操纵请求或代理响应的能力。

对于./manage.py runserver的本地测试,我在urls.py部分的if settings.DEBUG: ...添加了一个网址模式。这是我使用的视图功能代码,它使用 requests Python库支持GET,PUT和POST:https://gist.github.com/JustinTArthur/5710254