2011-03-07 155 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