2011-03-07 193 views
2

我的客户端 - 服务器应用程序主要基于特殊用途的http服务器,它以类似于Ajax的方式与客户端进行通信,例如,客户端GUI在异步http请求/响应周期被刷新。Django作为反向代理

特殊目的http服务器的可演化性是有限的,随着应用程序的增长,越来越多的标准功能需要由Django提供。

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

但是,我担心的是,通过Django在服务器上挖掘流量可能会破坏性能。这是一个有效的关注吗?

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

回答

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 

所以它实际上是相当简单且性能不够好,特别是如果重定向进入到同一台主机上的环回接口。

+0

在您使用的codelet中,不会传输标头。有没有一种简单的方法可以将传入请求按原样传递。我正在做类似的事情,并希望apss auth标题。但想要一个通过所有标题的干净解决方案(为了将来打样)。所以基本上我想写一个反向代理,但重定向到特殊用途的URL上,从我的django应用程序中为其余的服务。 – pranshus 2014-08-12 12:02:11

+1

我已经更新了示例代码以包含HTTP标头的传递。您可能需要弹出或修改某些原始请求标题,例如'主机','连接'。 – Bernhard 2014-08-18 13:43:26

2

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

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

+1

我不想设置和nginx服务器只是做到这一点。但我在制作中获得了它。我想镜像proxy_pass行为。所以我用你的脚本与[this](https://gist.github.com/pbassut/c0906f95f6d0720be4d8)非常简单的中间件与你的看法。谢谢 – 2015-11-16 23:34:27