【问题标题】:Django as reverse proxyDjango 作为反向代理
【发布时间】:2011-03-07 22:43:54
【问题描述】:

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

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

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

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

该问题是否有替代解决方案?

【问题讨论】:

    标签: django http client-server reverse-proxy


    【解决方案1】:

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

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

    【讨论】:

    • 我不想设置和 nginx 服务器只是这样做。但我在生产中得到了它。我想反映 proxy_pass 行为。所以我用你的脚本和this 非常简单的中间件与你的观点。谢谢
    【解决方案2】:

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

    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
    

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

    【讨论】:

    • 在您使用的codelet中,不传输标头。有没有一种简单的方法可以按原样传递传入的请求。我正在做类似的事情,并想要 apss o-auth 标头。但是想要一个干净的解决方案,它可以通过所有标题(以供将来打样)。所以本质上我想写一个反向代理,但在特殊目的的 url 上重定向,从我的 django 应用程序中提供其余的服务。
    • 我已更新示例代码以包含 HTTP 标头的传递。您可能需要弹出或修改一些原始请求标头,例如'主机','连接'。
    猜你喜欢
    • 2011-06-19
    • 1970-01-01
    • 2011-03-24
    • 1970-01-01
    • 2021-11-13
    • 2021-06-17
    • 2016-12-20
    • 2010-11-20
    • 2011-10-20
    相关资源
    最近更新 更多